Skip to content

Commit

Permalink
passwords!
Browse files Browse the repository at this point in the history
  • Loading branch information
Calvin Metcalf committed Nov 15, 2014
1 parent 89e0d6a commit 8c95b09
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 6 deletions.
13 changes: 13 additions & 0 deletions aesid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{"2.16.840.1.101.3.4.1.1": "aes-128-ecb",
"2.16.840.1.101.3.4.1.2": "aes-128-cbc",
"2.16.840.1.101.3.4.1.3": "aes-128-ofb",
"2.16.840.1.101.3.4.1.4": "aes-128-cfb",
"2.16.840.1.101.3.4.1.21": "aes-192-ecb",
"2.16.840.1.101.3.4.1.22": "aes-192-cbc",
"2.16.840.1.101.3.4.1.23": "aes-192-ofb",
"2.16.840.1.101.3.4.1.24": "aes-192-cfb",
"2.16.840.1.101.3.4.1.41": "aes-256-ecb",
"2.16.840.1.101.3.4.1.42": "aes-256-cbc",
"2.16.840.1.101.3.4.1.43": "aes-256-ofb",
"2.16.840.1.101.3.4.1.44": "aes-256-cfb"
}
22 changes: 22 additions & 0 deletions asn1.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,28 @@ var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function() {
);
});
exports.PrivateKey = PrivateKeyInfo;
var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function() {
this.seq().obj(
this.key('algorithm').seq().obj(
this.key('id').objid(),
this.key('decrypt').seq().obj(
this.key('kde').seq().obj(
this.key('id').objid(),
this.key('kdeparams').seq().obj(
this.key('salt').octstr(),
this.key('iters').int()
)
),
this.key('cipher').seq().obj(
this.key('algo').objid(),
this.key('iv').octstr()
)
)
),
this.key('subjectPrivateKey').octstr()
);
});
exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo;
var GeneralName = asn1.define('GeneralName', function() {
this.choice({
dNSName: this.implicit(2).ia5str()
Expand Down
3 changes: 2 additions & 1 deletion inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function Sign(algorithm, crypto) {
var data = algos[algorithm];
this._hash = crypto.createHash(data.hash);
this._tag = data.id;
this._crypto = crypto;
};
Sign.prototype._write = function _write(data, _, done) {
this._hash.update(data);
Expand All @@ -34,7 +35,7 @@ Sign.prototype.update = function update(data) {
Sign.prototype.sign = function signMethod(key, enc) {
this.end();
var hash = this._hash.digest();
var sig = sign(Buffer.concat([this._tag, hash]), key);
var sig = sign(Buffer.concat([this._tag, hash]), key, this._crypto);
if (enc) {
sig = sig.toString(enc);
}
Expand Down
26 changes: 25 additions & 1 deletion parseKeys.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
var pemstrip = require('pemstrip');
var asn1 = require('./asn1');
var aesid = require('./aesid.json');
module.exports = parseKeys;

function parseKeys(buffer) {
function parseKeys(buffer, crypto) {
var password;
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
password = buffer.passphrase;
buffer = buffer.key;
}
var stripped = pemstrip.strip(buffer);
var type = stripped.tag;
var data = new Buffer(stripped.base64, 'base64');
Expand All @@ -17,6 +23,10 @@ function parseKeys(buffer) {
default: throw new Error('unknown key id ' + subtype);
}
throw new Error('unknown key type ' + type);
case 'ENCRYPTED PRIVATE KEY':
data = asn1.EncryptedPrivateKey.decode(data, 'der');
data = decrypt(crypto, data, password);
//falling through
case 'PRIVATE KEY':
data = asn1.PrivateKey.decode(data, 'der');
subtype = data.algorithm.algorithm.join('.');
Expand All @@ -32,4 +42,18 @@ function parseKeys(buffer) {
return asn1.RSAPrivateKey.decode(data, 'der');
default: throw new Error('unknown key type ' + type);
}
}
function decrypt(crypto, data, password) {
var salt = data.algorithm.decrypt.kde.kdeparams.salt;
var iters = data.algorithm.decrypt.kde.kdeparams.iters;
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')];
var iv = data.algorithm.decrypt.cipher.iv;
var cipherText = data.subjectPrivateKey;
var keylen = parseInt(algo.split('-')[1], 10)/8;
var key = crypto.pbkdf2Sync(password, salt, iters, keylen);
var cipher = crypto.createDecipheriv(algo, key, iv);
var out = [];
out.push(cipher.update(cipherText));
out.push(cipher.final());
return Buffer.concat(out);
}
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ a package to duplicate the functionality of node's crypto public key functions,
- publicEncrypt and privateDecrypt?
- ~~other key encodings (non rss format public keys)~~
- dsa keys?
- keys with passwords
- ~~keys with passwords~~
4 changes: 2 additions & 2 deletions sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
var parseKeys = require('./parseKeys');
var bn = require('bn.js');
module.exports = sign;
function sign(hash, key) {
var priv = parseKeys(key);
function sign(hash, key, crypto) {
var priv = parseKeys(key, crypto);
var len = priv.modulus.byteLength();
var pad = [ 0, 1 ];
while (hash.length + pad.length + 1 < len) {
Expand Down
19 changes: 18 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ var nonrsa1024 = {
private: fs.readFileSync(__dirname + '/1024.priv'),
public: fs.readFileSync(__dirname + '/1024.pub')
}
var pass1024 = {
private: {
passphrase: 'fooo',
key:fs.readFileSync(__dirname + '/pass.1024.priv')
},
public: fs.readFileSync(__dirname + '/pass.1024.pub')
}
function isNode10() {
return process.version && process.version.split('.').length === 3 && parseInt(process.version.split('.')[1], 10) <= 10;
}
var nodeCrypto = require('crypto');
var myCrypto = require('../');
function testIt(keys, message, scheme) {
Expand All @@ -32,6 +42,7 @@ function testIt(keys, message, scheme) {
t.ok(myVer.update(message).verify(pub, nodeSig), 'me validate node sig');
});
}

testIt(rsa1024, new Buffer('sha224 with 1024 keys'), 'RSA-SHA224');
testIt(nonrsa1024, new Buffer('sha224 with 1024 keys non-rsa key'), 'RSA-SHA224');
testIt(rsa2028, new Buffer('sha224 with 2028 keys'), 'RSA-SHA224');
Expand All @@ -43,4 +54,10 @@ testIt(nonrsa1024, new Buffer('sha384 with 1024 keys non-rsa key'), 'RSA-SHA384'
testIt(rsa2028, new Buffer('SHA384 with 2028 keys'), 'RSA-SHA384');
testIt(rsa1024, new Buffer('SHA512 with 1024 keys'), 'RSA-SHA512');
testIt(nonrsa1024, new Buffer('sha512 with 1024 keys non-rsa key'), 'RSA-SHA512');
testIt(rsa2028, new Buffer('SHA512 with 2028 keys'), 'RSA-SHA512');
testIt(rsa2028, new Buffer('SHA512 with 2028 keys'), 'RSA-SHA512');
if (!isNode10()) {
testIt(pass1024, new Buffer('sha224 with 1024 keys and password'), 'RSA-SHA224');
testIt(pass1024, new Buffer('sha256 with 1024 keys and password'), 'RSA-SHA256');
testIt(pass1024, new Buffer('sha384 with 1024 keys and password'), 'RSA-SHA384');
testIt(pass1024, new Buffer('sha512 with 1024 keys and password'), 'RSA-SHA512');
}
18 changes: 18 additions & 0 deletions test/pass.1024.priv
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIji3ZZ6JbsA4CAggA
MB0GCWCGSAFlAwQBFgQQC6MKblq8zyX90/KmgotsMQSCAoDghNf+yxPC/KRh7F3O
k0lMgtDkV+wCLDv7aBvUqy8Ry2zqFPIlfLb8XtSW943XEu6KUI13IZPEr8p9h1ve
Iye6L0g6uAgbFxBE2DwBBSI7mYr7lokr4v0k+inMKf4JeRdI9XWgwOILKTGf1vH7
PhvBnqLhOg6BIOuF426qpiyYlmRda74d0Th4o6ZyhyMSzPI1XbWSg719Ew3N/tLe
OHdYl0eFrgNjq+xO4Ev+W7eNIh/XBMQtk9wo+mxeNdldRnX822HxTsL8fSSPs+9T
W5M/2EBTJMSsswSjZyFkq8ehtxovI2u0IBX1IiPulyUZLnSNPDV1eUVClK6rk+q1
kVsfJhUr2qvIjNlQWlbEXQj4VwGtgl0++l8vdpj59MuN2J3Nx5TNMLjA6BYAa/tr
Bu928QoT7ET+SGx5XKCwKb5fwXmDlV5zZC4kZWTaF/d/Icvj5F+fDZuYFg1JOXNZ
+q2oA1qMYaHGX6lF3pbO84ebg1iwQTDM8iIqFeSMGUJTnk/3a7sqfaWQbEQwGb+X
fXnSTwkF+wO2rriPbFvWyzecWu67zDCP0ZWUgGb86sSJCM7xRGShESwCjOrb88F1
5SZjyIqogrkc3IWiLH9gc5U8d86qoFjJnP6BfwYks1UIyXNGKfZTCqICpMphV+IS
b0N2jprjLTkWR6nxYGSH1bkKMs7x1M0FBLWWLAZqPn9X3pe6JwIBds04O6XjF0un
oxwDjcJdoxVs7PgRiM5d1Tubqu2zmpCCmXNiqi9B0+rV9/jHg9IA5gUfvYdCcEv+
oAr90I+2+PuBFa9lgdbDV6DtZk4bSYluqamxVeLPg/vrewYfVfDv6jftfY1D0DEy
69H0
-----END ENCRYPTED PRIVATE KEY-----
6 changes: 6 additions & 0 deletions test/pass.1024.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSK/7i5BV0x+gmX16Wrm7kRkCZ
y1QUt6wiM2g+SAZTYR0381VnSMX2cv7CpN3499lZj1rL5S7YTaZZwX3RvU5fz56/
eDX6ciL/PZsbclN2KdkMWYgmcb9J1zUeoMQ3cjfFUCdQZ/ZvDWa+wY2Zg8os2Bow
AoufHtYHm3eOly/cWwIDAQAB
-----END PUBLIC KEY-----

0 comments on commit 8c95b09

Please sign in to comment.