如何在 Java(Android)中生成与 .Net 中相同的 AES 密钥?

Posted

技术标签:

【中文标题】如何在 Java(Android)中生成与 .Net 中相同的 AES 密钥?【英文标题】:How to generate the same AES key in Java(Android) as in .Net? 【发布时间】:2012-12-30 19:00:53 【问题描述】:

我需要从 .Net WebService 提供的 salt 和密码生成 Java (android) 中的 AES 密钥。我需要具有与 .net 中生成的密钥相同的密钥,并且具有相同的密码和盐(使用 Rfc2898DeriveBytes 和 AesManaged())。 这是我在 Android 中的代码:

char[] passwordAsCharArray = password.toCharArray();
PBEKeySpec pbeKeySpec = new PBEKeySpec(passwordAsCharArray, salt, 1000, 256); 
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKeySpec secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES"); 

这是.net中的代码:

byte[] keyBytes = Encoding.Unicode.GetBytes(key);
Rfc2898DeriveBytes derivedKey = new Rfc2898DeriveBytes(key, keyBytes);
AesManaged rijndaelCSP = new AesManaged();
rijndaelCSP.BlockSize = 128;
rijndaelCSP.KeySize = 256;
rijndaelCSP.Key = derivedKey.GetBytes(rijndaelCSP.KeySize / 8);
rijndaelCSP.IV = derivedKey.GetBytes(rijndaelCSP.BlockSize / 8);                

ICryptoTransform decryptor = rijndaelCSP.CreateDecryptor();

当我比较两个键时,它们是不同的。任何想法如何在 Android 上生成与 .Net 中相同的密钥? (我知道在.net 中生成的密钥是正确的)。 .Net的迭代次数是1000,salt和password也和Android一样。


好的,事实证明我不需要完全相同的键(作为字节数组)。我需要这个来解密已经在.Net中加密的文件(用Java) - 使用这个密钥它给了我Bad Padding Exception所以我认为密钥不同并且导致问题,但我需要做的就是生成IV 像一把钥匙 - 这解决了我的问题。感谢回复!

【问题讨论】:

只是一个问题:您正在将 (String, byte[]) 传递给 Rfc2898DeriveBytes 构造函数,但我在 the docs 中找不到任何迭代次数。你确定 1000 是默认值吗? 是的,我已经检查过了:derivedKey.IterationsCount - value is 1000 能否向我们展示这两个代码 sn-ps 的十六进制输出,以便我们确保它不是输出编码错误?我认为您不需要将SecretKeyFactory.generateSecret() 的输出包装成SecretKeySpec 【参考方案1】:

看起来您在 .NET 代码中使用“密钥”(应该是密码)作为盐,而 Java 部分使用指定的盐。此外,您指定了用于解码 salt 的 Unicode 字符集,这很奇怪,salt 从一开始就应该是一个随机八位字节字符串(== 字节数组)。

我建议您首先将密码和随机盐转换为字节数组,使用十六进制表示(在您的控制台或调试器中)进行比较,然后再将它们用作每个中 PBKDF2 函数的输入参数。我建议您的密码使用 UTF-8 编码。

始终指定密码学中的所有参数,尽量不要使用默认值,例如为迭代计数。如果你的输入偏离了一个位,那么输出将完全不正确,并且无法判断哪个参数负责。

看起来 Java 和 .NET PBKDF2“原语”在两个平台上是相同的,互联网上有工作代码。

【讨论】:

以上是关于如何在 Java(Android)中生成与 .Net 中相同的 AES 密钥?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中生成与 Python 示例等效的 HMAC?

java - 如何在java中生成与openssl生成的相同类型的ecdsa密钥对?

有没有办法在java中生成与字母组合的ID?

如何在代码中分配动态资源样式?

如何使用 JDK 11 在 Android 项目中生成 javadoc

如何在Java中使用SHA384生成48个字符的哈希