两人一组结对编程:结对对象 20175223 姚明宇
html
http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
MyBC.java
MyDC.java
import java.util.*; import java.util.stream.Collectors; import java.lang.Integer; public class MyBC{ private static final Mapbasic = new HashMap (); static { basic.put('-', 1); basic.put('+', 1); basic.put('*', 2); basic.put('/', 2); basic.put('(', 0); } //中缀表达式 转 后缀表达式 public static String toSuffix(String infix){ List queue = new ArrayList (); List stack = new ArrayList (); char[] charArr = infix.trim().toCharArray(); String standard = "*/+-()"; char ch = '&'; int len = 0; for (int i = 0; i < charArr.length; i++) { ch = charArr[i]; if(Character.isDigit(ch)) { len++; }else if(Character.isLetter(ch)) { len++; }else if(ch == '.'){ len++; }else if(Character.isSpaceChar(ch)) { if(len > 0) { queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i))); len = 0; } continue; }else if(standard.indexOf(ch) != -1) { if(len > 0) { queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len, i))); len = 0; } if(ch == '(') { stack.add(ch); continue; } if (!stack.isEmpty()) { int size = stack.size() - 1; boolean flag = false; while (size >= 0 && ch == ')' && stack.get(size) != '(') { queue.add(String.valueOf(stack.remove(size))); size--; flag = true; } while (size >= 0 && !flag && basic.get(stack.get(size)) >= basic.get(ch)) { queue.add(String.valueOf(stack.remove(size))); size--; } } if(ch != ')') { stack.add(ch); } else { stack.remove(stack.size() - 1); } } if(i == charArr.length - 1) { if(len > 0) { queue.add(String.valueOf(Arrays.copyOfRange(charArr, i - len+1, i+1))); } int size = stack.size() - 1; while (size >= 0) { queue.add(String.valueOf(stack.remove(size))); size--; } } } return queue.stream().collect(Collectors.joining(" ")); } }
import java.util.StringTokenizer; import java.util.Stack; import java.lang.Integer; public class MyDC { /** * constant for addition symbol */ private final char ADD = '+'; /** * constant for subtraction symbol */ private final char SUBTRACT = '-'; /** * constant for multiplication symbol */ private final char MULTIPLY = '*'; /** * constant for division symbol */ private final char DIVIDE = '/'; /** * the stack */ private Stackstack; public MyDC() { stack = new Stack ( ); } public int evaluate(String expr) { int op1, op2, result = 0; String token; StringTokenizer tokenizer = new StringTokenizer (expr); while (tokenizer.hasMoreTokens ( )) { token = tokenizer.nextToken ( ); //若是是运算符,调用isOperator if (isOperator(token)==true) { op2=stack.pop(); op1=stack.pop(); //从栈中弹出操做数2 //从栈中弹出操做数1 result=evalSingleOp(token.charAt(0),op1,op2); //根据运算符和两个操做数调用evalSingleOp计算result; stack.push(result); //计算result入栈; } else//若是是操做数 { stack.push(Integer.parseInt(token)); } //操做数入栈; } return result; } private boolean isOperator(String token) { return (token.equals ("+") || token.equals ("-") || token.equals ("*") || token.equals ("/")); } private int evalSingleOp(char operation, int op1, int op2) { int result = 0; switch (operation) { case ADD: result = op1 + op2; break; case SUBTRACT: result = op1 - op2; break; case MULTIPLY: result = op1 * op2; break; case DIVIDE: result = op1 / op2; break; default:return 0; } return result; } }
//import junit.framework.TestCase; import java.util.Scanner; public class MyDCTest { public static void main(String[] args) { String expression, again; int result; try { Scanner in = new Scanner (System.in); do { MyDC evaluator = new MyDC ( ); System.out.println ("Enter a valid postfix expression: "); expression = in.nextLine ( ); result = evaluator.evaluate (expression); System.out.println ( ); System.out.println ("That expression equals " + result); System.out.print ("Evaluate another expression [Y/N]? "); again = in.nextLine ( ); System.out.println ( ); } while (again.equalsIgnoreCase ("y")); } catch (Exception IOException) { System.out.println ("Input exception reported"); } } }
import java.util.Scanner; public class MyBCTest { public static void main(String[] args) { MyBC mybc = new MyBC (); MyDC mydc = new MyDC (); String inExpression; String str2; Scanner reader = new Scanner (System.in); System.out.println ("IEnter a expression: "); inExpression = reader.nextLine (); str2 = mybc.toSuffix (inExpression); System.out.println ("str2: " +str2); System.out.println ("result: " +mydc.evaluate(str2)); } }
结对编程:20175233严顺尧
负责客户端,20175223姚明宇
负责服务器java
import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String args[]) { Scanner reader = new Scanner (System.in); System.out.println ("客户输入一个中缀表达式: "); String str = reader.nextLine (); Socket mysocket; DataInputStream in = null; DataOutputStream out = null; try { mysocket = new Socket ("127.0.0.1", 2010); in = new DataInputStream (mysocket.getInputStream ( )); out = new DataOutputStream (mysocket.getOutputStream ( )); out.writeUTF (str); //in读取信息,堵塞状态 String temp = in.readUTF ( ); System.out.println ("客户收到服务器的后缀表达式:\n" + temp); String answer = in.readUTF ( ); System.out.println ("客户收到服务器的计算结果:\n" + answer); Thread.sleep (500); } catch (Exception e) { System.out.println ("服务器已断开" + e); } } }
import java.io.*; import java.net.*; public class Server { public static void main(String args[]) { String question, temp, answer; MyDC mydc = new MyDC (); ServerSocket serverForClient = null; Socket socketOnServer = null; DataOutputStream out = null; DataInputStream in = null; try { serverForClient = new ServerSocket (2010); } catch (IOException e1) { System.out.println (e1); } try { System.out.println ("等待客户呼叫"); //堵塞状态,除非有客户呼叫 socketOnServer = serverForClient.accept ( ); out = new DataOutputStream (socketOnServer.getOutputStream ( )); in = new DataInputStream (socketOnServer.getInputStream ( )); // in读取信息,堵塞状态 question = in.readUTF ( ); System.out.println ("服务器收到客户的中缀表达式:\n" + question); temp = MyBC.toSuffix (question); System.out.println ("服务器将中缀表达式变形为后缀表达式:\n" +temp); out.writeUTF (temp); answer = String.valueOf(mydc.evaluate(temp)); out.writeUTF (answer); Thread.sleep (500); } catch (Exception e) { System.out.println ("客户已断开" + e); } } }
import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.lang.*; public class AES { public static String ecodes(String content, String key) { if (content == null || content.length ( ) < 1) { return null; } try { KeyGenerator kgen = KeyGenerator.getInstance ("AES"); SecureRandom random = SecureRandom.getInstance ("SHA1PRNG"); random.setSeed (key.getBytes ( )); kgen.init (128, random); SecretKey secretKey = kgen.generateKey ( ); byte[] enCodeFormat = secretKey.getEncoded ( ); SecretKeySpec secretKeySpec = new SecretKeySpec (enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance ("AES"); byte[] byteContent = content.getBytes ("utf-8"); cipher.init (Cipher.ENCRYPT_MODE, secretKeySpec); byte[] byteRresult = cipher.doFinal (byteContent); StringBuffer sb = new StringBuffer ( ); for (int i = 0; i < byteRresult.length; i++) { String hex = Integer.toHexString (byteRresult[i] & 0xFF); if (hex.length ( ) == 1) { hex = '0' + hex; } sb.append (hex.toUpperCase ( )); } return sb.toString ( ); } catch (NoSuchAlgorithmException e) { e.printStackTrace ( ); } catch (NoSuchPaddingException e) { e.printStackTrace ( ); } catch (InvalidKeyException e) { e.printStackTrace ( ); } catch (UnsupportedEncodingException e) { e.printStackTrace ( ); } catch (IllegalBlockSizeException e) { e.printStackTrace ( ); } catch (BadPaddingException e) { e.printStackTrace ( ); } return null; } public static String dcodes(String content, String key) { if (content == null || content.length ( ) < 1) { return null; } if (content.trim ( ).length ( ) < 19) { return content; } byte[] byteRresult = new byte[content.length ( ) / 2]; for (int i = 0; i < content.length ( ) / 2; i++) { int high = Integer.parseInt (content.substring (i * 2, i * 2 + 1), 16); int low = Integer.parseInt (content.substring (i * 2 + 1, i * 2 + 2), 16); byteRresult[i] = (byte) (high * 16 + low); } try { KeyGenerator kgen = KeyGenerator.getInstance ("AES"); SecureRandom random = SecureRandom.getInstance ("SHA1PRNG"); random.setSeed (key.getBytes ( )); kgen.init (128, random); SecretKey secretKey = kgen.generateKey ( ); byte[] enCodeFormat = secretKey.getEncoded ( ); SecretKeySpec secretKeySpec = new SecretKeySpec (enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance ("AES"); cipher.init (Cipher.DECRYPT_MODE, secretKeySpec); byte[] result = cipher.doFinal (byteRresult); return new String (result); } catch (NoSuchAlgorithmException e) { e.printStackTrace ( ); } catch (NoSuchPaddingException e) { e.printStackTrace ( ); } catch (InvalidKeyException e) { e.printStackTrace ( ); } catch (IllegalBlockSizeException e) { e.printStackTrace ( ); } catch (BadPaddingException e) { e.printStackTrace ( ); } return null; } }
import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Scanner; public class ClientAES { public static void main(String args[]) { Scanner reader = new Scanner (System.in); System.out.println ("客户输入一个中缀表达式: "); String str = reader.nextLine (); Socket mysocket; DataInputStream in = null; DataOutputStream out = null; try { mysocket = new Socket ("127.0.0.1", 2010); in = new DataInputStream (mysocket.getInputStream ( )); out = new DataOutputStream (mysocket.getOutputStream ( )); String key = "20175223yaomingyushidashuaibi111"; //输入密文,32字符密钥 String miwen = AES.ecodes(str,key); out.writeUTF (miwen); //in读取信息,堵塞状态 String temp = in.readUTF ( ); String answer = in.readUTF ( ); Thread.sleep (500); } catch (Exception e) { System.out.println ("服务器已断开" + e); } } }
import java.io.*; import java.net.*; public class ServerAES { public static void main(String args[]) { String miwen, temp, answer; MyDC mydc = new MyDC (); ServerSocket serverForClient = null; Socket socketOnServer = null; DataOutputStream out = null; DataInputStream in = null; try { serverForClient = new ServerSocket (2010); } catch (IOException e1) { System.out.println (e1); } try { System.out.println ("等待客户呼叫"); socketOnServer = serverForClient.accept ( ); out = new DataOutputStream (socketOnServer.getOutputStream ( )); in = new DataInputStream (socketOnServer.getInputStream ( )); // in读取信息,堵塞状态 miwen = in.readUTF ( ); System.out.println ("服务器收到客户的密文:\n" + miwen); String key = "20175223yaomingyushidashuaibi111"; String mingwen = AES.dcodes(miwen, key); temp = MyBC.toSuffix (mingwen); System.out.println ("服务器将中缀表达式变形为后缀表达式:\n" +temp); out.writeUTF (temp); answer = String.valueOf(mydc.evaluate(temp)); out.writeUTF (answer); Thread.sleep (500); } catch (Exception e) { System.out.println ("客户已断开" + e); } } }
import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.KeyAgreement; import javax.crypto.SecretKey; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * 非对称加密算法DH算法组件 * 非对称算法通常是用来传送对称加密算法的密钥来使用的,因此这里咱们用DH算法模拟密钥传送 * 对称加密AES算法继续作咱们的数据加解密 * @author kongqz * */ public class DH { //非对称密钥算法 public static final String KEY_ALGORITHM="DH"; //本地密钥算法,即对称加密算法。可选des,aes,desede public static final String SECRET_ALGORITHM="AES"; /** * 密钥长度,DH算法的默认密钥长度是1024 * 密钥长度必须是64的倍数,在512到1024位之间 * */ private static final int KEY_SIZE=512; //公钥 private static final String PUBLIC_KEY="DHPublicKey"; //私钥 private static final String PRIVATE_KEY="DHPrivateKey"; /** * 初始化甲方密钥 * @return Map 甲方密钥的Map * */ public static MapinitKey() throws Exception{ //实例化密钥生成器 KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密钥生成器 keyPairGenerator.initialize(KEY_SIZE); //生成密钥对 KeyPair keyPair=keyPairGenerator.generateKeyPair(); //甲方公钥 DHPublicKey publicKey=(DHPublicKey) keyPair.getPublic(); //甲方私钥 DHPrivateKey privateKey=(DHPrivateKey) keyPair.getPrivate(); //将密钥存储在map中 Map keyMap=new HashMap (); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 初始化乙方密钥 * @param key 甲方密钥(这个密钥是经过第三方途径传递的) * @return Map 乙方密钥的Map * */ public static Map initKey(byte[] key) throws Exception{ //解析甲方的公钥 //转换公钥的材料 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key); //实例化密钥工厂 KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //产生公钥 PublicKey pubKey=keyFactory.generatePublic(x509KeySpec); //由甲方的公钥构造乙方密钥 DHParameterSpec dhParamSpec=((DHPublicKey)pubKey).getParams(); //实例化密钥生成器 KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance(keyFactory.getAlgorithm()); //初始化密钥生成器 keyPairGenerator.initialize(dhParamSpec); //产生密钥对 KeyPair keyPair=keyPairGenerator.genKeyPair(); //乙方公钥 DHPublicKey publicKey=(DHPublicKey)keyPair.getPublic(); //乙方私钥 DHPrivateKey privateKey=(DHPrivateKey)keyPair.getPrivate(); //将密钥存储在Map中 Map keyMap=new HashMap (); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * 加密 * @param data 待加密数据 * @param key 密钥 * @return byte[] 加密数据 * */ public static byte[] encrypt(byte[] data,byte[] key) throws Exception{ //生成本地密钥 SecretKey secretKey=new SecretKeySpec(key,SECRET_ALGORITHM); //数据加密 Cipher cipher=Cipher.getInstance(secretKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal(data); } /** * 解密 * @param data 待解密数据 * @param key 密钥 * @return byte[] 解密数据 * */ public static byte[] decrypt(byte[] data,byte[] key) throws Exception{ //生成本地密钥 SecretKey secretKey=new SecretKeySpec(key,SECRET_ALGORITHM); //数据解密 Cipher cipher=Cipher.getInstance(secretKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, secretKey); return cipher.doFinal(data); } /** * 构建密钥 * @param publicKey 公钥 * @param privateKey 私钥 * @return byte[] 本地密钥 * */ public static byte[] getSecretKey(byte[] publicKey,byte[] privateKey) throws Exception{ //实例化密钥工厂 KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM); //初始化公钥 //密钥材料转换 X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(publicKey); //产生公钥 PublicKey pubKey=keyFactory.generatePublic(x509KeySpec); //初始化私钥 //密钥材料转换 PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(privateKey); //产生私钥 PrivateKey priKey=keyFactory.generatePrivate(pkcs8KeySpec); //实例化 KeyAgreement keyAgree=KeyAgreement.getInstance(keyFactory.getAlgorithm()); //初始化 keyAgree.init(priKey); keyAgree.doPhase(pubKey, true); //生成本地密钥 SecretKey secretKey=keyAgree.generateSecret(SECRET_ALGORITHM); return secretKey.getEncoded(); } /** * 取得私钥 * @param keyMap 密钥map * @return byte[] 私钥 * */ public static byte[] getPrivateKey(Map keyMap){ Key key=(Key)keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** * 取得公钥 * @param keyMap 密钥map * @return byte[] 公钥 * */ public static byte[] getPublicKey(Map keyMap) throws Exception{ Key key=(Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { //生成甲方的密钥对 Map keyMap1=DH.initKey(); //甲方的公钥 byte[] publicKey1=DH.getPublicKey(keyMap1); //甲方的私钥 byte[] privateKey1=DH.getPrivateKey(keyMap1); System.out.println("甲方公钥:/n"+Base64.encodeBase64String(publicKey1)); System.out.println("甲方私钥:/n"+Base64.encodeBase64String(privateKey1)); //由甲方的公钥产生的密钥对 Map keyMap2=DH.initKey(publicKey1); byte[] publicKey2=DH.getPublicKey(keyMap2); byte[] privateKey2=DH.getPrivateKey(keyMap2); System.out.println("乙方公钥:/n"+Base64.encodeBase64String(publicKey2)); System.out.println("乙方私钥:/n"+Base64.encodeBase64String(privateKey2)); //组装甲方的本地加密密钥,由乙方的公钥和甲方的私钥组合而成 byte[] key1=DH.getSecretKey(publicKey2, privateKey1); System.out.println("甲方的本地密钥:/n"+Base64.encodeBase64String(key1)); //组装乙方的本地加密密钥,由甲方的公钥和乙方的私钥组合而成 byte[] key2=DH.getSecretKey(publicKey1, privateKey2); System.out.println("乙方的本地密钥:/n"+Base64.encodeBase64String(key2)); System.out.println("================密钥对构造完毕,开始进行加密数据的传输============="); String str="密码交换算法"; System.out.println("/n===========甲方向乙方发送加密数据=============="); System.out.println("原文:"+str); System.out.println("===========使用甲方本地密钥对进行数据加密=============="); //甲方进行数据的加密 byte[] code1=DH.encrypt(str.getBytes(), key1); System.out.println("加密后的数据:"+Base64.encodeBase64String(code1)); System.out.println("===========使用乙方本地密钥对数据进行解密=============="); //乙方进行数据的解密 byte[] decode1=DH.decrypt(code1, key2); System.out.println("乙方解密后的数据:"+new String(decode1)+"/n/n"); System.out.println("===========反向进行操做,乙方向甲方发送数据==============/n/n"); str="乙方向甲方发送数据DH"; System.out.println("原文:"+str); //使用乙方本地密钥对数据进行加密 byte[] code2=DH.encrypt(str.getBytes(), key2); System.out.println("===========使用乙方本地密钥对进行数据加密=============="); System.out.println("加密后的数据:"+Base64.encodeBase64String(code2)); System.out.println("=============乙方将数据传送给甲方======================"); System.out.println("===========使用甲方本地密钥对数据进行解密=============="); //甲方使用本地密钥对数据进行解密 byte[] decode2=DH.decrypt(code2, key1); System.out.println("甲方解密后的数据:"+new String(decode2)); } }
import org.apache.commons.codec.binary.Base64; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Map; import java.util.Scanner; public class ClientDH { public static void main(String args[]) { String cipherText, plainText, answer; Scanner reader = new Scanner (System.in); System.out.println ("客户输入一个中缀表达式: "); String str = reader.nextLine (); Socket mysocket; DataInputStream in = null; DataOutputStream out = null; try { mysocket = new Socket ("127.0.0.1", 2010); in = new DataInputStream (mysocket.getInputStream ( )); out = new DataOutputStream (mysocket.getOutputStream ( )); //设立AES算法的32字符密钥,输入密文与密钥 String AES_Key = "20175223yaomingyushidashuaibi111"; //将中缀表达式变形为后缀表达式 plainText = MyBC.toSuffix (str); System.out.println ("后缀表达式明文:\n" + plainText); //将后缀表达式明文经过AES加密,并将后缀表达式密文发往客户端 cipherText = AES.ecodes (plainText, AES_Key); System.out.println ("后缀表达式密文:\n" + cipherText + "\n"); //out发送信息 out.writeUTF (cipherText); //对AES算法的32字符密钥进行DH算法加密 //生成甲方的密钥对 MapkeyMap1 = DH.initKey ( ); //甲方的公钥 byte[] publicKey1 = DH.getPublicKey (keyMap1); //甲方的私钥 byte[] privateKey1 = DH.getPrivateKey (keyMap1); System.out.println ("甲方公钥:/n" + Base64.encodeBase64String (publicKey1)); System.out.println ("甲方私钥:/n" + Base64.encodeBase64String (privateKey1)); String tempKey1 = Base64.encodeBase64String (publicKey1); //out发送信息 out.writeUTF (tempKey1); //组装甲方的本地加密密钥,由乙方的公钥和甲方的私钥组合而成 //in读取信息,堵塞状态 String tempKey2 = in.readUTF ( ); byte[] publicKey2 = Base64.decodeBase64 (tempKey2); System.out.println ("乙方公钥:/n" + Base64.encodeBase64String (publicKey1)); byte[] key1 = DH.getSecretKey (publicKey2, privateKey1); System.out.println ("甲方的本地密钥:/n" + Base64.encodeBase64String (key1)); //甲方使用本地密钥对AES_Key进行消息加密,并发给乙方 byte[] code1 = DH.encrypt (AES_Key.getBytes ( ), key1); System.out.println ("甲方使用本地密钥对AES_Key进行加密后的数据:" + Base64.encodeBase64String (code1)); //out发送信息,333333 out.writeUTF (Base64.encodeBase64String (code1)); //接受乙方的计算结果 answer = in.readUTF ( ); System.out.println ("\n**计算由服务器进行**\n\n客户收到服务器的计算结果:\n" + answer); Thread.sleep (500); } catch (Exception e) { System.out.println ("服务器已断开" + e); } } }
import org.apache.commons.codec.binary.Base64; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; public class ServerDH { public static void main(String args[]) { String cipherText, plainText, answer; MyDC mydc = new MyDC ( ); ServerSocket serverForClient = null; Socket socketOnServer = null; DataOutputStream out = null; DataInputStream in = null; try { serverForClient = new ServerSocket (2010); } catch (IOException e1) { System.out.println (e1); } try { System.out.println ("等待客户呼叫"); //堵塞状态,除非有客户呼叫 socketOnServer = serverForClient.accept ( ); out = new DataOutputStream (socketOnServer.getOutputStream ( )); in = new DataInputStream (socketOnServer.getInputStream ( )); // in读取信息,堵塞状态,111111 cipherText = in.readUTF ( ); System.out.println ("服务器收到客户的后缀表达式密文:\n" + cipherText + "\n"); //由甲方的公钥产生的密钥对 // in读取信息,堵塞状态,2222222 String tempKey1 = in.readUTF ( ); byte[] publicKey1 = Base64.decodeBase64 (tempKey1); System.out.println ("甲方公钥:/n" + Base64.encodeBase64String (publicKey1)); MapkeyMap2 = DH.initKey (publicKey1); byte[] publicKey2 = DH.getPublicKey (keyMap2); byte[] privateKey2 = DH.getPrivateKey (keyMap2); System.out.println ("乙方公钥:/n" + Base64.encodeBase64String (publicKey2)); System.out.println ("乙方私钥:/n" + Base64.encodeBase64String (privateKey2)); //为组装甲方的本地加密密钥,将乙方的公钥发给甲方 String tempKey2 = Base64.encodeBase64String (publicKey2); //out发送信息,333333 out.writeUTF (tempKey2); //组装乙方的本地加密密钥,由甲方的公钥和乙方的私钥组合而成 byte[] key2 = DH.getSecretKey (publicKey1, privateKey2); System.out.println ("乙方的本地密钥:/n" + Base64.encodeBase64String (key2)); //接受甲方的AES_Key的加密信息,对其解密 byte[] code1 = Base64.decodeBase64 (in.readUTF ( )); byte[] decode1 = DH.decrypt (code1, key2); String AES_Key = new String (decode1); System.out.println ("\n乙方解密后的AES_Key数据:" + AES_Key); //使用解密后的AES_Key对后缀表达式密文解密,并算出结果 plainText = AES.dcodes (cipherText, AES_Key); System.out.println ("\nAES_Key对后缀表达式密文解密:\n" + plainText); answer = String.valueOf (mydc.evaluate (plainText)); //将计算结果发给甲方 out.writeUTF (answer); System.out.println ("\n**结果由客户端进行输出**" ); Thread.sleep (500); } catch (Exception e) { System.out.println ("客户已断开" + e); } } }
import java.security.*; public class Md5{ public static String numberMD5(String plainTest) throws Exception{ String x=plainTest; MessageDigest m=MessageDigest.getInstance("MD5"); m.update(x.getBytes("UTF8")); byte s[ ]=m.digest( ); String result=""; for (int i=0; i < s.length; i++){ result+=Integer.toHexString((0x000000ff & s[i])|0xffffff00).substring(6); } return result; } }
import org.apache.commons.codec.binary.Base64; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; public class ServerMd5 { public static void main(String args[]) { String cipherText, plainText, answer; MyDC mydc = new MyDC ( ); ServerSocket serverForClient = null; Socket socketOnServer = null; DataOutputStream out = null; DataInputStream in = null; try { serverForClient = new ServerSocket (2010); } catch (IOException e1) { System.out.println (e1); } try { System.out.println ("等待客户呼叫"); //堵塞状态,除非有客户呼叫 socketOnServer = serverForClient.accept ( ); out = new DataOutputStream (socketOnServer.getOutputStream ( )); in = new DataInputStream (socketOnServer.getInputStream ( )); // in读取信息,堵塞状态,111111 cipherText = in.readUTF ( ); System.out.println ("服务器收到客户的后缀表达式密文:\n" + cipherText + "\n"); //由甲方的公钥产生的密钥对 // in读取信息,堵塞状态,2222222 String tempKey1 = in.readUTF ( ); byte[] publicKey1 = Base64.decodeBase64 (tempKey1); System.out.println ("甲方公钥:/n" + Base64.encodeBase64String (publicKey1)); MapkeyMap2 = DH.initKey (publicKey1); byte[] publicKey2 = DH.getPublicKey (keyMap2); byte[] privateKey2 = DH.getPrivateKey (keyMap2); System.out.println ("乙方公钥:/n" + Base64.encodeBase64String (publicKey2)); System.out.println ("乙方私钥:/n" + Base64.encodeBase64String (privateKey2)); //为组装甲方的本地加密密钥,将乙方的公钥发给甲方 String tempKey2 = Base64.encodeBase64String (publicKey2); //out发送信息,333333 out.writeUTF (tempKey2); //组装乙方的本地加密密钥,由甲方的公钥和乙方的私钥组合而成 byte[] key2 = DH.getSecretKey (publicKey1, privateKey2); System.out.println ("乙方的本地密钥:/n" + Base64.encodeBase64String (key2)); //接受甲方的AES_Key的加密信息,对其解密 byte[] code1 = Base64.decodeBase64 (in.readUTF ( )); byte[] decode1 = DH.decrypt (code1, key2); String AES_Key = new String (decode1); System.out.println ("\n乙方解密后的AES_Key数据:" + AES_Key); //使用解密后的AES_Key对后缀表达式密文解密,并算出结果 plainText = AES.dcodes (cipherText, AES_Key); String md5zhi2 =Md5.numberMD5(plainText); String md5zhi1 =in.readUTF ( ); if(md5zhi2.equals(md5zhi1))System.out.println ("\n能解密"); else System.out.println ("\n不能解密"); System.out.println ("\nAES_Key对后缀表达式密文解密:\n" + plainText); answer = String.valueOf (mydc.evaluate (plainText)); //将计算结果发给甲方 out.writeUTF (answer); System.out.println ("\n**结果由客户端进行输出**" ); Thread.sleep (500); } catch (Exception e) { System.out.println ("客户已断开" + e); } } }
import org.apache.commons.codec.binary.Base64; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.Socket; import java.util.Map; import java.util.Scanner; public class ClientMd5 { public static void main(String args[]) { String cipherText, plainText, answer; Scanner reader = new Scanner (System.in); System.out.println ("客户输入一个中缀表达式: "); String str = reader.nextLine (); Socket mysocket; DataInputStream in = null; DataOutputStream out = null; try { mysocket = new Socket ("127.0.0.1", 2010); in = new DataInputStream (mysocket.getInputStream ( )); out = new DataOutputStream (mysocket.getOutputStream ( )); //设立AES算法的32字符密钥,输入密文与密钥 String AES_Key = "20175223yaomingyushidashuaibi111"; //将中缀表达式变形为后缀表达式 plainText = MyBC.toSuffix (str); String md5zhi1 =Md5.numberMD5(plainText); System.out.println ("后缀表达式明文:\n" + plainText); //将后缀表达式明文经过AES加密,并将后缀表达式密文发往客户端 cipherText = AES.ecodes (plainText, AES_Key); System.out.println ("后缀表达式密文:\n" + cipherText + "\n"); //out发送信息 out.writeUTF (cipherText); //对AES算法的32字符密钥进行DH算法加密 //生成甲方的密钥对 MapkeyMap1 = DH.initKey ( ); //甲方的公钥 byte[] publicKey1 = DH.getPublicKey (keyMap1); //甲方的私钥 byte[] privateKey1 = DH.getPrivateKey (keyMap1); System.out.println ("甲方公钥:/n" + Base64.encodeBase64String (publicKey1)); System.out.println ("甲方私钥:/n" + Base64.encodeBase64String (privateKey1)); String tempKey1 = Base64.encodeBase64String (publicKey1); //out发送信息 out.writeUTF (tempKey1); //组装甲方的本地加密密钥,由乙方的公钥和甲方的私钥组合而成 //in读取信息,堵塞状态 String tempKey2 = in.readUTF ( ); byte[] publicKey2 = Base64.decodeBase64 (tempKey2); System.out.println ("乙方公钥:/n" + Base64.encodeBase64String (publicKey1)); byte[] key1 = DH.getSecretKey (publicKey2, privateKey1); System.out.println ("甲方的本地密钥:/n" + Base64.encodeBase64String (key1)); //甲方使用本地密钥对AES_Key进行消息加密,并发给乙方 byte[] code1 = DH.encrypt (AES_Key.getBytes ( ), key1); System.out.println ("甲方使用本地密钥对AES_Key进行加密后的数据:" + Base64.encodeBase64String (code1)); //out发送信息,333333 out.writeUTF (Base64.encodeBase64String (code1)); out.writeUTF(md5zhi1); //接受乙方的计算结果 answer = in.readUTF ( ); System.out.println ("\n**计算由服务器进行**\n\n客户收到服务器的计算结果:\n" + answer); Thread.sleep (500); } catch (Exception e) { System.out.println ("服务器已断开" + e); } } }
out.writeUTF()
; 传输后没法正确接收,变为乱码客户端:git
//经过 `Base64` 的方法 `encodeBase64String ();` 将数组转化为字符串类型 String tempKey1 = Base64.encodeBase64String (publicKey1); //out发送信息 out.writeUTF (tempKey1);
服务器:算法
...... //由客户端的公钥产生的密钥对 String tempKey1 = in.readUTF (); byte [] publicKey1 = tempKey1.getBytes (); System.out.println("客户端公钥:/n"+Base64.encodeBase64String(publicKey1)); Map<String,Object> keyMap2=DH.initKey(publicKey1); ......
报错:密钥格式不对。express
由于 out.writeUTF()
in.readUTF ()
传输的数据类型为 String
,而不是 byte []
数组,因此不可用 getBytes ()
方法来提取。
要使用 Base64 方法 encodeBase64String ()
的对应的方法 decodeBase64 (tempKey1)
来转换数据类型。apache
String tempKey1 = in.readUTF ( ); byte[] publicKey1 = Base64.decodeBase64 (tempKey1); System.out.println ("客户端公钥:/n" + Base64.encodeBase64String (publicKey1)); Map <String, Object> keyMap2 = DH.initKey (publicKey1);