Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ECDSA nistp256 from HEX #90

Closed
Pierozi opened this issue May 20, 2019 · 3 comments
Closed

ECDSA nistp256 from HEX #90

Pierozi opened this issue May 20, 2019 · 3 comments

Comments

@Pierozi
Copy link

Pierozi commented May 20, 2019

I'm struggle to encode using a private key in hexadecimal format.
I need to convert library from another language.

The key in hex are like this one a3ed0dd27cbfa62e13e340fb3dbb86895b99d5fd330a80e799baffcb1d29c17a

I've tried to decode, or even encapsulate with other libraries like signatory but I can't make it work.

@Keats
Copy link
Owner

Keats commented May 21, 2019

Do you have an example in another language?
What happens if you convert the hex string into a byte slice and use that as the key?

@Pierozi
Copy link
Author

Pierozi commented May 21, 2019

The implementation are based on this library https://github.com/kjur/jsrsasign
There is demo about key generation :https://kjur.github.io/jsrsasign/sample/sample-ecdsa.html

// create ECDSA key object with Hex input
const prvKey = new rs.KJUR.crypto.ECDSA({ curve: 'secp256r1' });
prvKey.setPrivateKeyHex('7609edbe72f75b17926742a0f1ab01ed418736c5f8b4f6783bc1634c38bc9f40');
prvKey.isPrivate = true;
prvKey.isPublic = false;

As far my understanding grabbed during the research (see annexes on the bottom), the HEX string that I have is not the full PEM.
But a seed which is deterministic. And we have to generate on the fly the Private key.

Here is the test with hex::decode

let private_key = hex::decode("a3ed0dd27cbfa62e13e340fb3dbb86895b99d5fd330a80e799baffcb1d29c17a").unwrap();
let payload = Claims {
    sub: "foo".to_owned(),
    company: "bar".to_owned()
};
let mut header = jwt::Header::default();
header.alg = jwt::Algorithm::ES256;

let jwt_token = match jwt::encode(&header,&payload, &private_key) {
    Ok(token) => token,
    Err(error) => {
        panic!("There was a problem during JWT ENCODE: {:?}", error);
    },
};

/*---- encode stdout ----
thread 'encode' panicked at 'There was a problem during JWT ENCODE: Error(InvalidEcdsaKey)', src/lib.rs:92:17
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.*/

I try different combiniaison with ring and signatory but I feel like what I need are missing.
I tough having faith using openssl but the key PEM resulting seems not correct and still not accepted by your library.

Test with OpenSsl

let group = openssl::ec::EcGroup::from_curve_name(openssl::nid::Nid::X9_62_PRIME256V1).unwrap();
let point = openssl::ec::EcPoint::new(&group).unwrap();
let private_number = openssl::bn::BigNum::from_hex_str("a3ed0dd27cbfa62e13e340fb3dbb86895b99d5fd330a80e799baffcb1d29c17a").unwrap();
let eckey = openssl::ec::EcKey::from_private_components(
    &group,
    &private_number,
    &point
).unwrap();
let private_key = eckey.private_key_to_pem().unwrap();

println!("{}", String::from_utf8(private_key.to_owned()).unwrap());

// same code jwt::encode as before

/*failures:

---- encode stdout ----
-----BEGIN EC PRIVATE KEY-----
MDcCAQEEIKPtDdJ8v6YuE+NA+z27holbmdX9MwqA55m6/8sdKcF6oAoGCCqGSM49
AwEHoQQDAgAA
-----END EC PRIVATE KEY-----

thread 'encode' panicked at 'There was a problem during JWT ENCODE: Error(InvalidEcdsaKey)', src/lib.rs:91:17
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.*/

Annexes:

def make_key(seed):
  secexp = randrange_from_seed__trytryagain(seed, NIST384p.order)
  return SigningKey.from_secret_exponent(secexp, curve=NIST384p)

@Keats Keats mentioned this issue May 25, 2019
@Pierozi
Copy link
Author

Pierozi commented Jun 3, 2019

Solve it with openssl, public key was missing.
Seems not possible with ring.

let private_key_hex = "a3ed0dd27cbfa62e13e340fb3dbb86895b99d5fd330a80e799baffcb1d29c17a";
let private_number: BigNum = match BigNum::from_hex_str(private_key_hex) {
    Ok(bn) => bn,
    Err(error) => panic!("Error during parsing private key in hex, please check your configuration: {:?}", error),
};

let group: EcGroup = EcGroup::from_curve_name(openssl::nid::Nid::X9_62_PRIME256V1).unwrap();
let mut context: BigNumContext = BigNumContext::new().unwrap();

let mut public_point = EcPoint::new(&group).unwrap();
match public_point.mul_generator(
    &group,
    &private_number,
    &mut context
) {
    Ok(_) => (),
    Err(error) => panic!("Error during public key generation from private key. key must be ECDSA nist256 format: {:?}", error),
}

let eckey: EcKey<Private> = match EcKey::from_private_components(
    &group,
    &private_number,
    &public_point
) {
    Ok(key) => key,
    Err(error) => panic!("Error pub/pvt key construction: {:?}", error),
};

return match eckey.private_key_to_pem() {
    Ok(pem) => pem,
    Err(error) => panic!("Error during PEM conversion: {:?}", error),
};

@Pierozi Pierozi closed this as completed Jun 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants