forked from coolaj86/eckles.js
v1.0.0: full PEM-to-JWK support
This commit is contained in:
parent
ea13bda056
commit
130a98677c
44
README.md
44
README.md
|
@ -1,19 +1,19 @@
|
|||
eckles.js
|
||||
=========
|
||||
|
||||
ECDSA tools. Lightweight. Zero Dependencies. Universal compatibility.
|
||||
ECDSA (elliptic curve) tools. Lightweight. Zero Dependencies. Universal compatibility.
|
||||
|
||||
* [x] PEM-to-JWK
|
||||
* [ ] JWK-to-PEM (partial)
|
||||
* [x] JWK-to-PEM
|
||||
|
||||
### PEM-to-JWK
|
||||
## PEM-to-JWK
|
||||
|
||||
* [x] SEC1/X9.62, PKCS#8, SPKI/PKIX
|
||||
* [x] P-256 (prime256v1, secp256r1), P-384 (secp384r1)
|
||||
|
||||
```js
|
||||
var eckles = require('eckles');
|
||||
var pem = require('fs').readFileSync('./fixtures/privkey-ec-p256.sec1.pem', 'ascii')
|
||||
var pem = require('fs').readFileSync('eckles/fixtures/privkey-ec-p256.sec1.pem', 'ascii');
|
||||
|
||||
eckles.import({ pem: pem }).then(function (jwk) {
|
||||
console.log(jwk);
|
||||
|
@ -30,15 +30,17 @@ eckles.import({ pem: pem }).then(function (jwk) {
|
|||
}
|
||||
```
|
||||
|
||||
### JWK-to-PEM
|
||||
## JWK-to-PEM
|
||||
|
||||
* [x] SEC1/X9.62
|
||||
* [x] SEC1/X9.62, PKCS#8, SPKI/PKIX
|
||||
* [x] P-256 (prime256v1, secp256r1), P-384 (secp384r1)
|
||||
|
||||
|
||||
```js
|
||||
var eckles = require('eckles');
|
||||
var jwk = require('eckles/fixtures/privkey-ec-p256.jwk.json');
|
||||
|
||||
eckles.export({ jwk: jwk }).then(function (pem) {
|
||||
// PEM in sec1 (x9.62) format
|
||||
// PEM in SEC1 (x9.62) format
|
||||
console.log(pem);
|
||||
});
|
||||
```
|
||||
|
@ -51,14 +53,32 @@ yZe7CnFsqeDcpnPbubP6cpYiVcnevNIYyg==
|
|||
-----END EC PRIVATE KEY-----
|
||||
```
|
||||
|
||||
<!--
|
||||
#### Advanced
|
||||
|
||||
`format: 'pkcs8'`:
|
||||
|
||||
The default output format is `sec1`/`x9.62` (EC-specific format) is used for private keys.
|
||||
Use `format: 'pkcs8'` to output in PKCS#8 format instead.
|
||||
|
||||
```js
|
||||
eckles.exportSEC1(jwk).then(function (pem) {
|
||||
// PEM in sec1 (x9.62) format
|
||||
eckles.export({ jwk: jwk, format: 'pkcs8' }).then(function (pem) {
|
||||
// PEM in PKCS#8 format
|
||||
console.log(pem);
|
||||
});
|
||||
```
|
||||
|
||||
`public: 'true'`:
|
||||
|
||||
If a private key is used as input, a private key will be output.
|
||||
|
||||
If you'd like to output a public key instead you can pass `public: true` or `format: 'spki'`.
|
||||
|
||||
```js
|
||||
eckles.export({ jwk: jwk, public: true }).then(function (pem) {
|
||||
// PEM in SPKI/PKIX format
|
||||
console.log(pem);
|
||||
});
|
||||
```
|
||||
-->
|
||||
|
||||
Goals
|
||||
-----
|
||||
|
|
|
@ -14,7 +14,7 @@ var OBJ_ID_EC_384 = '06 05 2B81040022'.replace(/\s+/g, '').toLowerCase();
|
|||
|
||||
// 1.2.840.10045.2.1
|
||||
// ecPublicKey (ANSI X9.62 public key type)
|
||||
//var OBJ_ID_EC_PUB = '06 07 2A8648CE3D0201'.replace(/\s+/g, '').toLowerCase();
|
||||
var OBJ_ID_EC_PUB = '06 07 2A8648CE3D0201'.replace(/\s+/g, '').toLowerCase();
|
||||
|
||||
|
||||
// The one good thing that came from the b***kchain hysteria: good EC documentation
|
||||
|
@ -325,9 +325,9 @@ EC.pack = function (opts) {
|
|||
if ('sec1' === format) {
|
||||
return PEM.packBlock({ type: "EC PRIVATE KEY", bytes: EC.packSec1(jwk) });
|
||||
} else if ('pkcs8' === format) {
|
||||
throw new Error("pkcs8 output not implemented");
|
||||
return PEM.packBlock({ type: "EC PRIVATE KEY", bytes: EC.packPkcs8(jwk) });
|
||||
} else {
|
||||
throw new Error("spki not implemented");
|
||||
return PEM.packBlock({ type: "PUBLIC KEY", bytes: EC.packSpki(jwk) });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -350,10 +350,32 @@ EC.packPkcs8 = function (jwk) {
|
|||
var x = toHex(base64ToUint8(urlBase64ToBase64(jwk.x)));
|
||||
var y = toHex(base64ToUint8(urlBase64ToBase64(jwk.y)));
|
||||
var objId = ('P-256' === jwk.crv) ? OBJ_ID_EC : OBJ_ID_EC_384;
|
||||
return Hex.toUint8(
|
||||
ASN1('30'
|
||||
, ASN1.UInt('00')
|
||||
, ASN1('30'
|
||||
, OBJ_ID_EC_PUB
|
||||
, objId
|
||||
)
|
||||
, ASN1('04'
|
||||
, ASN1('30'
|
||||
, ASN1.UInt('01')
|
||||
, ASN1('04', d)
|
||||
, ASN1('A1', ASN1.BitStr('04' + x + y)))))
|
||||
);
|
||||
};
|
||||
EC.packSpki = function (jwk) {
|
||||
var x = toHex(base64ToUint8(urlBase64ToBase64(jwk.x)));
|
||||
var y = toHex(base64ToUint8(urlBase64ToBase64(jwk.y)));
|
||||
var objId = ('P-256' === jwk.crv) ? OBJ_ID_EC : OBJ_ID_EC_384;
|
||||
return Hex.toUint8(
|
||||
ASN1('30'
|
||||
, ASN1('30'
|
||||
, OBJ_ID_EC_PUB
|
||||
, objId
|
||||
)
|
||||
, ASN1.BitStr('04' + x + y))
|
||||
);
|
||||
};
|
||||
EC.packPkix = EC.packSpki;
|
||||
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
{
|
||||
"name": "eckles",
|
||||
"version": "0.7.2",
|
||||
"version": "1.0.0",
|
||||
"description": "PEM-to-JWK and JWK-to-PEM for ECDSA keys in a lightweight, zero-dependency library focused on perfect universal compatibility.",
|
||||
"homepage": "https://git.coolaj86.com/coolaj86/eckles.js",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"eckles": "bin/eckles.js"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"fixtures",
|
||||
"lib"
|
||||
],
|
||||
"directories": {
|
||||
"lib": "lib"
|
||||
},
|
||||
|
|
51
test.sh
51
test.sh
|
@ -3,26 +3,53 @@ set -e
|
|||
|
||||
echo ""
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.sec1.pem
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.pkcs8.pem
|
||||
node bin/eckles.js fixtures/pub-ec-p256.spki.pem
|
||||
echo "Testing PEM-to-JWK P-256"
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.sec1.pem | tee fixtures/privkey-ec-p256.jwk.2
|
||||
diff fixtures/privkey-ec-p256.jwk.json fixtures/privkey-ec-p256.jwk.2
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.pkcs8.pem | tee fixtures/privkey-ec-p256.jwk.2
|
||||
diff fixtures/privkey-ec-p256.jwk.json fixtures/privkey-ec-p256.jwk.2
|
||||
node bin/eckles.js fixtures/pub-ec-p256.spki.pem | tee fixtures/pub-ec-p256.jwk.2
|
||||
diff fixtures/pub-ec-p256.jwk.json fixtures/pub-ec-p256.jwk.2
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.sec1.pem
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.pkcs8.pem
|
||||
node bin/eckles.js fixtures/pub-ec-p384.spki.pem
|
||||
echo "Testing PEM-to-JWK P-384"
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.sec1.pem | tee fixtures/privkey-ec-p384.jwk.2
|
||||
diff fixtures/privkey-ec-p384.jwk.json fixtures/privkey-ec-p384.jwk.2
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.pkcs8.pem | tee fixtures/privkey-ec-p384.jwk.2.2
|
||||
diff fixtures/privkey-ec-p384.jwk.json fixtures/privkey-ec-p384.jwk.2.2
|
||||
node bin/eckles.js fixtures/pub-ec-p384.spki.pem | tee fixtures/pub-ec-p384.jwk.2
|
||||
diff fixtures/pub-ec-p384.jwk.json fixtures/pub-ec-p384.jwk.2
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.jwk sec1
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.jwk pkcs8
|
||||
node bin/eckles.js fixtures/pub-ec-p256.jwk spki
|
||||
echo "Testing JWK-to-PEM P-256"
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.jwk.json sec1 | tee fixtures/privkey-ec-p256.sec1.pem.2
|
||||
diff fixtures/privkey-ec-p256.sec1.pem fixtures/privkey-ec-p256.sec1.pem.2
|
||||
node bin/eckles.js fixtures/privkey-ec-p256.jwk.json pkcs8 | tee fixtures/privkey-ec-p256.pkcs8.pem.2
|
||||
diff fixtures/privkey-ec-p256.pkcs8.pem fixtures/privkey-ec-p256.pkcs8.pem.2
|
||||
node bin/eckles.js fixtures/pub-ec-p256.jwk.json spki | tee fixtures/pub-ec-p256.spki.pem.2
|
||||
diff fixtures/pub-ec-p256.spki.pem fixtures/pub-ec-p256.spki.pem.2
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.jwk sec1
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.jwk pkcs8
|
||||
node bin/eckles.js fixtures/pub-ec-p384.jwk spki
|
||||
echo "Testing JWK-to-PEM P-384"
|
||||
echo ""
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.jwk.json sec1 | tee fixtures/privkey-ec-p384.sec1.pem.2
|
||||
diff fixtures/privkey-ec-p384.sec1.pem fixtures/privkey-ec-p384.sec1.pem.2
|
||||
node bin/eckles.js fixtures/privkey-ec-p384.jwk.json pkcs8 | tee fixtures/privkey-ec-p384.pkcs8.pem.2
|
||||
diff fixtures/privkey-ec-p384.pkcs8.pem fixtures/privkey-ec-p384.pkcs8.pem.2
|
||||
node bin/eckles.js fixtures/pub-ec-p384.jwk.json spki | tee fixtures/pub-ec-p384.spki.pem.2
|
||||
diff fixtures/pub-ec-p384.spki.pem fixtures/pub-ec-p384.spki.pem.2
|
||||
|
||||
rm fixtures/*.2
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
echo "PASSED:"
|
||||
echo "• All inputs produced valid outputs"
|
||||
echo "• All outputs matched known-good values"
|
||||
echo ""
|
||||
|
|
Loading…
Reference in New Issue