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