Giter Site home page Giter Site logo

diffie-hellman's Introduction

diffie hellman Build Status

pure js diffie-hellman, same api as node, most hard parts thanks to bn.js by @indutny. In node just returns an object with crypto.createDiffieHellman and crypto.getDiffieHellman in the browser returns a shim. To require the pure JavaScript one in node require('diffie-hellman/browser');;

diffie-hellman's People

Contributors

abhin4v avatar calvinmetcalf avatar dcousens avatar guybedford avatar kapouer avatar kylef avatar vihangm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

diffie-hellman's Issues

nodejs crypto module DH secret hash is not the same with diffie-hellman/browser

I do a test about crypto module with diffie-hellman/browser

  • When I use the followed , DH secret hex is not the same,
var dh1_secret = dh1.computeSecret(dh2.getPublicKey('hex'), 'hex');
var dh2_secret = dh2.computeSecret(dh1.getPublicKey('hex'), 'hex');

console.log(dh1_secret.toString('hex') === dh2_secret.toString('hex'));   // false
  • when I use the followed, DH secret is the same,
var dh1_secret = dh1.computeSecret(dh2.getPublicKey());
var dh2_secret = dh2.computeSecret(dh1.getPublicKey());    // true

The followed is the completed code.

var myCrypto = require('./browser');
var crypto = require('./');

p1 = "modp18"
var dh1 = myCrypto.getDiffieHellman(p1);
let dh1_secret_key = dh1.generateKeys();

let dh1_pk = dh1.getPublicKey('hex');

let dh2 = myCrypto.getDiffieHellman(p1);
let dh2_secret_key = dh2.generateKeys();

var dh1_secret = dh1.computeSecret(dh2.getPublicKey('hex'), 'hex');
var dh2_secret = dh2.computeSecret(dh1.getPublicKey('hex'), 'hex');

console.log(dh1_secret.toString('hex') === dh2_secret.toString('hex'));

Tests fail for Node.js >= 12

Sharing the logs:

    ✗ same error for bad prime
     ---
       operator: equal
       expected: 1
       actual:   9
       at: Test.<anonymous> (/home/nilesh/ups/diffie-hellman/test.js:127:5)
     ...
    ✗ same error for bad prime non testable generator
     ---
       operator: equal
       expected: 1
       actual:   5
       at: Test.<anonymous> (/home/nilesh/ups/diffie-hellman/test.js:130:5)
     ...
    ✓ same error for good prime wrong generator
    ✗ same error for good prime non testable generator
     ---
       operator: equal
       expected: 0
       actual:   4
       at: Test.<anonymous> (/home/nilesh/ups/diffie-hellman/test.js:136:5)
     ...
   
  tests 233
  pass  230
  fail  3
   
  Failed Tests: There were 3 failures

    ✗ check errors same error for bad prime
    ✗ check errors same error for bad prime non testable generator
    ✗ check errors same error for good prime non testable generator

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] test: `node test.js | tspec`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/nilesh/.npm/_logs/2020-01-31T15_53_55_954Z-debug.log

setPublicKey function error

Hi,
I ran to this error:
TypeError: DH.setPublicKey is not a function

I think dh.setPublicKey function is missing. Without it one cannot use pre-existing public/private keys.

Clean up `createDiffieHellman`

The constructor is a bit of a mess in terms of how it defaults certain arguments, maintaining a difficult-to-track cyclomatic complexity.

It would be nice to reduce it down if possible.

Compute secret should have blinds

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=860771#10From

Is this timing safe? From the github page it uses a pure-JS
BigNum implementation (bn.js) for the complicated stuff, but
the README of that code doesn't mention timing at all. And
from perusing the source code of bn.js, it doesn't appear to
be the case that their implementation of exponentiation in
a prime field is geared towards constant-time execution (when
the sizes are the same).

If you look at e.g. OpenSSL's source code (bn_exp.c), there's
a specific function (bn_mod_exp_mont_consttime) in there that
takes great care of making sure that the operation runs in
constant time - down to how the memory layout is organized. I
wouldn't know how you'd even do that in an interpreted
language such as JavaScript, but even if that's possible, I'd
suspect that a lot of brain power would need to go into
designing that [1], while bn.js's implementation of the
Red.pow function seems rather straight-forward. (Which is
fine, bn.js appears to have the goal to be a generic bignum
library, and not targeted at crypto.)

What I'm saying is: while not having tested that, I believe
that this implementation of DH is going to be susceptible to
timing attacks. (And if it isn't, the author should really
provide some rationale why not, with some test results. The
README is rather sparse, though.) Which would be fine if you
just wanted to use this library to generate the DH prime
itself (that is not timing critical), or just use it in an
academic context (to let people play around with DH), but
I'd not want to use this for real-world applications of the
actual key exchange protocol.

Regards,
Christian

[1] Especially if this is to be run in browsers, with
different JITs etc. Designing algorithms in pure JS
for these environments that are timing-safe looks rather
daunting to me.

Method checkPrime() is too slow

Hi.

I use ssh2 library https://github.com/mscdex/ssh2 in a browser. I have faced up with next problem.

Method checkPrime() at this code

defineError(this, checkPrime(this.__prime, generator));

works very very slowly, so I can't connect to my server. I try to connect by key with a passphrase, 'ctr' ciphers is used.
As I discovered method Red.prototype.pow make such delays.

Thanks a lot.

Unable to calculate correct shared secret

Hi. I'm trying to use this library while reverse engineering a commercial product. DH is used for the authentication procedure. To verify its correctness, I'm using known values for prime, generator, client's private key, client's public key, server's public key, and the shared secret, all of which are either fixed or logged by the product. Unfortunately I just can't manage to calculate the same shared secret.

Here's the relevant code:

import Ember from 'ember';
import CryptoJS from 'cryptojs';
import BU from 'npm:buffer';
import DH from 'npm:diffie-hellman';

export default Ember.Component.extend({

  // prime used by product
  prime1024: 'F488FD584E49DBCD20B49DE49107366B336C380D451D0F7C88B31C7C5B2D8EF6F3C923C043F0A55B188D8EBB558CB85D38D334FD7C175743A31D186CDE33212CB52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92F78C7',

  didInsertElement() {
    // this.connect();
    this.testEncryption();
  },


  testEncryption() {
    let dh = DH.createDiffieHellman(this.prime1024, 'hex', '02', 'hex');
    dh.setPrivateKey(new BU.Buffer('650620144A0F0A22C999AA0D71A4EEB65294021A', 'hex')); 
    dh.setPublicKey(new BU.Buffer('ikU8ISwVZuLx2TMdDTZKKD+M4USmwQBvygjjULJDKzp+GLZoSO1umMFlz+9BJl+SB4snQfj7IqjtFKGb0M9eLKtEoR0fMnO1P6sOPcYCqA14FXA+wLKAs6VV6Xev1gxLm4QgFBxZ7z6p1dLRM0sTEAt2FKJ40KZxTlEk9hRbfH0A', 'base64')); // probably irrelevant
    console.log('client private key', dh.getPrivateKey('base64'));

    // what server sends
    var serverPublicKey = 'qM/0YWK5nsVSHmg7HQgKA5qlzWdUqE/OTlth3r2IMwEIcoSADlp8sggkYU9ggg3Oy4QGKWPfxI2ABgcV0dXnDUVx8zQ9wQJCLKEKHtEVG2LeJUkjMVfn4JGvzlcMF1sTsPSsCrVuLJfdpNR5MhUvLwY+xivMBylpvJbuM8XEtHg=';
    var decServerPublicKey = new BU.Buffer(serverPublicKey, 'base64').reverse(); // LE -> BE
    var serverPublicKeyShould = [168, 207, 244, 97, 98, 185, 158, 197, 82, 30, 104, 59, 29, 8, 10, 3, 154, 165, 205, 103, 84, 168, 79, 206, 78, 91, 97, 222, 189, 136, 51, 1, 8, 114, 132, 128, 14, 90, 124, 178, 8, 36, 97, 79, 96, 130, 13, 206, 203, 132, 6, 41, 99, 223, 196, 141, 128, 6, 7, 21, 209, 213, 231, 13, 69, 113, 243, 52, 61, 193, 2, 66, 44, 161, 10, 30, 209, 21, 27, 98, 222, 37, 73, 35, 49, 87, 231, 224, 145, 175, 206, 87, 12, 23, 91, 19, 176, 244, 172, 10, 181, 110, 44, 151, 221, 164, 212, 121, 50, 21, 47, 47, 6, 62, 198, 43, 204, 7, 41, 105, 188, 150, 238, 51, 197, 196, 180, 120];
    console.log("decoded server public key (is)", decServerPublicKey);
    console.log("server public key     (should)", serverPublicKeyShould);

    var ss = dh.computeSecret(decServerPublicKey);
    console.log('shared secret     (is)', ss);
    console.log('shared secret rev (is)', ss.reverse());
    var ssShould = [159, 188, 246, 56, 207, 51, 58, 201, 186, 137, 134, 198, 130, 81, 40, 235, 108, 166, 40, 208, 19, 13, 249, 77, 0, 137, 114, 15, 154, 131, 240, 105, 193, 236, 41, 220, 51, 210, 161, 255, 188, 201, 123, 106, 95, 74, 93, 217, 193, 161, 146, 8, 49, 102, 185, 172, 174, 91, 183, 78, 142, 122, 196, 235, 106, 81, 253, 239, 252, 63, 0, 11, 158, 182, 141, 189, 66, 49, 91, 17, 40, 53, 165, 192, 194, 78, 130, 75, 169, 212, 46, 41, 171, 232, 98, 198, 7, 139, 225, 49, 70, 243, 179, 79, 24, 1, 52, 23, 125, 204, 160, 255, 129, 142, 170, 130, 26, 59, 127, 99, 107, 84, 175, 91, 167, 132, 72, 216]
;
    console.log('shared secret (should)', ssShould);
  },
});

To prove that these values are correct, I've done the same in Ruby, where it works:

#!/usr/bin/env ruby
require 'openssl'
require 'base64'

# 1024-bit prime number used by server
PRIME1024 = 'F488FD584E49DBCD20B49DE49107366B336C380D451D0F7C88B31C7C5B2D8EF6F3C923C043F0A55B188D8EBB558CB85D38D334FD7C175743A31D186CDE33212CB52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FABD00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92F78C7'

# example public key sent by server
# (has to be Base64 decoded and converted from LE to BE)
SERVER_PK_BIN = Base64.decode64 'qM/0YWK5nsVSHmg7HQgKA5qlzWdUqE/OTlth3r2IMwEIcoSADlp8sggkYU9ggg3Oy4QGKWPfxI2ABgcV0dXnDUVx8zQ9wQJCLKEKHtEVG2LeJUkjMVfn4JGvzlcMF1sTsPSsCrVuLJfdpNR5MhUvLwY+xivMBylpvJbuM8XEtHg='
SERVER_PK_HEX = SERVER_PK_BIN.bytes.reverse.map { |byte| '%02X' % byte }.join
puts "server public key (bytes): #{SERVER_PK_BIN.bytes.inspect}"
puts "server public key (hex): #{SERVER_PK_HEX}"

CLIENT_PK_BIN = Base64.decode64 'ikU8ISwVZuLx2TMdDTZKKD+M4USmwQBvygjjULJDKzp+GLZoSO1umMFlz+9BJl+SB4snQfj7IqjtFKGb0M9eLKtEoR0fMnO1P6sOPcYCqA14FXA+wLKAs6VV6Xev1gxLm4QgFBxZ7z6p1dLRM0sTEAt2FKJ40KZxTlEk9hRbfH0A'
CLIENT_PK_HEX = CLIENT_PK_BIN.bytes.map { |byte| '%02X' % byte }.join
puts "client public key (bytes): #{CLIENT_PK_BIN.bytes.inspect}"
puts "client public key (hex): #{CLIENT_PK_HEX}"

CLIENT_SK_HEX = '650620144A0F0A22C999AA0D71A4EEB65294021A'


p = OpenSSL::BN.new(PRIME1024, 16)
g = OpenSSL::BN.new(2)

dh = OpenSSL::PKey::DH.new
dh.set_pqg(p, nil, g)
#dh.generate_key! # would generate a new pair of keys
#
# set private and public key to hard-coded values from log
sk = OpenSSL::BN.new(CLIENT_SK_HEX, 16) # client's secret key
pk = OpenSSL::BN.new(CLIENT_PK_HEX, 16) # client's pubkey
dh.set_key pk, sk

puts "PK set: #{dh.pub_key.to_i}"
puts

# compute shared secrets
pk = OpenSSL::BN.new(SERVER_PK_HEX, 16) # server's pubkey
ss = dh.compute_key(pk).reverse # reverse to get the same order as in log
puts "Shared secret is #{ss.bytesize} bytes."

#puts ss.inspect
puts ss.bytes.inspect
puts "should: [159, 188, 246, 56, ... ]"

Any ideas?

[Bundler] BN.red is undefined

For some reason,computeSecret is throwing error saying cannot read 'red' of undefined. This seems to indicate that BN was not bundled properly.

Environment: browser.

Front-end was created using create-react-app

standalone js file?

I tried running "browserify index.js" to get the actual lib but I doesn't seem to work. It would be awesome if you could show and example of it working to get an idea on how to use it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.