У меня есть узел js-сервер для моего приложения для Android, и я хочу, чтобы связь была защищена с помощью обмена ключами DH.Я могу сгенерировать Prime p
и Base g
в java с помощью nodejs (можно исправить, если не прав)
Проблема:
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 между двумя разными языками но на одном языке - примеры с несколькими комментариями / статьями, обсуждающими существующие вики-документы, и меньше или нет кода.Я думаю, что это новый вопрос о мультиязычном клиент-сервере с ключами DH.
Узлы:
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));