Java 使用DiffieHellman生成的SecretKey的BadPaddingException
我见过很多问题/答案,但没有人适合我。问题是,当我想要解密文本时,我抛出BadPaddingException,但不知道为什么 以下是我加密文本的代码:Java 使用DiffieHellman生成的SecretKey的BadPaddingException,java,android,encryption,Java,Android,Encryption,我见过很多问题/答案,但没有人适合我。问题是,当我想要解密文本时,我抛出BadPaddingException,但不知道为什么 以下是我加密文本的代码: KeyAgreement keyAgreement = this.getSecretKeyAgreement(publicOtherUserKey, privateOwnKey); SecretKey secretKey = new SecretKeySpec(keyAgreement.gener
KeyAgreement keyAgreement = this.getSecretKeyAgreement(publicOtherUserKey, privateOwnKey);
SecretKey secretKey = new SecretKeySpec(keyAgreement.generateSecret(), "AES");
Cipher aesCipher = null;
aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] byteDataToEncrypt = text.getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt);
byte[] encodedBytes = Base64.encodeBase64(byteCipherText);
textEncrypted = new String(encodedBytes);
其中“publicOtherUserKey”和“privateOwnKey”是使用Diffie-Hellman协议生成的
下面是对文本进行解密的代码,将抛出BadPaddingException
KeyAgreement keyAgreement = this.getSecretKeyAgreement(publicOtherUserKey, privateOwnKey);
byte[] encodedBytes = text.getBytes();
SecretKey secretKey = new SecretKeySpec(keyAgreement.generateSecret(), "AES");
byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
Cipher decrypt = Cipher.getInstance("AES");
decrypt.init(Cipher.DECRYPT_MODE, secretKey);
textDecrypted = new String(decrypt.doFinal(decodedBytes));
其中“publicOtherUserKey”和“privateOwnKey”是使用Diffie-Hellman协议生成的,而“text”是加密文本
你能帮我吗
编辑
值得一提的是,所有的键和文本都是用Base64编码的
编辑2
与Diffie Hellman开始密钥交换的代码
int bitLength = 256; // 256 bits
SecureRandom rnd = new SecureRandom();
BigInteger p = BigInteger.probablePrime(bitLength, rnd);
BigInteger g = BigInteger.probablePrime(bitLength, rnd);
DHParameterSpec dhParams = new DHParameterSpec(p, g);
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC");
keyGen.initialize(dhParams, new SecureRandom());
KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "BC");
KeyPair aPair = keyGen.generateKeyPair();
aKeyAgree.init(aPair.getPrivate());
byte[] aPairPrivateKey = aPair.getPrivate().getEncoded();
byte[] encodedBytesPrivateKey = Base64.encodeBase64(aPairPrivateKey);
String privateKey = new String(encodedBytesPrivateKey);
byte[] aPairPublicKey = aPair.getPublic().getEncoded();
byte[] encodedBytesPublicKey = Base64.encodeBase64(aPairPublicKey);
String publicKey = new String(encodedBytesPublicKey);
其中“公钥”和“私钥”是以后生成密钥的密钥。“公钥”是发送给其他用户的密钥。“p”和“g”也是生成密钥的数字
完成交换的代码:
DHParameterSpec dhParams = new DHParameterSpec(p, g);
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DH", "BC");
keyGen.initialize(dhParams, new SecureRandom());
KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH", "BC");
KeyPair bPair = keyGen.generateKeyPair();
bKeyAgree.init(bPair.getPrivate());
byte[] userPublicBytesBase64 = base64EncodedPublicKey.getBytes();
byte[] userPublicKey = Base64.decodeBase64(userPublicBytesBase64);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(userPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance("DH");
PublicKey aPublicKey = keyFactory.generatePublic(keySpec);
bKeyAgree.doPhase(aPublicKey, true);
final byte[] bPairPrivateKey = bPair.getPrivate().getEncoded();
byte[] encodedBytesPrivateKey = Base64.encodeBase64(bPairPrivateKey);
String privateKey = new String(encodedBytesPrivateKey);
final byte[] bPairPublicKey = bPair.getPublic().getEncoded();
byte[] encodedBytesPublicKey = Base64.encodeBase64(bPairPublicKey);
String publicKey = new String(encodedBytesPublicKey);
“base64EncodedPublicKey”是在第一个代码块中生成的密钥(“publicKey”),而“p”和“g”也是在第一个代码块中生成的素数。看起来正确,但不安全。请提供一个完整且最少的示例(包括单个方法中的Diffie Hellman部分)。
Cipher.getInstance(“AES”)
可能默认为“AES/ECB/PKCS5Padding”
。永远不要使用ECB模式。你真的需要在随机IV中至少使用CBC模式。IV不必是秘密的,所以你可以在密文前加上它。此外,您应该验证您的密文。这可以通过认证模式(如GCM)或加密后MAC方案中的MAC(如HMAC-SHA256)来完成。使用Diffie Hellman partI编辑我不明白为什么(尝试)在启用KeyPairGenerator
时您自己生成p和g。你的g可能不是一个基本的根模p,所以它不能正常工作。