如何使用充气城堡在 Java 中实现三重 Diffie-Hellman(3 - DH) 密钥协议?
How to do a triple Diffie-Hellman(3 - DH) key agreement in Java using bouncy castle?
关于如何使用 Diffie-Hellman 密钥协商来计算共享密钥的示例有很多。但是,我找不到任何关于如何在 java 中使用充气城堡(或说实话提供的任何安全性)进行 3DH 的示例。我发现的所有内容,阅读的都是抽象理论,而不是真实的 implementation/example。
更具体地说,如何合并三个单独计算的 DH 协议?
一个很好的参考来源可以是 Signal's x3dh agreement protocol :
伪代码
DH1 = DH(IKA, SPKB)
DH2 = DH(EKA, IKB)
DH3 = DH(EKA, SPKB)
SK = KDF(DH1 || DH2 || DH3)
或者:
KeyAgreement ka1 = KeyAgreement.getInstance("X448",BouncyCastleProvider.PROVIDER_NAME); ka1.init(iPrivKey); //initator Private Key
ka1.doPhase(rPubKey, true); //recipient Public Key
byte[] secret1 = ka1.generateSecret();
...
byte[] secret2 = ka2.generateSecret();
...
byte[] secret3 = ka3.generateSecret();
准确地说我正在寻找如何做 SK = KDF(DH1 || DH2 || DH3)
已经计算了充气城堡中的 DH1 DH2 和 DH3? I.E 如何将 secret1、secret2 和 secret3 组合为输入键控 material 或 HKDFParameters 的种子?
正如@Topaco 所提到的,它只是三个共享秘密的简单串联。 Java代码如下:
byte[] getAgreementBytes(PrivateKey privKey,PublicKey pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
KeyAgreement ka = KeyAgreement.getInstance("X448", BouncyCastleProvider.PROVIDER_NAME);
ka.init(privKey);
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret();
privKey = null;//let gc do it's work
return secret;
}
...
...
...
byte[] secretA = getAgreementBytes(iPrivKeyA,getRPubKeyB());
byte[] secretB = getAgreementBytes(iPrivKeyB,getRPubKeyC());
byte[] secretC = getAgreementBytes(iPrivKeyC,getRPubKeyA());
byte[] secret = new byte[secretA.length + secretB.length + secretC.length];
System.arraycopy(secretA,0,secret,0,secretA.length);
System.arraycopy(secretB,0,secret,secretA.length,secretB.length);
System.arraycopy(secretC,0,secret,secretA.length + secretB.length,secretC.length);
return secret;
信号文档还提到使用 57 个 0xFF 字节(对于 X448),我还没有弄明白。但是,上面的代码对我有用。
关于如何使用 Diffie-Hellman 密钥协商来计算共享密钥的示例有很多。但是,我找不到任何关于如何在 java 中使用充气城堡(或说实话提供的任何安全性)进行 3DH 的示例。我发现的所有内容,阅读的都是抽象理论,而不是真实的 implementation/example。
更具体地说,如何合并三个单独计算的 DH 协议? 一个很好的参考来源可以是 Signal's x3dh agreement protocol :
伪代码
DH1 = DH(IKA, SPKB)
DH2 = DH(EKA, IKB)
DH3 = DH(EKA, SPKB)
SK = KDF(DH1 || DH2 || DH3)
或者:
KeyAgreement ka1 = KeyAgreement.getInstance("X448",BouncyCastleProvider.PROVIDER_NAME); ka1.init(iPrivKey); //initator Private Key
ka1.doPhase(rPubKey, true); //recipient Public Key
byte[] secret1 = ka1.generateSecret();
...
byte[] secret2 = ka2.generateSecret();
...
byte[] secret3 = ka3.generateSecret();
准确地说我正在寻找如何做 SK = KDF(DH1 || DH2 || DH3)
已经计算了充气城堡中的 DH1 DH2 和 DH3? I.E 如何将 secret1、secret2 和 secret3 组合为输入键控 material 或 HKDFParameters 的种子?
正如@Topaco 所提到的,它只是三个共享秘密的简单串联。 Java代码如下:
byte[] getAgreementBytes(PrivateKey privKey,PublicKey pubKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException {
KeyAgreement ka = KeyAgreement.getInstance("X448", BouncyCastleProvider.PROVIDER_NAME);
ka.init(privKey);
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret();
privKey = null;//let gc do it's work
return secret;
}
...
...
...
byte[] secretA = getAgreementBytes(iPrivKeyA,getRPubKeyB());
byte[] secretB = getAgreementBytes(iPrivKeyB,getRPubKeyC());
byte[] secretC = getAgreementBytes(iPrivKeyC,getRPubKeyA());
byte[] secret = new byte[secretA.length + secretB.length + secretC.length];
System.arraycopy(secretA,0,secret,0,secretA.length);
System.arraycopy(secretB,0,secret,secretA.length,secretB.length);
System.arraycopy(secretC,0,secret,secretA.length + secretB.length,secretC.length);
return secret;
信号文档还提到使用 57 个 0xFF 字节(对于 X448),我还没有弄明白。但是,上面的代码对我有用。