Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java/Erlang:Diffie-Hellman密钥交换不工作_Java_Erlang_X509_Diffie Hellman - Fatal编程技术网

Java/Erlang:Diffie-Hellman密钥交换不工作

Java/Erlang:Diffie-Hellman密钥交换不工作,java,erlang,x509,diffie-hellman,Java,Erlang,X509,Diffie Hellman,我想为我的应用程序实现我自己的加密。我对这篇文章做了一次大的修改。直到今天,我真的没有多少时间来解决这个问题。希望这比我原来的更有用。在这个问题上花了太多时间。希望能节省别人的时间 在执行此操作时,我遇到了几个问题。直到最后我才意识到发生了什么。我得到了不同的共享秘密,后来又得到了一些例外 这就是我所尝试的: 使用两种语言提供的内置设施。无法理解如何将原始公钥转换为Java可以使用的表单 划破了这一点,然后使用简单的公式来计算各方的公钥和私钥。(从统计上看,这本可以在大约25%的时间内奏效……

我想为我的应用程序实现我自己的加密。我对这篇文章做了一次大的修改。直到今天,我真的没有多少时间来解决这个问题。希望这比我原来的更有用。在这个问题上花了太多时间。希望能节省别人的时间

在执行此操作时,我遇到了几个问题。直到最后我才意识到发生了什么。我得到了不同的共享秘密,后来又得到了一些例外

这就是我所尝试的:

  • 使用两种语言提供的内置设施。无法理解如何将原始公钥转换为Java可以使用的表单
  • 划破了这一点,然后使用简单的公式来计算各方的公钥和私钥。(从统计上看,这本可以在大约25%的时间内奏效……幸运的是,我没有。)
  • 深入到ITU的ASN.1文档中,并发送了以类似于Java密钥的方式编码的Erlang公钥。通过将Java密钥保存到文件并使用十六进制编辑器来确定这一点。我没有回去做很长时间的测试。它确实去掉了
    java.security.spec.InvalidKeySpecException:不适当的密钥规范
    。我想统计数据在这里也对我不利。秘密仍然不一致
  • 将所有数字从Java发送到Erlang端以计算密钥,使用Java数字共享机密。。。同样的数字。有希望
  • 开始仔细检查他们交流的数据。这有点费时,因为Erlang将数据组织为无符号字节。EclipseIDE(可能在某些地方需要更改设置)在字节数组中使用有符号字节,在
    biginger
    中使用有符号整数数组

这就是我开始看到东西的地方。这些都是在多次迭代中手动输入的,以确保我找到了正确的事件模式。在Erlang中,我看到我的公钥以
开头,问题在于阅读文档,而不是理解文档。我花了很多时间在参考页上,因为我不经常编码。在
biginger
的文档中,我没有考虑太多这个特定的细节:

所有操作的行为就像大整数在 two's-complete表示法

在我的原始代码中有两个地方出现了问题:

       Ys = new BigInteger(buf2);          
       Sc = Ys.modPow(Xc, DiffieHellman.Group2.P);
第一行的问题是,如果在第一个字节中设置了位8,则整个
buf2
数组需要在前面加上
0x00
字节。第二行也有问题。。。在执行以下行之前,它不会变得明显:
aeskey=hash.digest(Sc.toByteArray())

这里的问题是,如果在结果的第一个字节中设置了位8<代码>0x00
在其前面。这将转发到
摘要()
函数,但需要省略

我的代码已更改为下面的代码,并且可以正常工作:)

这是因为私钥可以是“任意随机数”。
0x00
字节是在第二行中客户端公钥的前面加上的。但是,Erlang将整数解释为big-endian,任何前导的
0x00
字节最终都是不相关的,因为它不会影响数值,因此不会影响执行
加密:mod_pow()时的结果


关于如何改进代码的评论非常受欢迎。

当您通过套接字发送数据时,您无法知道它将分成多少块。当您指定
{packet,raw}
(或等效地
{packet,0}
)时,您告诉erlang您将负责将不确定数量的块组合到完整的数据中,因此erlang只将每个块放入单独的消息中。请参见此处:。我不知道上述问题是否导致了您的任何问题,但这是您需要解决的问题。@7stud谢谢。很容易改变。我想TCP可以解决这个问题。我相信TCP应该是在操作系统中实现的最高级别。然而,我注意到两件事。1) 密钥正确传输(仅128字节)2)当我使用
{packet,2}
时,我想erlang可能期待我在Java应用程序中没有提供的东西,并且无限期地挂起。我使用了
1
,这导致了成功的传输,但Java端的键长了1字节。更多的东西需要管理。我想TCP会处理的。我认为TCP处理的是将数据块拆分成数据包进行发送,然后在接收端将数据包重新组装成数据块——但数据拆分成的数据块数量由网络缓冲区的状态决定。读这个:还有这个:
public class MyProgram {
    private static Socket s;
    private static OutputStream out;
    private static InputStream in;
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MessageDigest hash;
        byte buffer[] = new byte[1024];
        byte buf2[];
        int len = 0;
        byte[] aeskey;

        try {
            hash = MessageDigest.getInstance("SHA-256");
            byte    keybuffer[] = new byte[64];
            SecureRandom srnd = SecureRandom.getInstance("SHA1PRNG");
            BigInteger Xc, Yc, Sc, Ys;

            srnd.nextBytes(keybuffer);
            Xc = new BigInteger(keybuffer);
            Yc = new BigInteger("2").modPow(Xc, DiffieHellman.Group2.P);

            s = new Socket("localhost",12321);
            out = s.getOutputStream();
            in = s.getInputStream();

            out.write(Yc.toByteArray());
            out.flush();

            len = in.read(buffer);
            buf2 = new byte[len];
            System.arraycopy(buffer, 0, buf2, 0, len);

            Ys = new BigInteger(buf2);          
            Sc = Ys.modPow(Xc, DiffieHellman.Group2.P);
            aeskey = hash.digest(Sc.toByteArray());

            out.close();
            in.close();
            s.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }
}
       Ys = new BigInteger(buf2);          
       Sc = Ys.modPow(Xc, DiffieHellman.Group2.P);
    len = in.read(buffer);
    buf2 = new byte[len+1];
    System.arraycopy(buffer, 0, buf2, 1, len);
    buf2[0] = 0;

    if(buf2[1] < 0)
        Ys = new BigInteger(buf2);
    else
        Ys = new BigInteger(Arrays.copyOfRange(buf2, 1, buf2.length));

    Sc = Ys.modPow(Xc, DiffieHellman.Group2.P);
    buffer = Sc.toByteArray();
    if(buffer[0] == 0)
        aeskey = hash.digest(Arrays.copyOfRange(buffer, 1, buffer.length));
    else
        aeskey = hash.digest(buffer);
    Xc = new BigInteger(keybuffer);
    Yc = new BigInteger("2").modPow(Xc, DiffieHellman.Group2.P);