Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rsa-compat

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rsa-compat - npm Package Compare versions

Comparing version 1.0.1 to 1.1.0

tests/generate-sig.js

41

lib/rsa-extra.js

@@ -9,2 +9,5 @@ 'use strict';

}
function b64ToBinstr(b64) {
return new Buffer(b64, 'b64').toString('binary');
}

@@ -41,3 +44,3 @@ /*

_forgeToPrivateJwk: function (keypair) {
var k = keypair._forge.privateKey;
var k = keypair._forge;

@@ -57,3 +60,3 @@ return {

, _forgeToPublicJwk: function (keypair) {
var k = keypair._forge.privateKey || keypair._forge.publicKey;
var k = keypair._forge || keypair._forgePublic;
return {

@@ -69,2 +72,26 @@ kty: "RSA"

//
// Import Forge
//
, _forgeImportJwk: require('./rsa-forge')._forgeImportJwk
, _forgeImportPublicJwk: require('./rsa-forge')._forgeImportPublicJwk
, _forgeImportPem: function (keypair) {
keypair._forge = keypair._forge || forge.pki.privateKeyFromPem(keypair.privateKeyPem);
}
, _forgeImportPublicPem: function (keypair) {
keypair._forgePublic = keypair._forgePublic || forge.pki.publicKeyFromPem(keypair.publicKeyPem);
}
, importForge: function (keypair) {
extrac._forgeImportJwk(keypair);
if (keypair.privateKeyPem) {
extrac._forgeImportPem(keypair);
}
if (keypair.publicKeyPem) {
extrac._forgeImportPublicPem(keypair);
}
return keypair;
}
//
// Export JWK

@@ -75,3 +102,3 @@ //

var hasPrivatePem = keypair.privateKeyPem && true;
var hasForgePrivate = keypair._forge && keypair._forge.privateKey && true;
var hasForgePrivate = keypair._forge && keypair._forge && true;

@@ -88,7 +115,7 @@ if (keypair.privateKeyJwk) {

if (keypair.privateKeyPem) {
keypair._forge = { privateKey: forge.pki.privateKeyFromPem(keypair.privateKeyPem) };
extrac._forgeImportPem(keypair);
}
}
if (keypair._forge && keypair._forge.privateKey) {
if (keypair._forge && keypair._forge) {
return extrac._forgeToPrivateJwk(keypair);

@@ -122,7 +149,7 @@ }

if (keypair.publicKeyPem) {
keypair._forge = { privateKey: forge.pki.publicKeyFromPem(keypair.publicKeyPem) };
extrac._forgeImportPublicPem(keypair);
}
}
if (keypair._forge && keypair._forge.privateKey) {
if (keypair._forge && keypair._forge) {
return extrac._forgeToPublicJwk(keypair);

@@ -129,0 +156,0 @@ }

77

lib/rsa-forge.js
'use strict';
var forge = require('node-forge');
var utils = require('./key-utils.js');

@@ -38,5 +37,18 @@ function notToJson() {

//
_base64ToBn: function (base64) {
return new forge.jsbn.BigInteger(utils.b64dec(base64).toString("hex"), 16);
_toStandardBase64: function (str) {
var b64 = str.replace(/-/g, "+").replace(/_/g, "/").replace(/=/g, "");
switch (b64.length % 4) {
case 2: b64 += "=="; break;
case 3: b64 += "="; break;
}
return b64;
}
, _base64ToBin: function (base64) {
var std64 = forgec._toStandardBase64(base64);
var hex = new Buffer(std64, 'base64').toString("hex");
return new forge.jsbn.BigInteger(hex, 16);
}
, _privateJwkToComponents: function (jwk) {

@@ -47,3 +59,3 @@ var components = [];

[ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
components.push(new forgec._base64tobin(jwk[key]));
components.push(forgec._base64ToBin(jwk[key]));
});

@@ -68,8 +80,9 @@

, generateKeypair: function (bitlen, exp, options, cb) {
var keypair = forge.pki.rsa.generateKeyPair({ bits: bitlen || 1024, e: exp || 0x10001 });
var fkeypair = forge.pki.rsa.generateKeyPair({ bits: bitlen || 1024, e: exp || 0x10001 });
keypair.toJSON = notToJson;
fkeypair.toJSON = notToJson;
cb(null, {
_forge: keypair
_forge: fkeypair.privateKey
, _forgePublic: fkeypair.publicKey
});

@@ -81,2 +94,26 @@ }

//
// Import (no-op)
//
, _forgeImportJwk: function (keypair) {
keypair._forge = keypair._forge || forge.pki.rsa.setPrivateKey.apply(
forge.pki.rsa
, forgec._privateJwkToComponents(keypair.privateKeyJwk)
);
keypair._forge.toJSON = notToJson;
}
, _forgeImportPublicJwk: function (keypair) {
keypair._forgePublic = keypair._forgePublic || forge.pki.rsa.setPublicKey.apply(
forge.pki.rsa
, forgec._publicJwkToComponents(keypair.publicKeyJwk)
);
keypair._forgePublic.toJSON = notToJson;
}
, import: function (keypair) {
// no-op since this must be done anyway in extra
return keypair;
}
//
// Export Public / Private PEMs

@@ -89,14 +126,8 @@ //

if (keypair.privateKeyJwk && !(keypair._forge && keypair._forge.privateKey)) {
keypair._forge = {
privateKey: forge.pki.rsa.setPrivateKey.apply(
forge.pki.rsa
, forgec._privateJwkToComponents(keypair.privateKeyJwk)
)
};
keypair._forge.toJSON = notToJson;
if (keypair.privateKeyJwk && !(keypair._forge && keypair._forge)) {
forgec._forgeImportJwk(keypair);
}
if (keypair._forge && keypair._forge.privateKey) {
return forge.pki.privateKeyToPem(keypair._forge.privateKey);
if (keypair._forge && keypair._forge) {
return forge.pki.privateKeyToPem(keypair._forge);
}

@@ -112,15 +143,9 @@

if ((keypair.privateKeyJwk || keypair.publicKeyJwk)
&& !(keypair._forge && (keypair._forge.privateKey || keypair._forge.publicKey))
&& !(keypair._forge && (keypair._forge || keypair._forgePublic))
) {
keypair._forge = {
publicKey: forge.pki.rsa.setPublicKey.apply(
forge.pki.rsa
, forgec._publicJwkToComponents(keypair.publicKeyJwk)
)
};
keypair._forge.toJSON = notToJson;
forgec._forgeImportPublicJwk(keypair);
}
if (keypair._forge) {
return forge.pki.publicKeyToPem(keypair._forge.publicKey || keypair._forge.privateKey);
return forge.pki.publicKeyToPem(keypair._forgePublic || keypair._forge);
}

@@ -127,0 +152,0 @@

@@ -52,11 +52,30 @@ 'use strict';

//
// Export Public / Private PEMs
// Import
//
, exportPrivatePem: function (keypair) {
, _ursaImportPem: function (keypair) {
if (keypair._ursa) {
return;
}
if (keypair.privateKeyPem) {
return keypair.privateKeyPem;
keypair._ursa = ursa.createPrivateKey(keypair.privateKeyPem);
keypair._ursa.toJSON = notToJson;
}
else if (keypair.publicKeyPem) {
ursac._ursaImportPublicPem(keypair);
}
}
, _ursaImportPublicPem: function (keypair) {
if (keypair._ursa || keypair._ursaPublic) {
return;
}
if (keypair.publicKeyPem) {
keypair._ursaPublic = ursa.createPublicKey(keypair.publicKeyPem);
keypair._ursaPublic.toJSON = notToJson;
}
}
, _ursaImportJwk: function (keypair) {
if (keypair._ursa) {
return keypair._ursa.toPrivatePem().toString('ascii');
return;
}

@@ -70,6 +89,45 @@

keypair._ursa.toJSON = notToJson;
}
else if (keypair.publicKeyJwk) {
ursac._ursaImportPublicJwk(keypair);
}
}
, _ursaImportPublicJwk: function (keypair) {
if (keypair._ursa || keypair._ursaPublic) {
return;
}
keypair._ursaPublic = ursa.createPublicKeyFromComponents.apply(
ursa
, ursac._publicJwkToComponents(keypair.publicKeyJwk)
);
keypair._ursaPublic.toJSON = notToJson;
}
, import: function (keypair) {
ursac._ursaImportJwk(keypair);
ursac._ursaImportPem(keypair);
return keypair;
}
//
// Export Public / Private PEMs
//
, exportPrivatePem: function (keypair) {
if (keypair.privateKeyPem) {
return keypair.privateKeyPem;
}
if (keypair._ursa) {
return keypair._ursa.toPrivatePem().toString('ascii');
}
if (keypair.privateKeyJwk) {
ursac._ursaImportJwk(keypair);
return keypair._ursa.toPrivatePem().toString('ascii');
}
throw new Error("None of privateKeyPem, _ursa, or privateKeyJwk found. No way to export private key PEM");

@@ -87,7 +145,3 @@ }

if (keypair.publicKeyJwk) {
keypair._ursaPublic = ursa.createPublicKeyFromComponents.apply(
ursa
, ursac._publicJwkToComponents(keypair.publicKeyJwk)
);
keypair._ursaPublic.toJSON = notToJson;
ursac._ursaImportPublicJwk(keypair);

@@ -98,7 +152,3 @@ return keypair._ursa.toPublicPem().toString('ascii');

if (keypair.privateKeyJwk) {
keypair._ursa = ursa.createPrivateKeyFromComponents.apply(
ursa
, ursac._privateJwkToComponents(keypair.privateKeyJwk)
);
keypair._ursa.toJSON = notToJson;
ursac._ursaImportJwk(keypair);

@@ -109,4 +159,3 @@ return keypair._ursa.toPublicPem().toString('ascii');

if (keypair.privateKeyPem) {
keypair._ursa = ursa.createPrivateKey(keypair.privateKeyPem);
keypair._ursa.toJSON = notToJson;
ursac._ursaImportPem(keypair);

@@ -113,0 +162,0 @@ return keypair._ursa.toPublicPem().toString('ascii');

@@ -17,3 +17,12 @@ /*!

try {
RSA._URSA = require('ursa');
} catch(e) {
// ignore
}
RSA.utils = require('./lib/key-utils.js');
RSA.utils.toWebsafeBase64 = function (b64) {
return b64.replace(/[+]/g, "-").replace(/\//g, "_").replace(/=/g,"");
};

@@ -32,3 +41,5 @@ RSA.utils._bytesToBuffer = function (bytes) {

var input = RSA.utils._bytesToBuffer('{"e":"'+ jwk.e + '","kty":"RSA","n":"'+ jwk.n +'"}');
return RSA.util.b64enc(crypto.createHash('sha256').update(input).digest());
var base64Digest = crypto.createHash('sha256').update(input).digest('base64');
return RSA.utils.toWebsafeBase64(base64Digest);
};

@@ -79,2 +90,76 @@

RSA.import = function (keypair/*, options*/) {
//options = options || NOBJ; // ignore
if (keypair.privateKeyJwk || keypair.privateKeyPem || keypair._ursa || (keypair._forge && keypair._forge)) {
keypair.privateKeyJwk = RSA._internal.exportPrivateJwk(keypair, { internal: true });
//keypair.privateKeyPem = RSA._internal.exportPrivatePem(keypair, { internal: true });
return keypair;
}
if (keypair.publicKeyJwk || keypair.publicKeyPem || keypair._ursaPublic || (keypair._forge && keypair._forgePublic)) {
keypair.publicKeyJwk = RSA._internal.exportPublicJwk(keypair, { internal: true });
//keypair.publicKeyPem = RSA._internal.exportPublicPem(keypair, { internal: true });
return keypair;
}
throw new Error('found neither private nor public keypair in any supported format');
};
RSA._ursaGenerateSig = function (keypair, sha256Buf) {
var sig = keypair._ursa.sign('sha256', sha256Buf);
var sig64 = RSA.utils.toWebsafeBase64(sig.toString('base64'));
return sig64;
};
RSA._forgeGenerateSig = function (keypair, sha256Buf) {
var forge = require('node-forge');
var bufF = forge.util.createBuffer(sha256Buf.toString('binary'), 'binary');
var md = {
algorithm: 'sha256'
, blockLength: 64
, digestLength: 20
, digest: function () {
return bufF;
}
};
var sigF = keypair._forge.sign(md);
var sig64 = RSA.utils.toWebsafeBase64(
new Buffer(forge.util.bytesToHex(sigF), "hex").toString('base64')
);
return sig64;
};
RSA.generateSignatureJwk = function (keypair, payload, nonce) {
keypair = RSA._internal.import(keypair);
keypair = RSA._internal.importForge(keypair);
keypair.publicKeyJwk = RSA.exportPublicJwk(keypair);
// Compute JWS signature
var protectedHeader = "";
if (nonce) {
protectedHeader = JSON.stringify({nonce: nonce});
}
var protected64 = RSA.utils.toWebsafeBase64(new Buffer(protectedHeader).toString('base64'));
var payload64 = RSA.utils.toWebsafeBase64(payload.toString('base64'));
var raw = protected64 + "." + payload64;
var sha256Buf = crypto.createHash('sha256').update(raw).digest();
var sig64;
if (RSA._URSA) {
sig64 = RSA._ursaGenerateSig(keypair, sha256Buf);
} else {
sig64 = RSA._forgeGenerateSig(keypair, sha256Buf);
}
return {
header: {
alg: "RS256"
, jwk: keypair.publicKeyJwk
}
, protected: protected64
, payload: payload64
, signature: sig64
};
};
RSA.exportPrivateKey = RSA._internal.exportPrivatePem;

@@ -81,0 +166,0 @@ RSA.exportPublicKey = RSA._internal.exportPublicPem;

{
"name": "rsa-compat",
"version": "1.0.1",
"version": "1.1.0",
"description": "RSA utils that work on Windows, Mac, and Linux with or without C compiler",

@@ -5,0 +5,0 @@ "main": "node.js",

@@ -16,4 +16,3 @@ # rsa-compat.js

```javascript
var PromiseA = require('bluebird');
var RSA = PromiseA.promisify(require('rsa-compat').RSA);
var RSA = require('rsa-compat').RSA;

@@ -24,3 +23,3 @@ var bitlen = 1024;

RSA.generateKeypair(bitlen, exp, options).then(function (keypair) {
RSA.generateKeypair(bitlen, exp, options, function (err, keypair) {
console.log(keypair);

@@ -30,2 +29,4 @@ });

Here's what the object might look like:
`console.log(keypair)`:

@@ -36,4 +37,2 @@ ```javascript

, privateKeyPem: '-----BEGIN RSA PRIVATE KEY-----\n/*base64 pem-encoded string*/'
// http://crypto.stackexchange.com/questions/6593/what-data-is-saved-in-rsa-private-key
, privateKeyJwk: {

@@ -45,23 +44,24 @@ kty: "RSA"

, p: '/*base64 first prime*/'
, q: /*base64 second prime*/
, dp: /*base64 first exponent for Chinese remainder theorem (dP = d (mod p−1))*/
, dq: /*base64 Second exponent, used for CRT (dQ = d (mod q−1))/
, qi: /*base64 Coefficient, used for CRT (qinv = q^−1 (mod p))*/
, q: '/*base64 second prime*/'
, dp: '/*base64 first exponent for Chinese remainder theorem (dP = d (mod p−1))*/'
, dq: '/*base64 Second exponent, used for CRT (dQ = d (mod q−1))/'
, qi: '/*base64 Coefficient, used for CRT (qinv = q^−1 (mod p))*/'
}
, publicKeyJwk: {
kty: "RSA"
, n: /*base64 modulus n = pq*/
, e: /base64 exponent (usually 65537)*/
, n: '/*base64 modulus n = pq*/'
, e: '/*base64 exponent (usually 65537)*/'
}
, _ursa: /*undefined or intermediate ursa object*/
, _ursaPublic: /*undefined or intermediate ursa object*/
, _forge: /*undefined or intermediate forge object*/
, _forgePublic: /*undefined or intermediate forge object*/
, _ursa: '/*undefined or intermediate ursa object*/'
, _ursaPublic: '/*undefined or intermediate ursa object*/'
, _forge: '/*undefined or intermediate forge object*/'
, _forgePublic: '/*undefined or intermediate forge object*/'
}
// NOTE: this object is JSON safe as _ursa and _forge will be ignored
```
NOTE: this object is JSON safe as _ursa and _forge will be ignored
See http://crypto.stackexchange.com/questions/6593/what-data-is-saved-in-rsa-private-key to learn a little more about the meaning of the specific fields in the JWK.
API

@@ -68,0 +68,0 @@ ---

@@ -5,10 +5,3 @@ 'use strict';

console.log('RSA');
console.log(RSA);
RSA.generateKeypair(null, null, null, function (err, keys) {
console.log('');
console.log('keys');
console.log(keys);
if (!keys.privateKeyJwk) {

@@ -26,3 +19,3 @@ throw new Error("Expected privateKeyJwk, but it is missing");

) {
console.error(keys);
console.error(Object.keys(keys));
throw new Error("Got unexpected keys");

@@ -36,22 +29,19 @@ }

, internal: true // preserve internal intermediate formats (_ursa, _forge)
, thumbprint: true // JWK sha256 thumbprint
//, thumbprint: true // JWK sha256 thumbprint
};
RSA.generateKeypair(512, 65537, options, function (err, keys) {
console.log('');
console.log('keys');
console.log(keys);
if (
keys.publicKeyJwk
|| keys.privateKeyPem
|| keys.publicKeyPem
|| keys.thumbprint
|| keys._ursa
|| keys._forge
(keys.publicKeyJwk && !keys.thumbprint)
|| !keys.privateKeyPem
|| !keys.publicKeyPem
//|| !keys.thumbprint
|| !(keys._ursa || keys._forge)
) {
console.error(keys);
throw new Error("Got unexpected keys");
console.error(Object.keys(keys));
throw new Error("Missing expected keys");
}
console.log('All is well!');
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc