我正在使用以下简单的加密和解密函数,只是为了看它在使用更复杂的安全功能(如填充和散列)之前的工作原理。由于某种原因,返回的明文与原始邮件不相似。这是代码:
public static byte[] encrypt(SecretKey secret, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
/* Encrypt the message. */
cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] ciphertext = cipher.doFinal(buffer);
return ciphertext;
}
public static byte[] decrypt(SecretKey secret, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
/* Decrypt the message. - use cipher instance created at encrypt */
cipher.init(Cipher.DECRYPT_MODE, secret);
byte[] clear = cipher.doFinal(buffer);
return clear;
}
和调用代码:
SecretKey secret1 = null;
byte[] ciphertext = null;
byte[] message = "Hello, World!".getBytes();
byte[] clear = null;
try {
// aSecret is a shared secret generated with ECDH
secret1 = Crypto.createAESKey(aSecret);
ciphertext = Crypto.encrypt(secret1, message);
clear = Crypto.decrypt(secret1, ciphertext);
String s = new String(clear);//clear.toString();
keyAText.setText(new String(message));
keyBText.setText(s);
return;
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
答案 0 :(得分:2)
这几乎可以肯定是因为您在初始化期间未使用IvParameterSpec
提供IV。在Java SE上,由于CTR 需要设置此参数,因此您的代码甚至无法运行。然而,其他提供商可能以不同的方式实现他们可能会提供一个随机的IV。
当然,如果您在加密和解密期间使用不同的随机IV,您的解密结果可能与您的明文不匹配。
尝试以下修正方法:
public static byte[] encrypt(SecretKey secret, byte[] buffer) throws GeneralSecurityException
{
/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
SecureRandom rng = new SecureRandom();
byte[] ivData = new byte[cipher.getBlockSize()];
rng.nextBytes(ivData);
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivData));
byte[] ciphertext = cipher.doFinal(buffer);
return Arrays.concatenate(ivData, ciphertext);
}
public static byte[] decrypt(SecretKey secret, byte[] buffer) throws GeneralSecurityException
{
/* Decrypt the message. - use cipher instance created at encrypt */
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
int n = cipher.getBlockSize();
byte[] ivData = Arrays.copyOf(buffer, n);
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivData));
byte[] clear = cipher.doFinal(buffer, n, buffer.length - n);
return clear;
}