如何从DH密钥获取AES密钥

时间:2018-01-24 01:55:15

标签: java encryption cryptography aes diffie-hellman

我有以下代码将DH密钥转换为AES密钥。当它们开始限制DH密钥的创建时,这曾经工作到Oracle JRE 8u161 //without converting to some models we could directly use the jsonParsed foreach(var response in jsonParsed ){ if(response.tags['CitrixResource']=='name'){ //do something } } 文件中的1024。现在,我将在最后一行得到java.security

NoSuchAlgorithmException: Unsupported secret key algorithm AES

我尝试将最后一行改为此。我可以使用新密钥加密和解密,但这不适用于之前生成的旧密钥。

PrivateKey privKey = null;
PublicKey pubKey = null;
PublicKey agreement = null;

KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
keyAgreement.init(privKey);
keyAgreement.doPhase(pubKey, false);
keyAgreement.doPhase(agreement, true);
SecretKey key = keyAgreement.generateSecret("AES");

我发现了一个类似的问题What metod KeyAgreement.generateSecret(String algorithm) does?,但我仍然无法解决如何在不破坏现有密钥的情况下解决这个问题。

2 个答案:

答案 0 :(得分:2)

Oracle / Sun提供程序的问题不是java.security中的DH密钥大小限制,该限制仅适用于TLS / SSL(即JSSE),但是在您链接的发行说明中稍稍向下一点:

  
      
  • 更严格的密钥生成
  •   
     

generateSecret(String)方法在SunJCE和SunPKCS11提供程序的javax.crypto.KeyAgreement服务中已被禁用。对这些提供程序调用此方法将为大多数算法字符串参数产生NoSuchAlgorithmException。可以通过将jdk.crypto.KeyAgreement.legacyKDF系统属性的值设置为true(不区分大小写)来重新启用此方法的先前行为。不建议通过设置此系统属性来重新启用此方法。

接下来的段落基本上(不是很清楚)说明,正确使用DH需要合适的KDF,但是此操作无法提供/定义KDF,因此不能确保适用性,而应该使用no-参数generateSecretKey()方法来获取原始DH值并自己应用合适的KDF;他们以SP800-56Ar2和普通哈希为例。

BouncyCastle相反。在1.60中,它有几种KeyAgreement算法,其KDF编码为DHwithSHA256CKDF

答案 1 :(得分:1)

通常,在CipherKeyAgreement类本身中检查密钥大小要求,而不是提供者的服务实现。当然,尝试测试另一个提供商,例如Bouncy Castle提供商,无论[ EDIT :这似乎在这种情况下有效,因此密钥大小限制在Java运行时提供的默认提供程序中,使用" BC"提供者似乎工作正常,see the comment below the answer]。

如果使用其他提供商不起作用,那么使用Bouncy Castle轻量级API(org.bouncycastle.**类)来使用DH的另一个软件实现,完全绕过KeyAgreement类。然而,应该避免走出JCA / KeyAgreement之外。

毋庸置疑,不使用的要求< 1024位密钥是有原因的,它们不再被认为是安全的。尽快升级您的安全性!