AJ ONeal
5 years ago
9 changed files with 276 additions and 46 deletions
@ -1,2 +1,2 @@ |
|||||
'use strict'; |
'use strict'; |
||||
module.exports = require('./lib/rasha.js'); |
module.exports = require('./lib/rsa.js'); |
||||
|
@ -0,0 +1,51 @@ |
|||||
|
'use strict'; |
||||
|
/*global Promise*/ |
||||
|
|
||||
|
var PEM = require('./pem.js'); |
||||
|
var x509 = require('./x509.js'); |
||||
|
var ASN1 = require('./asn1.js'); |
||||
|
|
||||
|
// Hacky-do, wrappy-do
|
||||
|
module.exports.generate = function (opts) { |
||||
|
if (!opts) { opts = {}; } |
||||
|
return new Promise(function (resolve, reject) { |
||||
|
try { |
||||
|
var modlen = opts.modulusLength || 2048; |
||||
|
var exp = opts.publicExponent || 0x10001; |
||||
|
var pair = require('./generate-privkey.js')(modlen,exp); |
||||
|
if (pair.private) { resolve(pair); return; } |
||||
|
pair = toJwks(pair); |
||||
|
resolve({ private: pair.private , public: pair.public }); |
||||
|
} catch(e) { |
||||
|
reject(e); |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
// PKCS1 to JWK only
|
||||
|
function toJwks(oldpair) { |
||||
|
var block = PEM.parseBlock(oldpair.privateKeyPem); |
||||
|
var asn1 = ASN1.parse(block.bytes); |
||||
|
var jwk = { kty: 'RSA', n: null, e: null }; |
||||
|
jwk = x509.parsePkcs1(block.bytes, asn1, jwk); |
||||
|
return { private: jwk, public: neuter(jwk) }; |
||||
|
} |
||||
|
|
||||
|
// Copied from rsa.js to prevent circular dep
|
||||
|
var privates = [ 'p', 'q', 'd', 'dp', 'dq', 'qi' ]; |
||||
|
function neuter(priv) { |
||||
|
var pub = {}; |
||||
|
Object.keys(priv).forEach(function (key) { |
||||
|
if (!privates.includes(key)) { |
||||
|
pub[key] = priv[key]; |
||||
|
} |
||||
|
}); |
||||
|
return pub; |
||||
|
} |
||||
|
|
||||
|
if (require.main === module) { |
||||
|
module.exports.generate().then(function (pair) { |
||||
|
console.info(JSON.stringify(pair.private, null, 2)); |
||||
|
console.info(JSON.stringify(pair.public, null, 2)); |
||||
|
}); |
||||
|
} |
@ -0,0 +1,53 @@ |
|||||
|
// Copyright 2016-2018 AJ ONeal. All rights reserved
|
||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
'use strict'; |
||||
|
|
||||
|
module.exports = function (bitlen, exp) { |
||||
|
var k = require('node-forge').pki.rsa |
||||
|
.generateKeyPair({ bits: bitlen || 2048, e: exp || 0x10001 }).privateKey; |
||||
|
var jwk = { |
||||
|
kty: "RSA" |
||||
|
, n: _toUrlBase64(k.n) |
||||
|
, e: _toUrlBase64(k.e) |
||||
|
, d: _toUrlBase64(k.d) |
||||
|
, p: _toUrlBase64(k.p) |
||||
|
, q: _toUrlBase64(k.q) |
||||
|
, dp: _toUrlBase64(k.dP) |
||||
|
, dq: _toUrlBase64(k.dQ) |
||||
|
, qi: _toUrlBase64(k.qInv) |
||||
|
}; |
||||
|
return { |
||||
|
private: jwk |
||||
|
, public: { |
||||
|
kty: jwk.kty |
||||
|
, n: jwk.n |
||||
|
, e: jwk.e |
||||
|
} |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
function _toUrlBase64(fbn) { |
||||
|
var hex = fbn.toRadix(16); |
||||
|
if (hex.length % 2) { |
||||
|
// Invalid hex string
|
||||
|
hex = '0' + hex; |
||||
|
} |
||||
|
while ('00' === hex.slice(0, 2)) { |
||||
|
hex = hex.slice(2); |
||||
|
} |
||||
|
return Buffer.from(hex, 'hex').toString('base64') |
||||
|
.replace(/\+/g, "-") |
||||
|
.replace(/\//g, "_") |
||||
|
.replace(/=/g,"") |
||||
|
; |
||||
|
} |
||||
|
|
||||
|
if (require.main === module) { |
||||
|
var keypair = module.exports(2048, 0x10001); |
||||
|
console.info(keypair.private); |
||||
|
console.warn(keypair.public); |
||||
|
//console.info(keypair.privateKeyJwk);
|
||||
|
//console.warn(keypair.publicKeyJwk);
|
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
// Copyright 2016-2018 AJ ONeal. All rights reserved
|
||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
'use strict'; |
||||
|
|
||||
|
module.exports = function (bitlen, exp) { |
||||
|
var keypair = require('crypto').generateKeyPairSync( |
||||
|
'rsa' |
||||
|
, { modulusLength: bitlen |
||||
|
, publicExponent: exp |
||||
|
, privateKeyEncoding: { type: 'pkcs1', format: 'pem' } |
||||
|
, publicKeyEncoding: { type: 'pkcs1', format: 'pem' } |
||||
|
} |
||||
|
); |
||||
|
var result = { privateKeyPem: keypair.privateKey.trim() }; |
||||
|
return result; |
||||
|
}; |
||||
|
|
||||
|
if (require.main === module) { |
||||
|
var keypair = module.exports(2048, 0x10001); |
||||
|
console.info(keypair.privateKeyPem); |
||||
|
console.warn(keypair.publicKeyPem); |
||||
|
//console.info(keypair.privateKeyJwk);
|
||||
|
//console.warn(keypair.publicKeyJwk);
|
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
// Copyright 2016-2018 AJ ONeal. All rights reserved
|
||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
'use strict'; |
||||
|
|
||||
|
module.exports = function (bitlen, exp) { |
||||
|
var ursa; |
||||
|
try { |
||||
|
ursa = require('ursa'); |
||||
|
} catch(e) { |
||||
|
ursa = require('ursa-optional'); |
||||
|
} |
||||
|
var keypair = ursa.generatePrivateKey(bitlen, exp); |
||||
|
var result = { privateKeyPem: keypair.toPrivatePem().toString('ascii').trim() }; |
||||
|
return result; |
||||
|
}; |
||||
|
|
||||
|
if (require.main === module) { |
||||
|
var keypair = module.exports(2048, 0x10001); |
||||
|
console.info(keypair.privateKeyPem); |
||||
|
console.warn(keypair.publicKeyPem); |
||||
|
//console.info(keypair.privateKeyJwk);
|
||||
|
//console.warn(keypair.publicKeyJwk);
|
||||
|
} |
@ -0,0 +1,67 @@ |
|||||
|
// Copyright 2016-2018 AJ ONeal. All rights reserved
|
||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public |
||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this |
||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
'use strict'; |
||||
|
|
||||
|
var oldver = false; |
||||
|
|
||||
|
module.exports = function (bitlen, exp) { |
||||
|
bitlen = parseInt(bitlen, 10) || 2048; |
||||
|
exp = parseInt(exp, 10) || 65537; |
||||
|
|
||||
|
try { |
||||
|
return require('./generate-privkey-node.js')(bitlen, exp); |
||||
|
} catch(e) { |
||||
|
if (!/generateKeyPairSync is not a function/.test(e.message)) { |
||||
|
throw e; |
||||
|
} |
||||
|
try { |
||||
|
return require('./generate-privkey-ursa.js')(bitlen, exp); |
||||
|
} catch(e) { |
||||
|
if (e.code !== 'MODULE_NOT_FOUND') { |
||||
|
console.error("[rsa-compat] Unexpected error when using 'ursa':"); |
||||
|
console.error(e); |
||||
|
} |
||||
|
if (!oldver) { |
||||
|
oldver = true; |
||||
|
console.warn("[WARN] rsa-compat: Your version of node does not have crypto.generateKeyPair()"); |
||||
|
console.warn("[WARN] rsa-compat: Please update to node >= v10.12 or 'npm install --save ursa node-forge'"); |
||||
|
console.warn("[WARN] rsa-compat: Using node-forge as a fallback may be unacceptably slow."); |
||||
|
if (/arm|mips/i.test(require('os').arch)) { |
||||
|
console.warn("================================================================"); |
||||
|
console.warn(" WARNING"); |
||||
|
console.warn("================================================================"); |
||||
|
console.warn(""); |
||||
|
console.warn("WARNING: You are generating an RSA key using pure JavaScript on"); |
||||
|
console.warn(" a VERY SLOW cpu. This could take DOZENS of minutes!"); |
||||
|
console.warn(""); |
||||
|
console.warn(" We recommend installing node >= v10.12, or 'gcc' and 'ursa'"); |
||||
|
console.warn(""); |
||||
|
console.warn("EXAMPLE:"); |
||||
|
console.warn(""); |
||||
|
console.warn(" sudo apt-get install build-essential && npm install ursa"); |
||||
|
console.warn(""); |
||||
|
console.warn("================================================================"); |
||||
|
} |
||||
|
} |
||||
|
try { |
||||
|
return require('./generate-privkey-forge.js')(bitlen, exp); |
||||
|
} catch(e) { |
||||
|
if (e.code !== 'MODULE_NOT_FOUND') { |
||||
|
throw e; |
||||
|
} |
||||
|
console.error("[ERROR] rsa-compat: could not generate a private key."); |
||||
|
console.error("None of crypto.generateKeyPair, ursa, nor node-forge are present"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
if (require.main === module) { |
||||
|
var keypair = module.exports(2048, 0x10001); |
||||
|
console.info(keypair.privateKeyPem); |
||||
|
console.warn(keypair.publicKeyPem); |
||||
|
//console.info(keypair.privateKeyJwk);
|
||||
|
//console.warn(keypair.publicKeyJwk);
|
||||
|
} |
Loading…
Reference in new issue