如何控制加密字符串的长度(密码学-加密)

时间:2018-10-16 17:01:12

标签: java encryption cryptography aes block-cipher

例如,我想传递一个字符串“ abc”,然后输出的加密字符串应为32字节,当我想传递“ abcdef”时,输出也应为32字节。换句话说,我想要固定长度的加密输出。我知道我的上限。就像我知道我的字符串永远不会超过8个字符。最多8个字符或少于8个字符。永远不会超过8个字符。

如果有人在Java Cipher中共享代码,那就太好了。

2 个答案:

答案 0 :(得分:0)

您应该应用填充方案。 Padding方案旨在完成纯文本,以便它们适合块密码的块大小。

您要求32个字节,这意味着对于AES两个加密块。您没有指定哪种安全类型,因此,我将考虑需要IV进行传输的C TR mode of operation

  • 让XX XX XX XX XX XX XX XX XX代表您的8字节字符串

例如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. 重新填充填充的消息,您将获得两个街区。
  2. 使用增加的计数器对CTR中的加密邮件进行加密。
  3. 为您自己设计一个填充。

答案 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个字节长