例如,我想传递一个字符串“ abc”,然后输出的加密字符串应为32字节,当我想传递“ abcdef”时,输出也应为32字节。换句话说,我想要固定长度的加密输出。我知道我的上限。就像我知道我的字符串永远不会超过8个字符。最多8个字符或少于8个字符。永远不会超过8个字符。
如果有人在Java Cipher中共享代码,那就太好了。
答案 0 :(得分:0)
您应该应用填充方案。 Padding方案旨在完成纯文本,以便它们适合块密码的块大小。
您要求32个字节,这意味着对于AES两个加密块。您没有指定哪种安全类型,因此,我将考虑需要IV进行传输的C TR mode of operation。
例如ANSI X.923填充方案,请在其末尾附加0并加上消息的长度。然后
XX XX XX XX XX XX XX XX 00 00 00 00 00 00 00 08
将是您的纯文本。 08是您的纯文本字节长度。
例如PKCS#5和PKCS#7填充方案,将消息的长度附加重复,然后
XX XX XX XX XX XX XX XX 08 08 08 08 08 08 08 08
将是您的纯文本。
这些填充旨在用于一个块。如果该块已满,它们将扩展下一个块。
解决方案;
答案 1 :(得分:0)
这取决于加密算法,模式和块大小。
例如AES使用128位(16字节)的固定块大小,CBC和ECB模式将返回固定长度,该长度将是128的倍数。
如果您使用ECB模式并且您输入的字节数组长度为10,则必须添加6个字节的填充以完成该块。
有很多填充块的方法,可以使用PKCS5或PKCS7。
在Java中,您可以使用Bouncy Castle的库https://www.bouncycastle.org/ 确保使用安全的IV和derived encryption key
在下面的示例中,填充由库处理
public byte[] genIV() {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
return iv;
}
public byte[] encrypt(byte[] plaintext, byte[] secretKey, byte[] iv) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
Cipher in = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
Key key = new SecretKeySpec(secretKey, "AES");
in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
return in.doFinal(plaintext);
}
public byte[] decrypt(byte[] ciphertext, byte[] secretKey, byte[] iv) throws InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, BadPaddingException, IllegalBlockSizeException {
Key key = new SecretKeySpec(secretKey, "AES");
Cipher out = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
return out.doFinal(ciphertext);
}
请记住,根据字符集,字符串中的每个字符至少 个8位长,在您的示例中,“ abcdef”至少6个字节长