我已经看到很多关于此问题的帖子,其中在解密AES 256时,前16个字节仍然是字节而不是文本。我已经尝试过这里建议的操作,例如将IV字节合并到Base64Encodeing之前的加密字节,但这没有用。我还确保我的两个Web方法(加密和解密)使用相同的IV字节。
我的独立逻辑(Java应用程序)按预期工作。经过数小时的艰辛工作和搜索尝试之后,我还是会问这里的一些专家。
对于以下代码可能存在的问题,我将不胜感激。
下面显示了两种Web服务GET方法,一种用于加密,另一种用于解密。
预先感谢
get("/AESEncrypt/:stringToEncrypt/:Base64SecretKey", (request, response) ->
{
String myKey = request.params("secretKey");
byte[] ivBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// assume encoded since string could be any characters
String str2Encrypt = URLDecoder.decode(request.params("stringToEncrypt"), "UTF-8");
//Salt please.
String salt = "somesalt";
final byte[] saltBytes = salt.getBytes("UTF-8");
// Use SHA 256.
final SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
final PBEKeySpec spec = new PBEKeySpec(
myKey.toCharArray(),
saltBytes,
65536,
256);
final SecretKey secretKey = factory.generateSecret(spec);
final SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//encrypt the message
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
final AlgorithmParameters params = cipher.getParameters();
final byte[] encryptedTextBytes = cipher.doFinal(str2Encrypt.getBytes("UTF-8"));
return Base64.encodeBase64String(encryptedTextBytes);
});
//-----------
get("/AESDecrypt/:stringToDecrypt/:decryptKey", (request, response) ->
{
String base64Key = request.params("decryptKey");
String strToDecrypt =request.params("stringToDecrypt");
String decryptedString = null;
//Salt please.
String salt = "somesalt";
final byte[] saltBytes = salt.getBytes("UTF-8");
// Derive the key
final SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
final PBEKeySpec spec = new PBEKeySpec(
base64Key.toCharArray(),
saltBytes,
65536,
256
);
final SecretKey secretKey = factory.generateSecret(spec);
final SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Decrypt the message
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
final AlgorithmParameters params = cipher.getParameters();
// byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ivBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] decryptedTextBytes = null;
try
{
decryptedTextBytes = cipher.doFinal(Base64.decodeBase64(strToDecrypt));
}
catch (IllegalBlockSizeException e)
{
e.printStackTrace();
}
catch (BadPaddingException e)
{
e.printStackTrace();
}
return new String(decryptedTextBytes);
});
答案 0 :(得分:1)
您在解密过程中通过了IV,但是在加密过程中没有通过它。因此IV是随机的,导致解密时第一个块损坏(因为您使用的是其他IV)。您的意思是:
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivBytes));
请注意,使用相同的密钥和IV加密多封邮件是不安全的。您确实确实想要一个随机IV,而不是固定IV。但是无论如何,您都必须使用相同的
。