Android加密API不会为AES生成安全IV [英] Android cryptography API not generating safe IV for AES
问题描述
我正在使用javax.crypto在我的应用程序中执行一些加密操作。我使用AES进行加密/解密,如下所示:
I'm using javax.crypto to do some cryptographic operations in my application. I use AES for encryption/decryption like this:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] cipherText = cipher.doFinal(plaintext);
byte[] iv = cipher.getIV(); //The problematic IV
在加密后,生成的IV被添加到密文之前。
The generated IV is prepended to the ciphertext after the enncryption.
Java规范明确指出,如果未向 cipher.init()
提供IV,则必须自动生成IV:
The Java specification clearly says that the IV must be generated automatically if its is not provided to cipher.init()
:
如果此密码需要任何无法从给定密钥派生的算法参数,则底层密码实现应该自己生成所需的参数(使用特定于提供者的默认值或随机值)
If this cipher requires any algorithm parameters that cannot be derived from the given key, the underlying cipher implementation is supposed to generate the required parameters itself (using provider-specific default or random values)
但有时候我最终会得到一些看起来不是很随机的密文,比如这个(在base64中):
But sometimes I end up with ciphertexts that don't seem very random, such as this one (in base64):
AAAAAAAAAAAAAAAAAAAAAOmI9Qh1fMiG6HV3tKZK3q5sCruaPdYqYnoUOM00rs6YZY3EvecYfR6vTHzZqk7ugknR9ZMipedYWJB1YOLmSYg=
前面的一串 A
字符是IV。 IV实际上是16个零字节。
The bunch of A
characters at the front is the IV. The IV is actually 16 zero-bytes.
大多数情况下,库生成适当的随机IV,但有时,它只会弹出零。为什么会发生这种情况?
Most of the time, the library generates proper, random IVs, but sometimes, it just pops out zeros. Why is this happening?
推荐答案
有些(大多数?)提供商只使用零字节填充的IV作为默认值。我强调你的引用:
Some (most?) providers simply use a zero-byte filled IV as their default. My emphasis of your quote:
如果这个密码需要任何无法从给定密钥派生的算法参数,那么应该使用底层密码实现自己生成所需的参数(使用特定于提供者的默认或随机值)
当你看时在密文的前面,你会看到它以一堆A字符开头。对于0x00字节,它是Base 64。
When you look to the front of your ciphertext, you see that it starts with a bunch of "A" characters. It's Base 64 for 0x00 bytes.
如果你想确保你有一个随机的IV,你必须自己生成它:
If you want to make sure that you have a random IV, you have to generate it yourself:
SecureRandom r = new SecureRandom();
byte[] ivBytes = new byte[16];
r.nextBytes(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));
这篇关于Android加密API不会为AES生成安全IV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!