我的Android应用程序具有节点js服务器,我希望使用DH密钥交换来确保通信的安全。我可以使用与nodejs相同的Java生成素数p
和基数g
(如果不正确,可以更正)
问题:
1。。我想在客户端和服务器端都使用秘密p
和g
,因为双方都将进行加密和解密
文档中显示的crypto.createDiffieHellman()
nodejs函数仅采用bitlength
的参数,因此在发现其他方法签名存在后,我对这些参数进行了硬编码。从文档中,我知道应该仅共享公共密钥。这些p
和g
最初是在客户端生成的
2。。在下面的示例代码中,密钥和秘密生成在nodejs中运行良好,但是当我从客户端(使用new String(Hex.encodeHex(kp.getPublic().getEncoded()))
生成的公共密钥进行测试时,我得到了Error: Supplied key is too large at DiffieHellman.dhComputeSecret
一天多以前,我的深入研究没有发现两种不同语言之间DH密钥交换的示例/演示,而是一个语言示例,其中包含讨论现有Wiki文档的注释/文章,而更少或没有代码。我认为这是带有DH键的跨语言客户端-服务器上的新问题。
Nodejs:
var crypto = require("crypto");
var assert = require("assert");
// the prime is shared by everyone
var p ="7287927445664946359687239486223244248530331441696747442753348226106279800740207968417650493105155177035805265358863967196769895080354517146585830093038907";
var g="3519494160132765249824212078020429853238178237852596056897517714427148886750491954575952859563331424777669938328249242087811536189850912851560984760609308";
let server = crypto.createDiffieHellman(Buffer.from(p,).toString("hex"),"hex",Buffer.from(g,).toString("hex"),"hex");
let prime = server.getPrime();
console.log("Generate Alice's keys...");
console.log(Buffer.from(prime).toString());
let alice = crypto.createDiffieHellman(prime);
let alicePublicKey = alice.generateKeys();
console.log("Generate Bob's keys...");
let bob = crypto.createDiffieHellman(prime);
//let bobPublicKey = bob.generateKeys();
//THIS IS PUBLIC KEY FROM JAVA IN HEX FORMAT
let bobPublicKey = Buffer.from("3081df30819706092a864886f70d0103013081890241008b26a5b60fd75471c366a0e8f67abe84d6f4c16b0dc97a602937420af3a658b34bb484df2d85281417a1bde4c0c51a7f97e8ac3a70fb34f092c2b1ebba01253b02404332edd9db0820ef954487cc1b327c638e2876b88a0cabc498811b42f7528af7fe58286a521f2190e9cc8785feaa5a8f019624bf88587a8b5b79854a11bcea1c02020180034300024012e116bc4fbd90542e03c1a5a130f923e579b65a50b8ed02e61f6369375f3a17ef270b3d05c52085ffe6e185ec7b19ea3cba7fe40d87e62254dc15f0e6db63b5","hex");
console.log("Exchange and generate the secret...");
let aliceBobSecret = alice.computeSecret(bobPublicKey);
let bobAliceSecret = bob.computeSecret(alicePublicKey);
// let davidAliceSecret = david.computeSecret(alicePublicKey, "latin1");
// let aliceDavidSecret = alice.computeSecret(davidPublicKey, "latin1");
console.log("alicePublicKey", alicePublicKey);
console.log("bobPublicKey", bobPublicKey);
assert.notEqual(alicePublicKey, bobPublicKey);
console.log("alicePublicKey and bobPublicKey NOT equal");
// console.log("aliceBobSecret", aliceBobSecret.toString("latin1"));
// console.log("bobAliceSecret", bobAliceSecret.toString("latin1"));
assert.equal(aliceBobSecret.toString("hex"), bobAliceSecret.toString("hex"));
console.log("aliceBobSecret and bobAliceSecret equal");
Java:
//THIS COMMENTED CODE IS USED TO INITIALLY GENERATE p AND g
/*AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DH");
paramGen.init(512); // number of bits
AlgorithmParameters params = paramGen.generateParameters();
DHParameterSpec dhSpec = (DHParameterSpec) params.getParameterSpec(DHParameterSpec.class);
BigInteger p512 = dhSpec.getP();
BigInteger g512 = dhSpec.getG();*/
BigInteger p512 = new BigInteger(Hex.decodeHex("008b26a5b60fd75471c366a0e8f67abe84d6f4c16b0dc97a602937420af3a658b34bb484df2d85281417a1bde4c0c51a7f97e8ac3a70fb34f092c2b1ebba01253b"));
BigInteger g512 = new BigInteger(Hex.decodeHex("4332edd9db0820ef954487cc1b327c638e2876b88a0cabc498811b42f7528af7fe58286a521f2190e9cc8785feaa5a8f019624bf88587a8b5b79854a11bcea1c"));
//A
KeyPairGenerator akpg = KeyPairGenerator.getInstance("DiffieHellman");
DHParameterSpec param = new DHParameterSpec(p512, g512);
String a = p512 + "";
String b = g512 + "";
System.out.println("Prime: " + new String(Hex.encodeHex(p512.toByteArray())));
System.out.println("PrimeH: " + p512);
System.out.println("Base: " + new String(Hex.encodeHex(g512.toByteArray())));
System.out.println("BaseH: " + g512);
akpg.initialize(param);
KeyPair kp = akpg.generateKeyPair();
//B
KeyPairGenerator bkpg = KeyPairGenerator.getInstance("DiffieHellman");
DHParameterSpec param2 = new DHParameterSpec(p512, g512);
System.out.println("Prime: " + p512);
System.out.println("Base: " + g512);
bkpg.initialize(param2);
KeyPair kp2 = bkpg.generateKeyPair();
KeyAgreement aKeyAgree = KeyAgreement.getInstance("DiffieHellman");
KeyAgreement bKeyAgree = KeyAgreement.getInstance("DiffieHellman");
aKeyAgree.init(kp.getPrivate());
bKeyAgree.init(kp2.getPrivate());
System.out.println("2Key: " +new String(Hex.encodeHex(kp.getPublic().getEncoded())));
aKeyAgree.doPhase(kp2.getPublic(), true);
bKeyAgree.doPhase(kp.getPublic(), true);
//System.out.println("Alice Secret Key: " + aKeyAgree.generateSecret());
//System.out.println("Bob's Secret Key: " + bKeyAgree.generateSecret());
MessageDigest hash = MessageDigest.getInstance("SHA-256");
/*byte[] ASharedSecret = hash.digest(aKeyAgree.generateSecret());
byte[] BSharedSecret = hash.digest(bKeyAgree.generateSecret());*/
byte[] ASharedSecret = aKeyAgree.generateSecret();
byte[] BSharedSecret = bKeyAgree.generateSecret();
System.out.println("Alice's Shared Secret: " + Arrays.toString(ASharedSecret));
System.out.println("Bob's Shared Secret: " + Arrays.toString(BSharedSecret));