Android加密API不会为AES生成安全IV [英] Android cryptography API not generating safe IV for AES

查看:180
本文介绍了Android加密API不会为AES生成安全IV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆