我对不工作的代码没有问题,但是这很令人困惑,我也不知道为什么即使我使用16byte长的字符串(所以不需要填充),但我的输出却很奇怪 cG + etVq + 7l + RfJS27jCtwg ==(无填充,但在加密之前为16字节长)
vs
cG + etVq + 7l + RfJS27jCtwskFauqkVxpbMJGODZoZe5c =(使用PKCS5Padding,但字符串相同) 所以为什么?
public class AES {
private static SecretKeySpec secretKey;
private static byte[] key;
public static void setKey(String myKey)
{
key = myKey.getBytes("UTF-8");
secretKey = new SecretKeySpec(key, "AES");
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
}
catch (Exception e)
{
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
public static String decrypt(String strToDecrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
}
catch (Exception e)
{
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}
public static SecretKeySpec getSecretKey() {
return secretKey;
}
public static void setSecretKey(SecretKeySpec secretKey) {
AES.secretKey = secretKey;
}
public static byte[] getKey() {
return key;
}
public static void setKey(byte[] key) {
AES.key = key;
}
}
答案 0 :(得分:1)
使用PKCS5Padding
,总是添加填充。没有不需要填充的字符串。一个16字节的字符串将产生一个32字节的输出(16的下一个倍数)。
例如,参见Wikipedia上的Padding:
如果原始数据是N个字节的整数倍,则将添加一个额外的字节块,其值为N。这是必需的,以便解密算法可以确定地确定最后一个块的最后一个字节是填充字节,该填充字节指示添加的填充字节数还是明文消息的一部分。
考虑一个纯文本消息,该消息是N个字节的整数倍,纯文本的最后一个字节为01。由于没有其他信息,解密算法将无法确定最后一个字节是纯文本字节还是填充字节。 。但是,通过在01个明文字节之后添加N个字节,每个字节的值N,解密算法可以始终将最后一个字节视为填充字节,并从密文末尾剥离适当数量的填充字节;表示要根据最后一个字节的值剥离的字节数。