HKDF是否在Java Cryptography Architecture中实现?

pup*_*eno 5 java hmac hkdf

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

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

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

pat*_*ckf 10

HKDF Java实现

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

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

当然,还有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 e.g. 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));
Run Code Online (Sandbox Code Playgroud)