Java Bouncy Castle Diffie Hellman与KDF的密钥协议:什么是用户密钥材料?

Java Bouncy Castle Diffie Hellman与KDF的密钥协议:什么是用户密钥材料?,java,cryptography,bouncycastle,diffie-hellman,kdf,Java,Cryptography,Bouncycastle,Diffie Hellman,Kdf,Bouncy Castle Diffie-Hellman文档提到在从静态长期密钥对导出临时密钥时使用“用户密钥材料”和KDF。没有提到如何生成此关键材料 例如,在BCFipsIn100.pdf中,他们有以下示例: public static byte[] initiatorAgreementWithKdf(PrivateKey initiatorPrivate, PublicKey recipientPublic, byte[] userKeyingMaterial) throws Ge

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?多长?当双方交换公钥时,它是否可以公开共享?

它用作
DHKDFParameters
类中的
extraInfo
参数,用于初始化KDF。KDF可用于通过在共享密钥之外的额外字节中混合从主密钥导出不同密钥,该共享密钥是根据密钥协商算法计算的,在这种情况下为ECCDH。SHA384KDF可能是与ANS X9.63兼容的KDF,它采用额外的
Info
octet字符串(该八位字符串(即字节数组)有各种“Info”名称)

没有关于如何生成它的规范。它可能是标签的ASCII编码,例如
“SessionKeyMaterial”.getBytes(StandardCharsets.US_ASCII)
。它还可以包括双方的标识符、公钥、nonce。基本上,它可以接受任何数据,只要您能够对该数据进行不重叠的显式编码(即数据的规范表示)


通常它只是一个称为标签的静态字符串。没有长度限制,数据可以公开共享。共享机密将确保生成的密钥在正确的各方之间共享,只要连接通过某种方式进行了身份验证;毕竟,您需要知道您正在与谁执行密钥协议

有趣的是,它可以是一个静态公共字符串或一个随机的nonce;我假设随机字节更好。在Bouncy Castle电子邮件列表中,建议使用长度至少等于KDF摘要大小的随机字节(例如BCFIPS示例中的SHA384)。如果两个DH密钥都是静态的,则它们可能是随机字节,这一点很重要。但之后您肯定必须验证会话密钥。无论如何,验证它们是一个好主意,当然,例如,通过在以前的消息上计算MAC。注入更多的随机性将简化一些安全性证明,但作为(EC)DH密钥对无论如何都应该随机生成,这在实践中并不是绝对必要的。我已将Java添加到标记中。请始终尝试指示运行时环境。如果我猜错了,请更改。请注意,SHA-384本质上是SHA-512,具有不同的初始常量值,然后从结果中提取最左边的位。SHA-512将具有相同的属性和更大的输出,如果您需要的话。