没有填充的加密不起作用
Encryption with no padding does not works
我正在制作用于在 AES/CBC 模式下加密和解密文本的应用程序。在 AES/CBC/PKCS5Padding(和 PKCS7Padding)中一切正常,但如果我将算法设置为 AES/CBC/NoPadding,我将得到 "error" 字符串作为输出。有什么问题?
Class包含加解密函数:
public class CriptographyUtils
{
private static final String INIT_VECTOR = "fedcba9876543210";
private static final String ALGORITHM = "AES/CBC/NoPadding";
public static String aesEncrypt(String key, String text) // encrypts text (get bytes -> encrypt -> encode -> to String)
{
String result;
try
{
IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes());
SecretKeySpec myKey = new SecretKeySpec(fixKey(key).getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, myKey, iv);
byte[] encryptedBytes = cipher.doFinal(text.getBytes("UTF-8"));
result = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
}
catch (Exception ex)
{
ex.printStackTrace();
result = "error";
}
return result;
}
public static String aesDecrypt(String key, String text) // decrypts text (get bytes -> decode -> decrypt -> to String)
{
String result;
try
{
IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
SecretKeySpec myKey = new SecretKeySpec(fixKey(key).getBytes("UTF-8"), "AES"); // create new KEY in utf-8
Cipher cipher = Cipher.getInstance(ALGORITHM); // create new cipher
cipher.init(Cipher.DECRYPT_MODE, myKey, iv); // set cipher into decrypt mode using my KEY
byte[] decryptedBytes = cipher.doFinal(Base64.decode(text, Base64.DEFAULT)); // get bytes -> decode -> decrypt
result = new String(decryptedBytes); // convert decrypted text to String
}
catch (Exception ex)
{
ex.printStackTrace();
result = "error";
}
return result;
}
private static String fixKey(String key)
{
if (key.length() < 16) // less than 128 bits
{
int numPad = 16 - key.length();
for (int i = 0; i < numPad; i++)
key += "0"; //0 pad to len 16 bytes
}
else if (key.length() > 16)
key = key.substring(0, 16); //truncate to 16 bytes
return key;
}
}
用法:
正在加密:
CriptographyUtils.aesEncrypt(key, textToEncrypt)
正在解密:
CriptographyUtils.aesDecrypt(key, textToDecrypt));
关键是:
private static final String key = "1234123412341234";
AES 是一种块加密算法,因此其输入必须是块大小的倍数,AES 为 16 字节。因此,如果不能保证数据是块大小的倍数,则需要添加填充。
使用填充:PKCS#7 是 AES 常用的填充,PKCS#5 基本相同。
PKCS#5 标识符仅适用于 AES,因为编码人员懒得添加对 PKCS#7 标识符的支持。见 PKCS#7 padding:
PKCS#5 填充与 PKCS#7 填充相同,不同之处在于它仅为使用 64 位(8 字节)块大小的块密码定义。实际上,两者可以互换使用。.
我正在制作用于在 AES/CBC 模式下加密和解密文本的应用程序。在 AES/CBC/PKCS5Padding(和 PKCS7Padding)中一切正常,但如果我将算法设置为 AES/CBC/NoPadding,我将得到 "error" 字符串作为输出。有什么问题?
Class包含加解密函数:
public class CriptographyUtils
{
private static final String INIT_VECTOR = "fedcba9876543210";
private static final String ALGORITHM = "AES/CBC/NoPadding";
public static String aesEncrypt(String key, String text) // encrypts text (get bytes -> encrypt -> encode -> to String)
{
String result;
try
{
IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes());
SecretKeySpec myKey = new SecretKeySpec(fixKey(key).getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, myKey, iv);
byte[] encryptedBytes = cipher.doFinal(text.getBytes("UTF-8"));
result = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
}
catch (Exception ex)
{
ex.printStackTrace();
result = "error";
}
return result;
}
public static String aesDecrypt(String key, String text) // decrypts text (get bytes -> decode -> decrypt -> to String)
{
String result;
try
{
IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
SecretKeySpec myKey = new SecretKeySpec(fixKey(key).getBytes("UTF-8"), "AES"); // create new KEY in utf-8
Cipher cipher = Cipher.getInstance(ALGORITHM); // create new cipher
cipher.init(Cipher.DECRYPT_MODE, myKey, iv); // set cipher into decrypt mode using my KEY
byte[] decryptedBytes = cipher.doFinal(Base64.decode(text, Base64.DEFAULT)); // get bytes -> decode -> decrypt
result = new String(decryptedBytes); // convert decrypted text to String
}
catch (Exception ex)
{
ex.printStackTrace();
result = "error";
}
return result;
}
private static String fixKey(String key)
{
if (key.length() < 16) // less than 128 bits
{
int numPad = 16 - key.length();
for (int i = 0; i < numPad; i++)
key += "0"; //0 pad to len 16 bytes
}
else if (key.length() > 16)
key = key.substring(0, 16); //truncate to 16 bytes
return key;
}
}
用法:
正在加密:
CriptographyUtils.aesEncrypt(key, textToEncrypt)
正在解密:
CriptographyUtils.aesDecrypt(key, textToDecrypt));
关键是:
private static final String key = "1234123412341234";
AES 是一种块加密算法,因此其输入必须是块大小的倍数,AES 为 16 字节。因此,如果不能保证数据是块大小的倍数,则需要添加填充。
使用填充:PKCS#7 是 AES 常用的填充,PKCS#5 基本相同。
PKCS#5 标识符仅适用于 AES,因为编码人员懒得添加对 PKCS#7 标识符的支持。见 PKCS#7 padding:
PKCS#5 填充与 PKCS#7 填充相同,不同之处在于它仅为使用 64 位(8 字节)块大小的块密码定义。实际上,两者可以互换使用。.