当前位置: 首页 > 面试题库 >

比播种SecureRandom更好的方法来创建AES密钥

壤驷雅达
2023-03-14
问题内容

我需要将加密的数据从Java客户端发送到C#服务器。现在,我正在学习如何使用AES(要求)加密数据。按照这个公认的答案使用AES进行android加密/解密,我正在执行以下操作:

byte[] keyStart = "qweroiwejrwoejlsifeoisrn".getBytes(); // Random character string

byte[] toEncrypt = myMessageString.getBytes();

keyGen = KeyGenerator.getInstance("AES");
sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
keyGen.init(128, sr);
SecretKey secretKey = keyGen.generateKey();
byte[] secretKeyByte = secretKey.getEncoded();

SecretKeySpec skeySpec = new SecretKeySpec(secretKeyByte, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
cipher.doFinal(toEncrypt);

由于该算法SecureRandom使用,keyStart我不确定如果没有,是否可以在C#甚至其他Java程序中对此进行解码SecureRandom

这种加密/解密是否仅在知道的值的情况下工作,keyStart或者由于我正在使用,SecureRandom我仍然需要传递其他内容才能解密?

另外,还有更好的方法吗?或者这还好吗?


问题答案:

不,您应该使用a SecureRandom来从静态数据中派生密钥的想法非常糟糕:

  1. SecureRandom的主要功能是生成随机值,不应将其用作密钥流的生成器;
  2. SecureRandom,当实例化为时,"SHA1PRNG"并不能实现定义良好的算法,并且实际上已经知道该算法会发生变化,甚至从一个Sun JDK更改为另一个。
  3. Oracle提供的"SHA1PRNG"使用初始种子作为 唯一 种子的实现,其他人可能只是 种子 添加 到随机池中。

使用"SHA1PRNG"的密钥导出函数已经知道生产Android上的几个版本的问题,并且可能无法在任何其他Java RE。

那么,您应该怎么做呢?

  1. 使用new SecureRandom()或什至更好KeyGenerator地生成真正的随机密钥,如果您需要全新的随机密钥,则无需播种随机数生成器;
  2. byte[]将已知密钥直接提供给SecretKeySpec,或使用十六进制解码器从十六进制对其进行解码(请注意,String实例很难从内存中删除,因此,只有在没有其他方法的情况下,才可以这样做);
  3. 如果要通过密码创建密钥,请使用PBKDF2(尽管使用的迭代次数要比链接中提供的次数高);
  4. 如果要从一个密钥种子中创建多个密钥,请使用真正的基于密钥的密钥派生机制,例如,使用HKDF(请参见下文)。

如果种子是通过例如密钥协商算法(例如Diffie-Hellman或ECDH)生成的,则首选选项4。

请注意,对于选项3 PBKDF2,明智的做法是仅保留ASCII密码。这是由于Oracle的PBKDF2实现不使用UTF-8编码这一事实。

至于选项4,我已经帮助将所有好的KBKDF添加到BouncyCastle库中,因此,如果您可以将BouncyCastle添加到您的类路径和/或已安装的安全提供程序列表中,则无需自己实现KBKDF。目前最好的KBKDF可能是HKDF。如果无法将BouncyCastle添加到类路径中,则可能需要将派生数据上SHA-256输出的最左边字节用作“穷人” KDF。



 类似资料:
  • 我正在尝试使用AES加密算法加密文本,将此加密文本保存到文件中,然后稍后重新打开并解密这些文本。下面是我的加密和解密逻辑 这就是解密逻辑 我收到一个“大小错误”异常。我的猜测是,通过使用 SecureRandom 类,这两种方法在加密或欺骗文本时使用不同的密钥。有没有办法在两个例程中使用相同的密钥?

  • 问题内容: 在我们的代码库中找到以下代码: 在这里,将创建一个默认值,然后使用该默认值为另一个种子创建种子,该种子将在本课程的稍后版本中使用。这真的有必要吗?因为这样做了,第二个比第一个好吗? 当第二秒生成种子时,给出了字节数,这重要吗?难道一个比另一个不同数量的字节播种可能是好还是坏?用于播种的字节数是否应该与将用于的字节数相对应? 如果未调用setSeed,则对nextBytes的第一次调用将

  • Edit:是我现在正在做的事情,但是由于只是返回,所以这似乎是对Map的误用。另外,它读起来并不像是商业逻辑。 最后编辑:我接受了@Holger的回答。不能期望处理流上的所有元素,因为它不是终端操作。也是如此。即使您可能已经终止了您的流,以保证它将处理所有操作,您也不应该编写期望每个用户都这样做的代码。因此,要进行处理,您应该在上使用,然后根据需要再次开始对进行流式处理。

  • 本文向大家介绍Python实现AES加密,解密的两种方法,包括了Python实现AES加密,解密的两种方法的使用技巧和注意事项,需要的朋友参考一下 第一种 第二种 以上就是Python实现AES加密,解密的两种方法的详细内容,更多关于Python实现AES加密,解密的资料请关注呐喊教程其它相关文章!

  • 我正在尝试使用Nimbus JOSE+JWT从我的私钥解密JWE数据。 有人能帮我解决这个问题吗。我使用的是Java1.8 我的私钥 我的JWE数据

  • 问题内容: 一直困扰我的是Javascript中的方法多么不可预测。 根据我的经验,在很多情况下计时器都非常不准确。所谓不准确,是指实际延迟时间或多或少地相差250-500ms。尽管这不是很长的时间,但是使用它来隐藏/显示UI元素时,时间显然是显而易见的。 是否有任何技巧可以确保准确执行(无需借助外部API),或者这是一个失败的原因? 问题答案: 是否有任何技巧可以确保准确执行(无需借助外部API