这个问题可以去查相关的料
由于JDK版本不同,在Java 8 update 161版本以后就会出现此问题,根本原因还是DH密钥长度至少为512位,而DES算法密钥没有这么长,密钥长度不一致引起的。
解决方法:
配置JVM的系统变量:-Djdk.crypto.KeyAgreement.legacyKDF=true
1.发送方构建公钥私钥。
2.发送方发布发送方公钥。
3.接收方接收发送方公钥构建接收方公钥私钥。
4.接收方发布接收方公钥。
5.发送方通过发送方的私钥和接收方的公钥构建对称加密秘钥用于加密。
6.接收方通过接收方的私钥和发送方的公钥构建对称加密秘钥用于解密。
7.发送方通过秘钥加密数据并发送。
8.接收方接收数据并通过秘钥解密数据。
我稍微整理了下
public static void jdkDHFlow() throws Exception { //1.发送方构建公钥私钥 KeyPair senderKeyPair = jdkSenderPublicKey(); //2.发送方发布公钥 byte[] senderPublicKeyEncode = senderKeyPair.getPublic().getEncoded(); //3.接收方构建公钥私钥->接收方通过发送方公钥构建公钥私钥 KeyPair receiverKeyPair = jdkreceiverPublicKey(senderPublicKeyEncode); //4.接收方发布公钥 byte[] receiverPublicKeyEncode = receiverKeyPair.getPublic().getEncoded(); //5.发送方构建对称加密的秘钥->依据接收方公钥和自己的公钥私钥构建 SecretKey senderDesKey = jdkGetSecretKey(senderKeyPair,receiverPublicKeyEncode); //6.接收方构建对称加密秘钥->依据发送方公钥和接收方公钥撕咬构建 SecretKey receiverDesKey = jdkGetSecretKey(receiverKeyPair,senderPublicKeyEncode); //对比双方对称加密秘钥是否安相同 查看是否测试成功 if(Objects.equals(receiverDesKey,senderDesKey)){ System.out.println("双方秘钥相同"); } //7.发送方加密 Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE,senderDesKey); byte[] result = cipher.doFinal(BASE_STRING.getBytes()); System.out.println("JDK DH 加密:"+ Base64.encodeBase64String(result)); //8.接收方解密 cipher.init(Cipher.DECRYPT_MODE,receiverDesKey); result = cipher.doFinal(result); System.out.println("JDK DH 解密:"+new String(result)); } /** * 发送方构建发送方公钥 * @return 构建完成的公钥 */ public static KeyPair jdkSenderPublicKey() throws NoSuchAlgorithmException { //1.初始化发送方秘钥 KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH"); senderKeyPairGenerator.initialize(512); //生成秘钥 KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair(); return senderKeyPair; } /** * 依据发送方公钥生成接收方公钥 * @param senderPublicKey 发送方公钥 * @return 接收方公钥 */ public static KeyPair jdkreceiverPublicKey(byte[] senderPublicKey) throws Exception { KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKey); PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec); //使用和发送方一样的参数初始化 DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH"); //发送方公钥解析出来的dhParameterSpec receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair(); return receiverKeyPair; } /** * 自己的公钥私钥与对方的公钥构建 对称秘钥 * @param keyPair 自己秘钥对 * @param publicKey 对方公钥 * @return 本地对称加密秘钥 */ public static SecretKey jdkGetSecretKey(KeyPair keyPair,byte[] publicKey) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey); PublicKey senderPublicKey = keyFactory.generatePublic(x509EncodedKeySpec); KeyAgreement keyAgreement = KeyAgreement.getInstance("DH"); keyAgreement.init(keyPair.getPrivate()); keyAgreement.doPhase(senderPublicKey,true); SecretKey secretKey = keyAgreement.generateSecret("DES"); return secretKey; }
发送方的本地密钥:是通过发送方的私钥和接受方的公钥一起生成的
public key 不对,是不是用错函数?
高版本的
这一节讲的不咋地
String str="imooc security";
Cipher cipher=Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
byte[] bs=cipher.doFinal(str.getBytes());
加密代码改成这样就行了