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

added support for secp256r1 curve and updated tests. modified the tests to accept multiple curves #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ $ npm install key-encoder

### Getting Started

To get started, first define your key encoder and raw private/public keys.
To get started, first define your key encoder and raw private/public keys. Keyencoder supports the following curves: `secp256k1`, `secp256r1`

#### SECP256k1 Key Encoders

Expand Down
7 changes: 7 additions & 0 deletions lib/key-encoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ var curves = {
privatePEMOptions: {label: 'EC PRIVATE KEY'},
publicPEMOptions: {label: 'PUBLIC KEY'},
curve: new EC('secp256k1')
},
//prime256v1/secp256r1: parameters from RFC 5480, Section 2.1.1.1
secp256r1: {
curveParameters: [1, 2, 840, 10045, 3, 1, 7],
privatePEMOptions: {label: 'EC PRIVATE KEY'},
publicPEMOptions: {label: 'PUBLIC KEY'},
curve: new EC('p256')
}
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "key-encoder",
"version": "1.1.6",
"version": "1.1.7",
"description": "Library for encoding ECDSA private keys to PEM, DER and raw hex formats",
"main": "index.js",
"scripts": {
Expand Down
203 changes: 122 additions & 81 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,127 +4,168 @@ var test = require('tape'),
SubjectPublicKeyInfoASN = KeyEncoder.SubjectPublicKeyInfoASN,
BN = require('bn.js')

var keys = {
rawPrivate: '844055cca13efd78ce79a4c3a4c5aba5db0ebeb7ae9d56906c03d333c5668d5b',
rawPublic: '04147b79e9e1dd3324ceea115ff4037b6c877c73777131418bfb2b713effd0f502327b923861581bd5535eeae006765269f404f5f5c52214e9721b04aa7d040a75',
pemPrivate: '-----BEGIN EC PRIVATE KEY-----\n' +
'MHQCAQEEIIRAVcyhPv14znmkw6TFq6XbDr63rp1WkGwD0zPFZo1boAcGBSuBBAAK\n' +
'oUQDQgAEFHt56eHdMyTO6hFf9AN7bId8c3dxMUGL+ytxPv/Q9QIye5I4YVgb1VNe\n' +
'6uAGdlJp9AT19cUiFOlyGwSqfQQKdQ==\n' +
'-----END EC PRIVATE KEY-----',
pemCompactPrivate: '-----BEGIN EC PRIVATE KEY-----\n' +
'MC4CAQEEIIRAVcyhPv14znmkw6TFq6XbDr63rp1WkGwD0zPFZo1boAcGBSuBBAAK\n' +
'-----END EC PRIVATE KEY-----',
pemPublic: '-----BEGIN PUBLIC KEY-----\n' +
'MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFHt56eHdMyTO6hFf9AN7bId8c3dxMUGL\n' +
'+ytxPv/Q9QIye5I4YVgb1VNe6uAGdlJp9AT19cUiFOlyGwSqfQQKdQ==\n' +
'-----END PUBLIC KEY-----',
derPrivate: '30740201010420844055cca13efd78ce79a4c3a4c5aba5db0ebeb7ae9d56906c03d333c5668d5ba00706052b8104000aa14403420004147b79e9e1dd3324ceea115ff4037b6c877c73777131418bfb2b713effd0f502327b923861581bd5535eeae006765269f404f5f5c52214e9721b04aa7d040a75',
derPublic: '3056301006072a8648ce3d020106052b8104000a03420004147b79e9e1dd3324ceea115ff4037b6c877c73777131418bfb2b713effd0f502327b923861581bd5535eeae006765269f404f5f5c52214e9721b04aa7d040a75'
}

var keyEncoder = new KeyEncoder('secp256k1')
var keys = [
//secp256k1
{
rawPrivate: '844055cca13efd78ce79a4c3a4c5aba5db0ebeb7ae9d56906c03d333c5668d5b',
rawPublic: '04147b79e9e1dd3324ceea115ff4037b6c877c73777131418bfb2b713effd0f502327b923861581bd5535eeae006765269f404f5f5c52214e9721b04aa7d040a75',
pemPrivate: '-----BEGIN EC PRIVATE KEY-----\n' +
'MHQCAQEEIIRAVcyhPv14znmkw6TFq6XbDr63rp1WkGwD0zPFZo1boAcGBSuBBAAK\n' +
'oUQDQgAEFHt56eHdMyTO6hFf9AN7bId8c3dxMUGL+ytxPv/Q9QIye5I4YVgb1VNe\n' +
'6uAGdlJp9AT19cUiFOlyGwSqfQQKdQ==\n' +
'-----END EC PRIVATE KEY-----',
pemCompactPrivate: '-----BEGIN EC PRIVATE KEY-----\n' +
'MC4CAQEEIIRAVcyhPv14znmkw6TFq6XbDr63rp1WkGwD0zPFZo1boAcGBSuBBAAK\n' +
'-----END EC PRIVATE KEY-----',
pemPublic: '-----BEGIN PUBLIC KEY-----\n' +
'MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFHt56eHdMyTO6hFf9AN7bId8c3dxMUGL\n' +
'+ytxPv/Q9QIye5I4YVgb1VNe6uAGdlJp9AT19cUiFOlyGwSqfQQKdQ==\n' +
'-----END PUBLIC KEY-----',
derPrivate: '30740201010420844055cca13efd78ce79a4c3a4c5aba5db0ebeb7ae9d56906c03d333c5668d5ba00706052b8104000aa14403420004147b79e9e1dd3324ceea115ff4037b6c877c73777131418bfb2b713effd0f502327b923861581bd5535eeae006765269f404f5f5c52214e9721b04aa7d040a75',
derPublic: '3056301006072a8648ce3d020106052b8104000a03420004147b79e9e1dd3324ceea115ff4037b6c877c73777131418bfb2b713effd0f502327b923861581bd5535eeae006765269f404f5f5c52214e9721b04aa7d040a75'
},
//secp256r1
{
rawPrivate: 'ff2d3419e5d1e9421ba3ad0c398369ca7c09de3ad5c163e1ce370d0df8f2f9d8',
rawPublic: '0478b62fda69d898dfedadb897d6a8a7f0d1a9687eb8cee28b9db05a9d094ad92da36202d8499b0635b38fff3a99eaacdc7e2990807c72d8256b49f853b739872d',
pemPrivate: '-----BEGIN EC PRIVATE KEY-----\n' +
'MHcCAQEEIP8tNBnl0elCG6OtDDmDacp8Cd461cFj4c43DQ348vnYoAoGCCqGSM49\n' +
'AwEHoUQDQgAEeLYv2mnYmN/trbiX1qin8NGpaH64zuKLnbBanQlK2S2jYgLYSZsG\n' +
'NbOP/zqZ6qzcfimQgHxy2CVrSfhTtzmHLQ==\n' +
'-----END EC PRIVATE KEY-----',
pemPublic: '-----BEGIN PUBLIC KEY-----\n' +
'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeLYv2mnYmN/trbiX1qin8NGpaH64\n' +
'zuKLnbBanQlK2S2jYgLYSZsGNbOP/zqZ6qzcfimQgHxy2CVrSfhTtzmHLQ==\n' +
'-----END PUBLIC KEY-----',
derPrivate: '30770201010420ff2d3419e5d1e9421ba3ad0c398369ca7c09de3ad5c163e1ce370d0df8f2f9d8a00a06082a8648ce3d030107a1440342000478b62fda69d898dfedadb897d6a8a7f0d1a9687eb8cee28b9db05a9d094ad92da36202d8499b0635b38fff3a99eaacdc7e2990807c72d8256b49f853b739872d',
derPublic: '3059301306072a8648ce3d020106082a8648ce3d0301070342000478b62fda69d898dfedadb897d6a8a7f0d1a9687eb8cee28b9db05a9d094ad92da36202d8499b0635b38fff3a99eaacdc7e2990807c72d8256b49f853b739872d'
}
]

var curve_params = [
[1, 3, 132, 0, 10], //secp256k1
[1, 2, 840, 10045, 3, 1, 7], //secp256r1
]

var keyEncoder = [];
keyEncoder[0] = new KeyEncoder('secp256k1')
keyEncoder[1] = new KeyEncoder('secp256r1')

test('encodeECPrivateKeyASN', function(t) {
t.plan(3)
t.plan(3*keys.length)

var secp256k1Parameters = [1, 3, 132, 0, 10],
pemOptions = {label: 'EC PRIVATE KEY'}
var pemOptions = {label: 'EC PRIVATE KEY'}

var privateKeyObject = {
version: new BN(1),
privateKey: new Buffer(keys.rawPrivate, 'hex'),
parameters: secp256k1Parameters,
publicKey: { unused: 0, data: new Buffer(keys.rawPublic, 'hex') }
}
for (let i=0; i < keys.length; i++) {
var privateKeyObject = {
version: new BN(1),
privateKey: new Buffer(keys[i].rawPrivate, 'hex'),
parameters: curve_params[i],
publicKey: { unused: 0, data: new Buffer(keys[i].rawPublic, 'hex') }
}

var privateKeyPEM = ECPrivateKeyASN.encode(privateKeyObject, 'pem', pemOptions)
t.equal(privateKeyPEM, keys.pemPrivate, 'encoded PEM private key should match the OpenSSL reference')
var privateKeyPEM = ECPrivateKeyASN.encode(privateKeyObject, 'pem', pemOptions)
t.equal(privateKeyPEM, keys[i].pemPrivate, 'encoded PEM private key should match the OpenSSL reference')

var decodedPrivateKeyObject = ECPrivateKeyASN.decode(privateKeyPEM, 'pem', pemOptions)
t.equal(JSON.stringify(privateKeyObject), JSON.stringify(decodedPrivateKeyObject), 'encoded-and-decoded private key object should match the original')
var decodedPrivateKeyObject = ECPrivateKeyASN.decode(privateKeyPEM, 'pem', pemOptions)
t.equal(JSON.stringify(privateKeyObject), JSON.stringify(decodedPrivateKeyObject), 'encoded-and-decoded private key object should match the original')

var openSSLPrivateKeyObject = ECPrivateKeyASN.decode(keys.pemPrivate, 'pem', pemOptions)
t.equal(JSON.stringify(privateKeyObject), JSON.stringify(openSSLPrivateKeyObject), 'private key object should match the one decoded from the OpenSSL PEM')
var openSSLPrivateKeyObject = ECPrivateKeyASN.decode(keys[i].pemPrivate, 'pem', pemOptions)
t.equal(JSON.stringify(privateKeyObject), JSON.stringify(openSSLPrivateKeyObject), 'private key object should match the one decoded from the OpenSSL PEM')
}
})

test('encodeSubjectPublicKeyInfoASN', function(t) {
t.plan(1)

var secp256k1Parameters = [1, 3, 132, 0, 10],
pemOptions = {label: 'PUBLIC KEY'}

var publicKeyObject = {
algorithm: {
id: [1, 2, 840, 10045, 2, 1],
curve: secp256k1Parameters
},
pub: {
unused: 0,
data: new Buffer(keys.rawPublic, 'hex')
t.plan(2)

var pemOptions = {label: 'PUBLIC KEY'}

for (let i=0; i < keys.length; i++) {
var publicKeyObject = {
algorithm: {
id: [1, 2, 840, 10045, 2, 1],
curve: curve_params[i]
},
pub: {
unused: 0,
data: new Buffer(keys[i].rawPublic, 'hex')
}
}
}

var publicKeyPEM = SubjectPublicKeyInfoASN.encode(publicKeyObject, 'pem', pemOptions)
t.equal(publicKeyPEM, keys.pemPublic, 'encoded PEM public key should match the OpenSSL reference')
var publicKeyPEM = SubjectPublicKeyInfoASN.encode(publicKeyObject, 'pem', pemOptions)
t.equal(publicKeyPEM, keys[i].pemPublic, 'encoded PEM public key should match the OpenSSL reference')
}
})

test('encodeRawPrivateKey', function(t) {
t.plan(2)
t.plan(4)

var privateKeyPEM = keyEncoder.encodePrivate(keys.rawPrivate, 'raw', 'pem')
t.equal(privateKeyPEM, keys.pemPrivate, 'encoded PEM private key should match the OpenSSL reference')
for (let i=0; i < keys.length; i++) {
var privateKeyPEM = keyEncoder[i].encodePrivate(keys[i].rawPrivate, 'raw', 'pem')
t.equal(privateKeyPEM, keys[i].pemPrivate, 'encoded PEM private key should match the OpenSSL reference')

var privateKeyDER = keyEncoder.encodePrivate(keys.rawPrivate, 'raw', 'der')
t.equal(privateKeyDER, keys.derPrivate, 'encoded DER private key should match the OpenSSL reference')
var privateKeyDER = keyEncoder[i].encodePrivate(keys[i].rawPrivate, 'raw', 'der')
console.log(privateKeyDER)
t.equal(privateKeyDER, keys[i].derPrivate, 'encoded DER private key should match the OpenSSL reference')
}
})

test('encodeDERPrivateKey', function(t) {
t.plan(2)
t.plan(4)

var rawPrivateKey = keyEncoder.encodePrivate(keys.derPrivate, 'der', 'raw')
t.equal(rawPrivateKey, keys.rawPrivate, 'encoded raw private key should match the OpenSSL reference')
for (let i=0; i < keys.length; i++) {
var rawPrivateKey = keyEncoder[i].encodePrivate(keys[i].derPrivate, 'der', 'raw')
t.equal(rawPrivateKey, keys[i].rawPrivate, 'encoded raw private key should match the OpenSSL reference')

var privateKeyPEM = keyEncoder.encodePrivate(keys.derPrivate, 'der', 'pem')
t.equal(privateKeyPEM, keys.pemPrivate, 'encoded PEM private key should match the OpenSSL reference')
var privateKeyPEM = keyEncoder[i].encodePrivate(keys[i].derPrivate, 'der', 'pem')
t.equal(privateKeyPEM, keys[i].pemPrivate, 'encoded PEM private key should match the OpenSSL reference')
}
})

test('encodePEMPrivateKey', function(t) {
t.plan(2)
t.plan(4)

var rawPrivateKey = keyEncoder.encodePrivate(keys.pemPrivate, 'pem', 'raw')
t.equal(rawPrivateKey, keys.rawPrivate, 'encoded raw private key should match the OpenSSL reference')
for (let i=0; i < keys.length; i++) {
var rawPrivateKey = keyEncoder[i].encodePrivate(keys[i].pemPrivate, 'pem', 'raw')
t.equal(rawPrivateKey, keys[i].rawPrivate, 'encoded raw private key should match the OpenSSL reference')

var privateKeyDER = keyEncoder.encodePrivate(keys.pemPrivate, 'pem', 'der')
t.equal(privateKeyDER, keys.derPrivate, 'encoded DER private key should match the OpenSSL reference')
var privateKeyDER = keyEncoder[i].encodePrivate(keys[i].pemPrivate, 'pem', 'der')
t.equal(privateKeyDER, keys[i].derPrivate, 'encoded DER private key should match the OpenSSL reference')
}
})

test('encodeRawPublicKey', function(t) {
t.plan(2)
t.plan(4)

var publicKeyPEM = keyEncoder.encodePublic(keys.rawPublic, 'raw', 'pem')
t.equal(publicKeyPEM, keys.pemPublic, 'encoded PEM public key should match the OpenSSL reference')
for (let i=0; i < keys.length; i++) {
var publicKeyPEM = keyEncoder[i].encodePublic(keys[i].rawPublic, 'raw', 'pem')
t.equal(publicKeyPEM, keys[i].pemPublic, 'encoded PEM public key should match the OpenSSL reference')

var publicKeyDER = keyEncoder.encodePublic(keys.rawPublic, 'raw', 'der')
t.equal(publicKeyDER, keys.derPublic, 'encoded DER public key should match the OpenSSL reference')
var publicKeyDER = keyEncoder[i].encodePublic(keys[i].rawPublic, 'raw', 'der')
t.equal(publicKeyDER, keys[i].derPublic, 'encoded DER public key should match the OpenSSL reference')
}
})

test('encodeDERPublicKey', function(t) {
t.plan(2)
t.plan(4)

var rawPublicKey = keyEncoder.encodePublic(keys.derPublic, 'der', 'raw')
t.equal(rawPublicKey, keys.rawPublic, 'encoded raw public key should match the OpenSSL reference')
for (let i=0; i < keys.length; i++) {
var rawPublicKey = keyEncoder[i].encodePublic(keys[i].derPublic, 'der', 'raw')
t.equal(rawPublicKey, keys[i].rawPublic, 'encoded raw public key should match the OpenSSL reference')

var publicKeyPEM = keyEncoder.encodePublic(keys.derPublic, 'der', 'pem')
t.equal(publicKeyPEM, keys.pemPublic, 'encoded PEM public key should match the OpenSSL reference')
var publicKeyPEM = keyEncoder[i].encodePublic(keys[i].derPublic, 'der', 'pem')
t.equal(publicKeyPEM, keys[i].pemPublic, 'encoded PEM public key should match the OpenSSL reference')
}
})

test('encodePEMPublicKey', function(t) {
t.plan(2)
t.plan(4)

var rawPublicKey = keyEncoder.encodePublic(keys.pemPublic, 'pem', 'raw')
t.equal(rawPublicKey, keys.rawPublic, 'encoded raw public key should match the OpenSSL reference')
for (let i=0; i < keys.length; i++) {
var rawPublicKey = keyEncoder[i].encodePublic(keys[i].pemPublic, 'pem', 'raw')
t.equal(rawPublicKey, keys[i].rawPublic, 'encoded raw public key should match the OpenSSL reference')

var publicKeyDER = keyEncoder.encodePublic(keys.pemPublic, 'pem', 'der')
t.equal(publicKeyDER, keys.derPublic, 'encoded DER public key should match the OpenSSL reference')
var publicKeyDER = keyEncoder[i].encodePublic(keys[i].pemPublic, 'pem', 'der')
t.equal(publicKeyDER, keys[i].derPublic, 'encoded DER public key should match the OpenSSL reference')
}
})