简体   繁体   中英

How to do a triple Diffie-Hellman(3 - DH) key agreement in Java using bouncy castle?

There are ample examples on how to do Diffie-Hellman key agreement to compute a shared secret. However, I could not find any example on how to do 3DH in java using bouncy castle(or any security provided to be honest). All of what I am finding, reading is abstract theory, and not actual real implementation/example.

More specifically, how can the three individually computed DH agreements be combined? A good source of reference could be Signal's x3dh agreement protocol :

pseudo code

    DH1 = DH(IKA, SPKB)
    DH2 = DH(EKA, IKB)
    DH3 = DH(EKA, SPKB)
    SK = KDF(DH1 || DH2 || DH3)

or alternatively:

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(); 

To be exactly precise on what I am looking for how to do SK = KDF(DH1 || DH2 || DH3) having already computed DH1 DH2 and DH3 in bouncy castle? IE how to combine secret1, secret2 and secret3 as input keying material or seed for HKDFParameters?

As mentioned by @Topaco it is just plain concatenation of the three shared secrets. Java code follows:

     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;

The signal doc also mentions using 57 0xFF bytes (for X448), which I am yet to make sense of. However, the above code works for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM