HKDF是否在Java Cryptography Architecture中实现?

在我写的应用程序中,我需要使用HKDF从一个密码中派生出两个不同的密钥。 在Java中搜索如何使用它的示例我发现了这两个:

  • https://github.com/WhisperSystems/libsignal-protocol-java/blob/master/java/src/main/java/org/whispersystems/libsignal/kdf/HKDF.java
  • https://www.javatips.net/api/keywhiz-master/hkdf/src/main/java/keywhiz/hkdf/Hkdf.java

在这两种情况下,HKDF都是在JCA提供的HMAC之上实施的。 我还没有详细阅读这些实现,但我想知道,这是不是在JCA或其自身的任何地方实现的? 我是否必须实施自己的HKDF?

最让我担心的部分是在应用info参数时犯了一个错误。 它看起来非常重要而且至关重要。

HKDF Java实现

否, 基于散列消息validation码(HMAC)的密钥派生函数(HKDF)与大多数KDF一样,在JCA中没有标准实现。

其他项目中嵌入了一些实现(如您所说):

  • Mozilla的服务/同步加密
  • WhisperSystems / libsignal -协议- java的
  • 方/ keywhiz

当然,还有Bouncy Castle使用他们自己的Hmac / Mac实现和API。 然而,BC是一种巨大的依赖性,并且对于例如嵌入式或移动用例而言可能是不实用的。 为此我实现了一个独立的轻量级java lib(传递所有RFC 5869测试向量),它适用于任何javax.crypto.Mac实例:

如果您愿意,当使用内置的JCA Hmac实现时,您当然可以自己实现它,这是一个相当直接的规范。

HKDF中的信息参数

来自RFC 5869 :

虽然’info’值在HKDF的定义中是可选的,但它是
在应用程序中经常非常重要。 其主要目标是
将派生的密钥材料绑定到特定于应用程序和上下文
信息。 (…)特别是,它可以防止针对不同的上下文推导出相同的密钥材料。

因此,例如,如果您想从相同的源材料派生密钥和IV,您将使用info参数( 使用此lib ):

 //example input String userInput = "this is a user input with bad entropy"; HKDF hkdf = HKDF.fromHmacSha256(); //extract the "raw" data to create output with concentrated entropy byte[] pseudoRandomKey = hkdf.extract(staticSalt32Byte, userInput.getBytes(StandardCharsets.UTF_8)); //create expanded bytes for eg AES secret key and IV byte[] expandedAesKey = hkdf.expand(pseudoRandomKey, "aes-key".getBytes(StandardCharsets.UTF_8), 16); byte[] expandedIv = hkdf.expand(pseudoRandomKey, "aes-iv".getBytes(StandardCharsets.UTF_8), 16); //Example boilerplate encrypting a simple string with created key/iv SecretKey key = new SecretKeySpec(expandedAesKey, "AES"); //AES-128 key Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(expandedIv)); byte[] encrypted = cipher.doFinal("my secret message".getBytes(StandardCharsets.UTF_8)); 
Interesting Posts