-->

Can't bridge Elliptic Curve Diffie-Hellman wit

2019-02-16 00:25发布

问题:

I know this is a very specific question but I tried to exchange keys between php and a client using the Elliptic Curve Diffie-Hellman algorithm (ECDH) based on 2 libraries that seem sound:

  1. https://github.com/mdanter/phpecc for the php part and

  2. http://www-cs-students.stanford.edu/~tjw/jsbn/ecdh.html for the js part.

It seems that the parameters (as can be seen at the second demo) just aren't right for the Mattias Danter library in (1)!

What I tried:

a. produce Alice public key in php

b. take x- and y-values from (a) and put in js demo page at stanford in place of Alice fields

c. produce from page (b) Bob's public point and private key

d. re-run php in (a) but now reset Alice's properties to previous run (I had to add some setters in Mattias Danter classes) and then used Bob's public values and secret key to reset Bob to javascript's values

e. import keys and compare

but php catches an error:

Fatal error: Uncaught exception 'ErrorException' with message 'Curve CurveFp Object 
( [a:protected] => -3 [b:protected] => 
2455155546008943817740293915197451784769108058161191238065 [prime:protected] => 
6277101735386680763835789423207666416083908700390324961279 ) does not contain point 
( 1328803036204499271979785126753219480492435117174 , 
-228023147101697490181439300085858154675358736333 )' in 
/var/www/users/test/php/tests/ext/phpecc-master/classes/Point.php:53 

searching my code I found what caused the error: it was during the calculation of the common key by Alice:

public function calculateKey() {
  $this->agreed_key = Point::mul($this->secret, $this->receivedPubPoint)->getX();
}

Bob's public key (from javascript) was stored in EcDH::receivedPubPoint and generates error!!

Here is object Alice with some identation (EcDH class):

Alice:
EcDH Object
(
  [generator:EcDH:private] => Point Object
  (
    [curve] => CurveFp Object
    (
      [a:protected] => -3
      [b:protected] => 2455155546008943817740293915197451784769108058161191238065
      [prime:protected] => 6277101735386680763835789423207666416083908700390324961279
    )

    [x] => 602046282375688656758213480587526111916698976636884684818
    [y] => 174050332293622031404857552280219410364023488927386650641
    [order] => 6277101735386680763835789423176059013767194773182842284081
  )

  [pubPoint:EcDH:private] => Point Object
  (
    [curve] => CurveFp Object
    (
      [a:protected] => -3
      [b:protected] => 2455155546008943817740293915197451784769108058161191238065
      [prime:protected] => 6277101735386680763835789423207666416083908700390324961279
    )

    [x] => 1230571492519579244570075682716266141492045436832711426918
    [y] => 925696034592317781055362853857916815608433923236519324844
    [order] =>
  )

  [receivedPubPoint:EcDH:private] =>
  [secret:EcDH:private] => 14506874945990177925841757912817895350330843517362
  [agreed_key:EcDH:private] =>
)

My opinion is that the javascript public values are not correct due to the way fields under "Elliptic Curve parameters" are implemented in http://www-cs-students.stanford.edu/~tjw/jsbn/ecdh.html.

By searching more I found that this js blocks of Stanford's code are problematic compared with the php version:

// ECCurveFp
// constructor
function ECCurveFp(q,a,b) {
    this.q = q;
    this.a = this.fromBigInteger(a);
    this.b = this.fromBigInteger(b);
    this.infinity = new ECPointFp(this, null, null);
}

// ----------------
// SECNamedCurves
function secp192k1() {
    // p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1
    var p = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37");
    var a = BigInteger.ZERO;
    var b = fromHex("3");
    //byte[] S = null;
    var n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
    var h = BigInteger.ONE;
    var curve = new ECCurveFp(p, a, b);
    var G = curve.decodePointHex("04"
                + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
                + "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D");
    return new X9ECParameters(curve, G, n, h);
}

Are there any suggestions?

Thanks.

回答1:

You should make sure that JS and PHP libraries use the same curve. Do they?