在没有填充的情况下检测AES中的错误密钥 [英] Detect wrong key in AES with no padding

查看:135
本文介绍了在没有填充的情况下检测AES中的错误密钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果 AES / ECB / PKCS5Padding 被使用,当尝试使用错误的密钥解密邮件时,您会收到BadPaddingException。但是,当使用 AES / ECB / NoPadding 时,消息被成功地解密为某些错误的数据,但是也不例外。

In case AES/ECB/PKCS5Padding is used you get a BadPaddingException when trying to decrypt a message with the wrong key. But there is no exception when AES/ECB/NoPadding is used - message is successfully decrypted to some wrong data.

在没有使用填充的情况下,是否有方法在AES解密期间检测出错误的密钥?

Is there a way to detect the wrong cipher key during AES decryption when no padding is used?

编辑:
我正在与具有加密设置为 AES / ECB / NoPadding 。我想我不能改变这个。

I'm communicating with the device which has encryption set to AES/ECB/NoPadding. I think I can't change this.

推荐答案

完整性检测填充



PKCS#5填充将成功解密,概率大于2 -8 。您尝试的每256个随机密钥将给您一个错误的明文,而不会抛出异常 1 。检查填充是必要的,但它不是确定密钥是否正确的好方法。

Padding for integrity detection

PKCS#5 padding will successfully decrypt with a probability of a little more than 2-8. Every 256th random key that you try will give you a wrong plaintext without throwing an exception1. Checking padding is necessary, but it is not a good way to determine whether the key is correct.

相同的数字对于ANSI X.923填充是正确的,但ISO 10126填充是不同的。填充最多为一个完整的块,至少有一个字节,因此ISO10126Padding的有效值为0x01到0x10。由于它是随机的,所以使用最后一个填充字节,因此大约16/256〜6%的错误键不会引发异常。

The same numbers are true for ANSI X.923 padding, but ISO 10126 padding is different. Padding is at most a full block and at least a single byte, so valid values for ISO10126Padding are 0x01 through 0x10. Since it is randomized only the last padding byte is used and therefore roughly 16/256 ~ 6% wrong keys won't throw an exception.

在尝试解密完整密文之前,检查密钥的有效性的方法是发送密钥检查值( KCV )以及密文。

A way check the validity of the key before trying to decrypt the full ciphertext is by sending a Key Check Value (KCV) along with the ciphertext.

这只是一个使用密钥的完全零填充块的加密。由于像AES这样的块密码(目前)并不易受到通过已知明文攻击的密钥恢复的影响,所以应该给出一个很好的方式来检查一个有效的密钥。

This is simply an encryption of a full zero-filled block with the key. Since block ciphers like AES are (currently) not vulnerable to key recovery through known-plaintext attacks, this should give a good way to check for a valid key.

您可以使用HMAC来检查密钥完整性。伪代码:

You could be using HMAC to check for key integrity. Pseudo-code:

byte[] salt = generateRandomByteArray(16);
byte[] keyTag = hmacSha256(key, salt);
return keyTag + salt + encrypt(data, key);

在接收端,您可以读取盐,通过HMAC运行键和盐,并与接收的keyTag。但是,只检查密钥是否正确。你真的应该检查密钥和密文的整体组合是否正确。

At the receiver side you can read the salt, run the key and the salt through HMAC and compare with the received keyTag. But that only checks whether the key is correct. You really should be checking whether the whole combination of key and ciphertext is correct.

此属性称为身份验证加密,可以通过运行密钥HMAC密文创建认证标签。然后,您需要通过HKDF(伪代码)生成两个密钥:

This property is called authenticated encryption and it can be achieved by running the keyed HMAC over the ciphertext to create the authentication tag. You would then need to generate two keys through HKDF (pseudo-code):

byte[] keyEnc = hkdf(key, "Encryption");
byte[] keyMac = hkdf(key, "MAC");
byte[] ciphertext = encrypt(data, keyEnc);
byte[] authTag = hmacSha256(keyMac, ciphertext);
return ciphertext + authTag;

在最基本的形式中,HKDF只是HMAC的双重调用。只需使用经过认证的模式,如GCM或EAX可能会更容易。

In its most basic form, HKDF is simply a double invocation of HMAC. It might be easier to just use an authenticated mode like GCM or EAX.

如果您无法对当前的加密过程添加任何内容,那么仍然有确定密钥是否正确的概率方法。主要思想是必须检查恢复的明文是否有意义。

If you cannot add anything to your current encryption procedure, then there are still probabilistic ways to determine whether the key was correct. The main idea is that the recovered plaintext has to be examined whether it makes sense.

例如,如果您的真实明文是一些文本,则可以检查解密的明文只包含可以使用ASCII的字符,或者如果你加密的UTF-8,你可以检查它是否真的正确地解码它。如果原始明文是一些JSON,那么您可以运行一个JSON验证器来检查您是否获得了有效的JSON,并且相对确定应用了正确的密钥。

For example, if your real plaintext is some text then you can check whether the decrypted plaintext contains only characters that would be available in ASCII or if you encrypted UTF-8, you can check whether it actually properly decodes it. If the original plaintext was some JSON, then you can run a JSON validator to check that you get valid JSON and be relatively sure that the correct key was applied.

保持请记住,攻击者可能仍然会篡改密文以产生正确验证的相关明文。成功率在很大程度上取决于你的明文的结构。

Keep in mind that an attacker might still tamper with the ciphertext to produce a related plaintext that properly verifies. The success rate heavily depends on the structure of your plaintext.

1 具有随机密钥,则在解密之前的解密明文的最后字节是0x01字节的机会是256,这是有效的填充,而不管它之前的内容。你有一个256 * 256的机会获得一个0x0202在最后两个字节也是一个有效的填充。

1 When you're having random keys, then the chance that the last bytes of the decrypted plaintext before unpadding is a 0x01 byte is 1 in 256 which is a valid padding regardless what comes before it. You have a 1 in 256*256 chance to get a 0x0202 in the last two bytes which is also a valid padding.

请不要使用ECB模式。它不是特别安全的,因为它不提供语义安全性。您至少应该使用CBC模式随机生成IV。

Please don't use ECB mode. It's not particularly secure since it doesn't provide semantic security. You should at least be using CBC mode with a randomly generated IV.

实现: HMAC-SHA256 AES-GCM

参考文献: HKDF

这篇关于在没有填充的情况下检测AES中的错误密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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