Bouncy Castle Diffie-Hellman文档说明了在从静态长期密钥对中导出短暂密钥时使用“用户密钥资料”和KDF。没有提到如何生成此密钥材料。
例如,在BCFipsIn100.pdf中,他们有这个例子:
public static byte[] initiatorAgreementWithKdf(PrivateKey initiatorPrivate, PublicKey recipientPublic, byte[] userKeyingMaterial) throws GeneralSecurityException {
KeyAgreement agreement = KeyAgreement.getInstance("ECCDHwithSHA384CKDF", "BCFIPS");
agreement.init(initiatorPrivate, new UserKeyingMaterialSpec(userKeyingMaterial));
agreement.doPhase(recipientPublic, true);
SecretKey agreedKey = agreement.generateSecret("AES[256]");
return agreedKey.getEncoded();
}
他们的例子为userKeyingMaterial使用静态字符串,但是没有提到它应该是什么。
有关如何生成userKeyingMaterial的规范是什么?它可以是一个像他们的例子一样的静态字符串,还是它本质上是一个nonce?什么长度?当双方交换公钥时可以公开分享吗?
它在extraInfo
类中用作DHKDFParameters
参数,用于初始化KDF。 KDF可以用于通过混合除了共享秘密之外的附加字节来从主密钥导出不同的密钥,从密钥协商算法计算,在这种情况下是ECCDH。 SHA384KDF可能是ANS X9.63兼容的KDF,它需要一个额外的Info
八位字节串(这个八位字节串(即字节数组)有各种“信息”启发名称。
没有关于如何生成它的规范。它可能是标签的ASCII编码,比如"SessionKeyMaterial".getBytes(StandardCharsets.US_ASCII)
。它还可以包括双方的标识符,公钥,随机数。本质上它可以接收任何数据,只要您设法对不重叠的数据进行显式编码(即数据的规范表示)。
通常它只是一个称为标签的静态字符串。没有长度限制,数据可以公开共享。只要连接以这种或那种方式进行身份验证,共享密钥将确保生成的密钥仅在权利方之间共享;毕竟,你需要知道你与谁签订了密钥协议。