java获取密钥长度_java.security.InvalidKeyException:解密期间密钥大小错误

在解密期间,我得到的是“错误的密钥大小”或“给定的最终块未正确填充” ,这取决于我正在运行的操作系统。

在Win7上,使用IBMJCE或SUNJCE(两者都是Java8),解密在25%的时间内失败:javax.crypto.BadPaddingException:给com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)的最终块没有正确填充at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:294)at javax.crypto.Cipher.doFinal(Cipher.java:2087)

在mac上,使用SUNJCE,解密在100%的时间内失败:java.security.InvalidKeyException:com.sun.crypto.provider.DESedeCrypt.init(DESedeCrypt.java:69)的密钥大小错误,位于com的com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:91)。 sun.crypto.provider.CipherCore.init(CipherCore.java:469)at com.sun.crypto.provider.DESedeCipher.engineInit(DESedeCipher.java:197)at javax.crypto.Cipher.implInit(Cipher.java:791)在javax.crypto.Cipher.chooseProvider(Cipher.java:849)javax.crypto.Cipher.init(Cipher.java:1348)

使用DESEde,我相信密钥大小需要为24,我可以看到在Windows上,解密后,它总是24字节,而在mac上,它永远不会是24字节。

这是起点。 在decryptWithSymmetricKey期间始终抛出异常。 请注意,我对大部分代码(特定于DESede)进行了短循环,无法进一步缩小代码(非常新的安全空间)。public static void runtest() throws Exception {

String symmPad = "DESede/CBC/PKCS5Padding";

String asymmPad = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";

String pubKeyFp = "somekey";

String stringToEncrypt = "abcdefg";

KeyGenerator kgen = KeyGenerator.getInstance(DESEDE);

kgen.init(112);

SecretKey secKey = kgen.generateKey();

String encryptedKey = encryptSymmetricKey(secKey, asymmPad);

String encryptedData = encryptDataWithSymmetricKey(stringToEncrypt, secKey, symmPad);

String decryptedKey = decryptWithPrivateKey(encryptedKey, pubKeyFp, asymmPad);

String decryptedData = decryptWithSymmetricKey(encryptedData, decryptedKey, symmPad);

}

这里我们加密对称密钥,两个环境中的密钥长度都是24private static String encryptSymmetricKey(SecretKey secKey, String asymmPadding) throws Exception {

KeyPair keyPair = getKeyPair("self4");

Cipher cipher = Cipher.getInstance(asymmPadding);

OAEPParameterSpec ospec = new OAEPParameterSpec(SHA256, MGF1, MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);

cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic(), ospec);

String secKeyEncoded = new String(secKey.getEncoded());

byte[] encrypted = cipher.doFinal(secKeyEncoded.getBytes());

char[] encoded = Hex.encodeHex(encrypted);

return new String(encoded);

}

这里我们用对称密钥加密我们的字符串private static String encryptDataWithSymmetricKey(String data, SecretKey secretKey, String symmPadding) throws Exception {

Cipher cipher = Cipher.getInstance(symmPadding);

IvParameterSpec iv = new IvParameterSpec(new byte[8]);

cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

byte[] encrypted = cipher.doFinal(data.getBytes());

char[] encoded = Hex.encodeHex(encrypted);

return new String(encoded);

}

解密和解码对称密钥是我第一次看到mac上的可变长度密钥。public String decryptWithPrivateKey(String encryptedData, String pubKeyFp, String asymmPadding) throws Exception {

loadKeystores();

String alias = fingerPrintAliasMap.get(pubKeyFp);

KeyPair keyPair = getKeyPair(alias);

Cipher cipher = Cipher.getInstance(asymmPadding);

OAEPParameterSpec oParamSpec = new OAEPParameterSpec(SHA256, MGF1, MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);

cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate(), oParamSpec);

byte[] decoded = Hex.decodeHex(encryptedData.toCharArray());

byte[] decrypted = cipher.doFinal(decoded);

System.out.println("decoded and decrypted key length: " + decrypted.length); // 24 on windows, random on mac

return new String(Hex.encodeHex(decrypted));

}

故障发生在这里 - 在Windows上,它在cipher.doFinal 25%的时间内失败,在mac上,它在100%的时间在cipher.init失败。public String decryptWithSymmetricKey(String encryptedHexData, String symmKey, String symmPadding) throws Exception {

byte[] key = Hex.decodeHex(symmKey.toCharArray());

SecretKey skeySpec = new SecretKeySpec(key, DESEDE);

IvParameterSpec iv = new IvParameterSpec(new byte[8]);

Cipher cipher = Cipher.getInstance(symmPadding);

cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); // mac: Wrong key size

byte[] decoded = Hex.decodeHex(encryptedHexData.toCharArray());

byte[] deciphered = cipher.doFinal(decoded); // windows: Given final block not properly padded

return new String(deciphered);

}

我假设如果我在mac上解决这个问题,它也应该在Windows上解决它。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值