四方Diffie-Hellman密钥交换

3

我正在尝试修改一个三方 Diffie-Hellman 密钥交换的示例。

以下是代码。

           
       // Alice uses Carol's public key
            Key ac = aliceKeyAgree.doPhase(carolKpair.getPublic(), false);
        // Bob uses Alice's public key
            Key ba = bobKeyAgree.doPhase(aliceKpair.getPublic(), false);
        // Carol uses Bob's public key
            Key cb = carolKeyAgree.doPhase(bobKpair.getPublic(), false);
            
            Key sc = saraKeyAgree.doPhase(carolKpair.getPublic(), false);
            
        // Alice uses Carol's result from above
            aliceKeyAgree.doPhase(cb, true);
        // Bob uses Alice's result from above
            bobKeyAgree.doPhase(ac, true);
        // Carol uses Bob's result from above
            carolKeyAgree.doPhase(ba, true);
            saraKeyAgree.doPhase(sc,true);
            
        // Alice, Bob and Carol compute their secrets
            byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
            System.out.println("Alice secret: " + toHexString(aliceSharedSecret));
            byte[] bobSharedSecret = bobKeyAgree.generateSecret();
            System.out.println("Bob secret: " + toHexString(bobSharedSecret));
            byte[] carolSharedSecret = carolKeyAgree.generateSecret();
            System.out.println("Carol secret: " + toHexString(carolSharedSecret));
            
            byte[] saraSharedSecret = saraKeyAgree.generateSecret();
            System.out.println("Sara secret: " + toHexString(saraSharedSecret));
        // Compare Alice and Bob
            if (!java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret))
                throw new Exception("Alice and Bob differ");
            System.out.println("Alice and Bob are the same");
        // Compare Bob and Carol
            if (!java.util.Arrays.equals(bobSharedSecret, carolSharedSecret))
                throw new Exception("Bob and Carol differ");
            System.out.println("Bob and Carol are the same");

在这个过程的结尾,只有3个结果匹配,第四个结果不同。我做错了什么?

1
请关注Diffie-Hellman密钥交换中的多方操作的讨论。 - undefined
@JamesReinstateMonicaPolk 这对我理解这个主题有所帮助,足以回答问题,尽管它并没有完全解释其中一些发布的代码。 - undefined
1个回答

3

更新的答案

我仍然不是密码学专家,所以在做这个过程中我学到了很多,非常感谢!

我已经重写了逻辑,下面的整个示例已发布,供以后遇到此问题的任何人参考。它还在Compile Java的沙盒中进行了测试。

我将尝试解释这里发生的事情,但如果有人注意到我的实现/解释中存在明显缺陷,请告诉我。我不能说我完全理解了它或Java所使用的API,因此非常希望得到任何澄清。

解释

这使用了一些聪明的数学技巧,其中大部分由底层API处理,我们只需要按照正确的顺序和正确的值告诉它该做什么。

选择生成器g和模数p,并在所有参与者之间共享。

Alice、Bob、Carol和Sara选择私钥(A、B、CS)并计算其公钥(gA,gB,gC,gS)。这些是从g的私钥幂模p计算出来的。

每个参与者都需要将其操作结果发送给下一个参与者,并且每个参与者都需要使用从另一个参与者传递过来的值执行n-1次操作,其中n是参与者的数量。

在此过程结束时,每个参与者都将通过使用进程和传递方法,将g提高到每个其他人的私钥幂模p而无需向彼此透露其私钥。

在第一轮中,每个参与者通过将其公钥提高到左侧参与者的公钥幂模p,计算出中间值(gAB,gBC等)。

在第2+次通过中,他们重复此过程,但是使用来自其左侧的人的上一次操作结果,将该结果提高到其自己的私钥幂模p

这种传递和计算过程重复进行,直到每个人都计算出了gABCS,它变成了共享的秘密。

由于数学的工作方式(如果我没有弄错,则是指数法则),gABCS=gBCSA=gCSAB=gSABC等。

一个窃听者Eve可以看到 gA, gB, gC, gS, gAB, gBC, gCS, gSA, gABC, gBCS, gCSA 的值,但是她不能使用它们的任何组合来有效地重现 gABCS,因为她不知道A,B,CS的值,这些是从未传输的私钥。
理论上,这种方法可以扩展到更多参与者。按照下面代码中的模式进行操作。您需要添加另一个参与者,在每次传递中将其添加到操作列表中,并添加一次操作以确保每个人都执行所需的操作数量。
下面添加了关于四个和五个参与者的示例代码。
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
   /*
    * This program executes the Diffie-Hellman key agreement protocol between
    * 4 parties: Alice, Bob, Carol and Sara using a shared 2048-bit DH parameter.
    */
    public class DHKeyAgreement4 {
        private DHKeyAgreement4() {}
        public static void main(String argv[]) throws Exception {


        // Alice creates her own DH key pair with 2048-bit key size
            KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
            aliceKpairGen.initialize(2048);
            KeyPair aliceKpair = aliceKpairGen.generateKeyPair();
        // This DH parameters can also be constructed by creating a
        // DHParameterSpec object using agreed-upon values
            DHParameterSpec dhParamShared = ((DHPublicKey)aliceKpair.getPublic()).getParams();
        // Bob creates his own DH key pair using the same params
            KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
            bobKpairGen.initialize(dhParamShared);
            KeyPair bobKpair = bobKpairGen.generateKeyPair();
        // Carol creates her own DH key pair using the same params
            KeyPairGenerator carolKpairGen = KeyPairGenerator.getInstance("DH");
            carolKpairGen.initialize(dhParamShared);
            KeyPair carolKpair = carolKpairGen.generateKeyPair();
        // Carol creates her own DH key pair using the same params
            KeyPairGenerator saraKpairGen = KeyPairGenerator.getInstance("DH");
            saraKpairGen.initialize(dhParamShared);
            KeyPair saraKpair = saraKpairGen.generateKeyPair();




          //Alice initialize
          KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
          //Alice computes gA
          aliceKeyAgree.init(aliceKpair.getPrivate());

          //Bob initialize
          KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
          //Bob computes gB
          bobKeyAgree.init(bobKpair.getPrivate());

          //Carol initialize
          KeyAgreement carolKeyAgree = KeyAgreement.getInstance("DH");
          //Carol computes gC
          carolKeyAgree.init(carolKpair.getPrivate());

          //Sara initialize
          KeyAgreement saraKeyAgree = KeyAgreement.getInstance("DH");
          //Sara computes gS
          saraKeyAgree.init(saraKpair.getPrivate());


          //First Pass

          //Alice computes gSA
          Key gSA = aliceKeyAgree.doPhase(saraKpair.getPublic(), false);

          //Bob computes gAB
          Key gAB = bobKeyAgree.doPhase(aliceKpair.getPublic(), false); 

          //Carol computes gBC
          Key gBC = carolKeyAgree.doPhase(bobKpair.getPublic(), false); 

          //Sara computes gCS
          Key gCS = saraKeyAgree.doPhase(carolKpair.getPublic(), false);


          //Second Pass

          //Alice computes gCSA
          Key gCSA = aliceKeyAgree.doPhase(gCS, false);

          //Bob computes gSAB
          Key gSAB = bobKeyAgree.doPhase(gSA, false);

          //Carol computes gABC
          Key gABC = carolKeyAgree.doPhase(gAB, false);

          //Sara computes gBCS
          Key gBCS = saraKeyAgree.doPhase(gBC, false); 


          //Third Pass

          //Alice computes gBCSA
          Key gBCSA = aliceKeyAgree.doPhase(gBCS, true); //This is Alice's secret

          //Bob computes gCSAB
          Key gCSAB = bobKeyAgree.doPhase(gCSA, true); //This is Bob's secret

          //Sara Computes gABCS
          Key gABCS = saraKeyAgree.doPhase(gABC, true); //This is Sara's secret

          //Carol computes gSABC
          Key gSABC = carolKeyAgree.doPhase(gSAB, true); //This is Carol's secret



        // Alice, Bob, Carol and Sara compute their secrets
            byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
            System.out.println("Alice secret: " + toHexString(aliceSharedSecret));

            byte[] bobSharedSecret = bobKeyAgree.generateSecret();
            System.out.println("Bob secret: " + toHexString(bobSharedSecret));

            byte[] carolSharedSecret = carolKeyAgree.generateSecret();
            System.out.println("Carol secret: " + toHexString(carolSharedSecret));

            byte[] saraSharedSecret = saraKeyAgree.generateSecret();
            System.out.println("Sara secret: " + toHexString(saraSharedSecret));

        // Compare Alice and Bob
            if (!java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret))
                System.out.println("Alice and Bob differ");//    throw new Exception("Alice and Bob differ");
            else
                System.out.println("Alice and Bob are the same");
        // Compare Bob and Carol
            if (!java.util.Arrays.equals(bobSharedSecret, carolSharedSecret))
                System.out.println("Bob and Carol differ");//throw new Exception("Bob and Carol differ");
            else
                System.out.println("Bob and Carol are the same");
          //Compare Carol and Sara
            if (!java.util.Arrays.equals(carolSharedSecret, saraSharedSecret))
                System.out.println("Carol and Sara differ");//throw new Exception("Carol and Sara differ");
            else
                System.out.println("Carol and Sara are the same");

        }
    /*
     * Converts a byte to hex digit and writes to the supplied buffer
     */
        private static void byte2hex(byte b, StringBuffer buf) {
            char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                                '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            int high = ((b & 0xf0) >> 4);
            int low = (b & 0x0f);
            buf.append(hexChars[high]);
            buf.append(hexChars[low]);
        }
    /*
     * Converts a byte array to hex string
     */
        private static String toHexString(byte[] block) {
            StringBuffer buf = new StringBuffer();
            int len = block.length;
            for (int i = 0; i < len; i++) {
                byte2hex(block[i], buf);
                if (i < len-1) {
                    buf.append(":");
                }
            }
            return buf.toString();
        }
    }

五人参与的示例

import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.crypto.interfaces.*;
   /*
    * This program executes the Diffie-Hellman key agreement protocol between
    * 5 parties: Alice, Bob, Carol, Sara and Dave using a shared 2048-bit DH parameter.
    */
    public class DHKeyAgreement5 {
        private DHKeyAgreement5() {}
        public static void main(String argv[]) throws Exception {


        // Alice creates her own DH key pair with 2048-bit key size
            KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
            aliceKpairGen.initialize(2048);
            KeyPair aliceKpair = aliceKpairGen.generateKeyPair();
        // This DH parameters can also be constructed by creating a
        // DHParameterSpec object using agreed-upon values
            DHParameterSpec dhParamShared = ((DHPublicKey)aliceKpair.getPublic()).getParams();
        // Bob creates his own DH key pair using the same params
            KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
            bobKpairGen.initialize(dhParamShared);
            KeyPair bobKpair = bobKpairGen.generateKeyPair();
        // Carol creates her own DH key pair using the same params
            KeyPairGenerator carolKpairGen = KeyPairGenerator.getInstance("DH");
            carolKpairGen.initialize(dhParamShared);
            KeyPair carolKpair = carolKpairGen.generateKeyPair();
        // Sara creates her own DH key pair using the same params
            KeyPairGenerator saraKpairGen = KeyPairGenerator.getInstance("DH");
            saraKpairGen.initialize(dhParamShared);
            KeyPair saraKpair = saraKpairGen.generateKeyPair();
                    // Dave creates her own DH key pair using the same params
            KeyPairGenerator daveKpairGen = KeyPairGenerator.getInstance("DH");
            daveKpairGen.initialize(dhParamShared);
            KeyPair daveKpair = daveKpairGen.generateKeyPair();



          //Alice initialize
          KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
          //Alice computes gA
          aliceKeyAgree.init(aliceKpair.getPrivate());

          //Bob initialize
          KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
          //Bob computes gB
          bobKeyAgree.init(bobKpair.getPrivate());

          //Carol initialize
          KeyAgreement carolKeyAgree = KeyAgreement.getInstance("DH");
          //Carol computes gC
          carolKeyAgree.init(carolKpair.getPrivate());

          //Sara initialize
          KeyAgreement saraKeyAgree = KeyAgreement.getInstance("DH");
          //Sara computes gS
          saraKeyAgree.init(saraKpair.getPrivate());

          //Dave initialize
          KeyAgreement daveKeyAgree = KeyAgreement.getInstance("DH");
          //Sara computes gS
          daveKeyAgree.init(daveKpair.getPrivate());


          //First Pass

          //Alice computes gDA
          Key gDA = aliceKeyAgree.doPhase(daveKpair.getPublic(), false);

          //Bob computes gAB
          Key gAB = bobKeyAgree.doPhase(aliceKpair.getPublic(), false); 

          //Carol computes gBC
          Key gBC = carolKeyAgree.doPhase(bobKpair.getPublic(), false); 

          //Sara computes gCS
          Key gCS = saraKeyAgree.doPhase(carolKpair.getPublic(), false);

          //Dave computed gSD
          Key gSD = daveKeyAgree.doPhase(saraKpair.getPublic(), false);


          //Second Pass

          //Alice computes gSDA
          Key gSDA = aliceKeyAgree.doPhase(gSD, false);

          //Bob computes gDAB
          Key gDAB = bobKeyAgree.doPhase(gDA, false);

          //Carol computes gABC
          Key gABC = carolKeyAgree.doPhase(gAB, false);

          //Sara computes gBCS
          Key gBCS = saraKeyAgree.doPhase(gBC, false); 

          //Dave computes gCSD
          Key gCSD = daveKeyAgree.doPhase(gCS, false); 

          //Third Pass

          //Alice computes gCSDA
          Key gCSDA = aliceKeyAgree.doPhase(gCSD, false); 

          //Bob computes gSDAB
          Key gSDAB = bobKeyAgree.doPhase(gSDA, false); 

          //Carol computes gDABC
          Key gDABC = carolKeyAgree.doPhase(gDAB, false); 

          //Sara Computes gABCS
          Key gABCS = saraKeyAgree.doPhase(gABC, false); 

          //Dave computes gBCSC
          Key gBCSD = daveKeyAgree.doPhase(gBCS, false); 

          //Fourth Pass

          //Alice computes gBCSDA
          Key gBCSDA = aliceKeyAgree.doPhase(gBCSD, true); //This is Alice's secret

          //Bob computes gSDABC
          Key gCSDAB = bobKeyAgree.doPhase(gCSDA, true); //This is Bob's secret

          //Carol computes gSABC
          Key gSDABC = carolKeyAgree.doPhase(gSDAB, true); //This is Carol's secret

          //Sara Computes gABCS
          Key gDABCS = saraKeyAgree.doPhase(gDABC, true); //This is Sara's secret


          Key gABCSD = daveKeyAgree.doPhase(gABCS, true); //This is Dave's secret



        // Alice, Bob, Carol and Sara compute their secrets
            byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();
            System.out.println("Alice secret: " + toHexString(aliceSharedSecret));

            byte[] bobSharedSecret = bobKeyAgree.generateSecret();
            System.out.println("Bob secret: " + toHexString(bobSharedSecret));

            byte[] carolSharedSecret = carolKeyAgree.generateSecret();
            System.out.println("Carol secret: " + toHexString(carolSharedSecret));

            byte[] saraSharedSecret = saraKeyAgree.generateSecret();
            System.out.println("Sara secret: " + toHexString(saraSharedSecret));

          byte[] daveSharedSecret = daveKeyAgree.generateSecret();
            System.out.println("Dave secret: " + toHexString(daveSharedSecret));

        // Compare Alice and Bob
            if (!java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret))
                System.out.println("Alice and Bob differ");//    throw new Exception("Alice and Bob differ");
            else
                System.out.println("Alice and Bob are the same");
        // Compare Bob and Carol
            if (!java.util.Arrays.equals(bobSharedSecret, carolSharedSecret))
                System.out.println("Bob and Carol differ");//throw new Exception("Bob and Carol differ");
            else
                System.out.println("Bob and Carol are the same");
          //Compare Carol and Sara
            if (!java.util.Arrays.equals(carolSharedSecret, saraSharedSecret))
                System.out.println("Carol and Sara differ");//throw new Exception("Carol and Sara differ");
            else
                System.out.println("Carol and Sara are the same");
          //Compare Sara and Dave
          if (!java.util.Arrays.equals(saraSharedSecret, daveSharedSecret))
                System.out.println("Sara and Dave differ");//throw new Exception("Carol and Sara differ");
            else
                System.out.println("Sara and Dave are the same");

        }
    /*
     * Converts a byte to hex digit and writes to the supplied buffer
     */
        private static void byte2hex(byte b, StringBuffer buf) {
            char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                                '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            int high = ((b & 0xf0) >> 4);
            int low = (b & 0x0f);
            buf.append(hexChars[high]);
            buf.append(hexChars[low]);
        }
    /*
     * Converts a byte array to hex string
     */
        private static String toHexString(byte[] block) {
            StringBuffer buf = new StringBuffer();
            int len = block.length;
            for (int i = 0; i < len; i++) {
                byte2hex(block[i], buf);
                if (i < len-1) {
                    buf.append(":");
                }
            }
            return buf.toString();
        }
    }

根据你的逻辑,Alice、Bob和Carol的密钥彼此不同,而我需要这四个人都有相同的密钥。 - undefined
你能编辑你的问题,将你从中工作的示例作为一个单独的块包含进来吗? - undefined
Alice计算A=ga,Bob计算B=gb,Charlie计算C=gc。A、B和C被公开。Alice计算AC=Ca,Bob计算AB=Ba,Charlie计算BC=Cb。AB、AC和BC被公开。Alice计算ABC=BCa,Bob计算ABC=ACb,Charlie计算ABC=ABc。每个人共享ABC=gabc。这是三方算法,并在上面的代码中实现。 - undefined
不好意思,我是指你能否编辑你的问题,包括你所使用的实际代码作为基础,或者提供一个链接。 - undefined
1
从这里开始,我使用了三方的Deffie Helman密钥交换。 - undefined
太棒了。如果这个有效,请接受答案 :) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接