Diffie Hellman Обмен ключами между Java-клиентом и сервером nodejs - PullRequest
0 голосов
/ 26 декабря 2018

У меня есть узел 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));
...