passes basic reciprical test
This commit is contained in:
parent
5de4362c6c
commit
fdd30294d8
15
README.md
15
README.md
|
@ -65,6 +65,7 @@ API
|
|||
---
|
||||
|
||||
* `RSA.generateKeypair(bitlen, exp, options, cb)`
|
||||
* `RSA.import(keypair, options)`
|
||||
* `RSA.exportPrivatePem(keypair)`
|
||||
* `RSA.exportPublicPem(keypair)`
|
||||
* `RSA.exportPrivateJwk(keypair)`
|
||||
|
@ -100,6 +101,20 @@ RSA.generateKeypair(1024, 65537, { pem: false, public: false, internal: false },
|
|||
}
|
||||
```
|
||||
|
||||
### RSA.import(keypair, options)
|
||||
|
||||
Imports keypair as JWKs and internal values `_ursa` and `_forge`.
|
||||
|
||||
```javascript
|
||||
var keypair = RSA.import({ privateKeyPem: '...'});
|
||||
|
||||
console.log(keypair);
|
||||
```
|
||||
|
||||
```javascript
|
||||
{ privateKeyPem: ..., privateKeyJwk: ..., _ursa: ..., _forge: ... }
|
||||
```
|
||||
|
||||
### RSA.export*(keypair)
|
||||
|
||||
You put in an object like `{ privateKeyPem: '...' }` or `{ publicKeyJwk: {} }`
|
||||
|
|
|
@ -1,9 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
function binstrToB64Url(binstr) {
|
||||
return new Buffer(binstr, 'binary').toString('base64')
|
||||
.replace(/[+]/g, "-").replace(/\//g, "_").replace(/=/g,"");
|
||||
// for forge
|
||||
function _bigIntToBase64Url(fbin) {
|
||||
var hex = fbin.toRadix(16);
|
||||
if (hex.length % 2) {
|
||||
// Invalid hex string
|
||||
hex = '0' + hex;
|
||||
}
|
||||
var buf = Buffer.from(hex, 'hex');
|
||||
var b64 = buf.toString('base64');
|
||||
var b64Url = b64.replace(/[+]/g, "-").replace(/\//g, "_").replace(/=/g,"");
|
||||
|
||||
return b64Url;
|
||||
}
|
||||
/*
|
||||
// I think this doesn't work because toByteArray() returns signed bytes
|
||||
function _xxx_bigIntToBase64Url(fbin) {
|
||||
if (!fbin.toByteArray) {
|
||||
console.log('fbin');
|
||||
console.log(fbin);
|
||||
}
|
||||
var byteArray = fbin.toByteArray();
|
||||
var buf = Buffer.from(byteArray);
|
||||
var b64 = buf.toString('base64');
|
||||
var b64Url = b64.replace(/[+]/g, "-").replace(/\//g, "_").replace(/=/g,"");
|
||||
|
||||
return b64Url;
|
||||
}
|
||||
*/
|
||||
|
||||
var extrac = module.exports = {
|
||||
//
|
||||
|
@ -14,22 +38,22 @@ var extrac = module.exports = {
|
|||
|
||||
return {
|
||||
kty: "RSA"
|
||||
, n: binstrToB64Url(k.n.toByteArray())
|
||||
, e: binstrToB64Url(k.e.toByteArray())
|
||||
, d: binstrToB64Url(k.d.toByteArray())
|
||||
, p: binstrToB64Url(k.p.toByteArray())
|
||||
, q: binstrToB64Url(k.q.toByteArray())
|
||||
, dp: binstrToB64Url(k.dP.toByteArray())
|
||||
, dq: binstrToB64Url(k.dQ.toByteArray())
|
||||
, qi: binstrToB64Url(k.qInv.toByteArray())
|
||||
, n: _bigIntToBase64Url(k.n)
|
||||
, e: _bigIntToBase64Url(k.e)
|
||||
, d: _bigIntToBase64Url(k.d)
|
||||
, p: _bigIntToBase64Url(k.p)
|
||||
, q: _bigIntToBase64Url(k.q)
|
||||
, dp: _bigIntToBase64Url(k.dP)
|
||||
, dq: _bigIntToBase64Url(k.dQ)
|
||||
, qi: _bigIntToBase64Url(k.qInv)
|
||||
};
|
||||
}
|
||||
, _forgeToPublicJwk: function (keypair) {
|
||||
var k = keypair._forge || keypair._forgePublic;
|
||||
return {
|
||||
kty: "RSA"
|
||||
, n: binstrToB64Url(k.n.toByteArray())
|
||||
, e: binstrToB64Url(k.e.toByteArray())
|
||||
, n: _bigIntToBase64Url(k.n)
|
||||
, e: _bigIntToBase64Url(k.e)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ var forgec = module.exports = {
|
|||
|
||||
return b64;
|
||||
}
|
||||
, _base64ToBin: function (base64) {
|
||||
, _base64UrlToBin: function (base64) {
|
||||
var std64 = forgec._toStandardBase64(base64);
|
||||
var hex = new Buffer(std64, 'base64').toString("hex");
|
||||
|
||||
|
@ -34,7 +34,7 @@ var forgec = module.exports = {
|
|||
|
||||
// [ 'n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv' ]
|
||||
[ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
|
||||
components.push(forgec._base64ToBin(jwk[key]));
|
||||
components.push(forgec._base64UrlToBin(jwk[key]));
|
||||
});
|
||||
|
||||
return components;
|
||||
|
@ -42,7 +42,7 @@ var forgec = module.exports = {
|
|||
, _publicJwkToComponents: function (jwk) {
|
||||
var components = [];
|
||||
[ 'n', 'e' ].forEach(function (key) {
|
||||
components.push(new Buffer(jwk[key], 'base64'));
|
||||
components.push(forgec._base64UrlToBin(jwk[key]));
|
||||
});
|
||||
|
||||
return components;
|
||||
|
@ -55,13 +55,15 @@ var forgec = module.exports = {
|
|||
//
|
||||
, generateKeypair: function (bitlen, exp, options, cb) {
|
||||
var fkeypair = forge.pki.rsa.generateKeyPair({ bits: bitlen || 1024, e: exp || 0x10001 });
|
||||
|
||||
fkeypair.toJSON = notToJson;
|
||||
|
||||
cb(null, {
|
||||
var result = {
|
||||
_forge: fkeypair.privateKey
|
||||
, _forgePublic: fkeypair.publicKey
|
||||
});
|
||||
};
|
||||
|
||||
result._forge.toJSON = notToJson;
|
||||
result._forgePublic.toJSON = notToJson;
|
||||
|
||||
cb(null, result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,8 +77,8 @@ var forgec = module.exports = {
|
|||
forge.pki.rsa
|
||||
, forgec._privateJwkToComponents(keypair.privateKeyJwk)
|
||||
);
|
||||
}
|
||||
keypair._forge.toJSON = notToJson;
|
||||
}
|
||||
|
||||
forgec._forgeImportPublicJwk(keypair);
|
||||
}
|
||||
|
@ -94,13 +96,15 @@ var forgec = module.exports = {
|
|||
, forgec._publicJwkToComponents(keypair.publicKeyJwk || keypair.privateKeyJwk)
|
||||
);
|
||||
}
|
||||
if (keypair._forgePublic) {
|
||||
keypair._forgePublic.toJSON = notToJson;
|
||||
}
|
||||
}
|
||||
, _forgeImportPem: function (keypair) {
|
||||
if (!keypair._forge && keypair.privateKeyPem) {
|
||||
keypair._forge = forge.pki.privateKeyFromPem(keypair.privateKeyPem);
|
||||
}
|
||||
keypair._forge.toJSON = notToJson;
|
||||
}
|
||||
|
||||
forgec._forgeImportPublicPem(keypair);
|
||||
}
|
||||
|
@ -115,8 +119,10 @@ var forgec = module.exports = {
|
|||
else if (keypair.publicKeyPem) {
|
||||
keypair._forgePublic = keypair._forgePublic || forge.pki.publicKeyFromPem(keypair.publicKeyPem);
|
||||
}
|
||||
if (keypair._forgePublic) {
|
||||
keypair._forgePublic.toJSON = notToJson;
|
||||
}
|
||||
}
|
||||
, import: function (keypair) {
|
||||
// no-op since this must be done anyway in extra
|
||||
return keypair;
|
||||
|
|
|
@ -115,19 +115,22 @@ var ursac = module.exports = {
|
|||
//
|
||||
// Export Public / Private PEMs
|
||||
//
|
||||
, _pemBinToPem: function (pem) {
|
||||
return pem.toString('ascii').replace(/[\n\r]+/g, '\r\n');
|
||||
}
|
||||
, exportPrivatePem: function (keypair) {
|
||||
if (keypair.privateKeyPem) {
|
||||
return keypair.privateKeyPem;
|
||||
}
|
||||
|
||||
if (keypair._ursa) {
|
||||
return keypair._ursa.toPrivatePem().toString('ascii');
|
||||
return ursac._pemBinToPem(keypair._ursa.toPrivatePem());
|
||||
}
|
||||
|
||||
if (keypair.privateKeyJwk) {
|
||||
ursac._ursaImportJwk(keypair);
|
||||
|
||||
return keypair._ursa.toPrivatePem().toString('ascii');
|
||||
return ursac._pemBinToPem(keypair._ursa.toPrivatePem());
|
||||
}
|
||||
|
||||
throw new Error("None of privateKeyPem, _ursa, or privateKeyJwk found. No way to export private key PEM");
|
||||
|
@ -138,25 +141,25 @@ var ursac = module.exports = {
|
|||
}
|
||||
|
||||
if (keypair._ursa || keypair._ursaPublic) {
|
||||
return (keypair._ursa || keypair._ursaPublic).toPublicPem().toString('ascii');
|
||||
return ursac._pemBinToPem((keypair._ursa || keypair._ursaPublic).toPublicPem());
|
||||
}
|
||||
|
||||
if (keypair.publicKeyJwk) {
|
||||
ursac._ursaImportPublicJwk(keypair);
|
||||
|
||||
return keypair._ursaPublic.toPublicPem().toString('ascii');
|
||||
return ursac._pemBinToPem(keypair._ursaPublic.toPublicPem());
|
||||
}
|
||||
|
||||
if (keypair.privateKeyJwk) {
|
||||
ursac._ursaImportJwk(keypair);
|
||||
|
||||
return keypair._ursa.toPublicPem().toString('ascii');
|
||||
return ursac._pemBinToPem(keypair._ursa.toPublicPem());
|
||||
}
|
||||
|
||||
if (keypair.privateKeyPem) {
|
||||
ursac._ursaImportPem(keypair);
|
||||
|
||||
return keypair._ursa.toPublicPem().toString('ascii');
|
||||
return ursac._pemBinToPem(keypair._ursa.toPublicPem());
|
||||
}
|
||||
|
||||
throw new Error("None of publicKeyPem, _ursa, publicKeyJwk, privateKeyPem, or privateKeyJwk found. No way to export public key PEM");
|
||||
|
|
2
node.js
2
node.js
|
@ -110,6 +110,8 @@ function create(deps) {
|
|||
};
|
||||
|
||||
RSA.import = function (keypair/*, options*/) {
|
||||
keypair = RSA._internal.import(keypair, { internal: true });
|
||||
keypair = RSA._internal.importForge(keypair, { internal: true });
|
||||
//options = options || NOBJ; // ignore
|
||||
if (keypair.privateKeyJwk || keypair.privateKeyPem || keypair._ursa || keypair._forge) {
|
||||
keypair.privateKeyJwk = RSA._internal.exportPrivateJwk(keypair, { internal: true });
|
||||
|
|
|
@ -28,7 +28,6 @@ try {
|
|||
// PEM tests
|
||||
//
|
||||
//
|
||||
console.log('');
|
||||
console.log('JWK -> PEM ?', privkeyPemRef === refs.privPem);
|
||||
if (privkeyPemRef !== refs.privPem) {
|
||||
// Watch out for tricky whitespaces (\n instead of \r\n, trailing \r\n, etc)
|
||||
|
@ -39,7 +38,6 @@ if (privkeyPemRef !== refs.privPem) {
|
|||
throw new Error("Failed to validate importedJwk against referencePem");
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('PEM -> _ -> PEM ?', privkeyPemRef === refs.privPem);
|
||||
if (hasUrsa) {
|
||||
imported = RSA.import({ privateKeyPem: privkeyPemRef });
|
||||
|
@ -57,17 +55,13 @@ if (privkeyPemRef !== refs.privPem2) {
|
|||
throw new Error("Failed to validate importedPem against referencePem");
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// JWK tests
|
||||
//
|
||||
//
|
||||
console.log('');
|
||||
console.log('PEM -> JWK', privkeyJwkRef.n === refs.privJwk.n);
|
||||
console.log('PEM -> JWK ?', privkeyJwkRef.n === refs.privJwk.n);
|
||||
if (privkeyJwkRef.n !== refs.privJwk.n) {
|
||||
console.log('REF:');
|
||||
console.log(privkeyJwkRef);
|
||||
|
@ -76,10 +70,9 @@ if (privkeyJwkRef.n !== refs.privJwk.n) {
|
|||
throw new Error("Failed to validate importedPem against referenceJwk");
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('JWK -> _ -> JWK', privkeyJwkRef.n === refs.privJwk2.n);
|
||||
imported = RSA.import({ privateKeyJwk: privkeyJwkRef });
|
||||
refs.privJwk2 = RSA.exportPrivateJwk({ _forge: imported._forge });
|
||||
console.log('JWK -> _ -> JWK ?', privkeyJwkRef.n === refs.privJwk2.n);
|
||||
if (privkeyJwkRef.n !== refs.privJwk2.n) {
|
||||
console.log('REF:');
|
||||
console.log(privkeyJwkRef);
|
||||
|
|
Loading…
Reference in New Issue