diff options
Diffstat (limited to 'node_modules/public-encrypt/privateDecrypt.js')
-rw-r--r-- | node_modules/public-encrypt/privateDecrypt.js | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/node_modules/public-encrypt/privateDecrypt.js b/node_modules/public-encrypt/privateDecrypt.js new file mode 100644 index 000000000..9047c0e08 --- /dev/null +++ b/node_modules/public-encrypt/privateDecrypt.js @@ -0,0 +1,108 @@ +var parseKeys = require('parse-asn1'); +var mgf = require('./mgf'); +var xor = require('./xor'); +var bn = require('bn.js'); +var crt = require('browserify-rsa'); +var createHash = require('create-hash'); +var withPublic = require('./withPublic'); +module.exports = function privateDecrypt(private_key, enc, reverse) { + var padding; + if (private_key.padding) { + padding = private_key.padding; + } else if (reverse) { + padding = 1; + } else { + padding = 4; + } + + var key = parseKeys(private_key); + var k = key.modulus.byteLength(); + if (enc.length > k || new bn(enc).cmp(key.modulus) >= 0) { + throw new Error('decryption error'); + } + var msg; + if (reverse) { + msg = withPublic(new bn(enc), key); + } else { + msg = crt(enc, key); + } + var zBuffer = new Buffer(k - msg.length); + zBuffer.fill(0); + msg = Buffer.concat([zBuffer, msg], k); + if (padding === 4) { + return oaep(key, msg); + } else if (padding === 1) { + return pkcs1(key, msg, reverse); + } else if (padding === 3) { + return msg; + } else { + throw new Error('unknown padding'); + } +}; + +function oaep(key, msg){ + var n = key.modulus; + var k = key.modulus.byteLength(); + var mLen = msg.length; + var iHash = createHash('sha1').update(new Buffer('')).digest(); + var hLen = iHash.length; + var hLen2 = 2 * hLen; + if (msg[0] !== 0) { + throw new Error('decryption error'); + } + var maskedSeed = msg.slice(1, hLen + 1); + var maskedDb = msg.slice(hLen + 1); + var seed = xor(maskedSeed, mgf(maskedDb, hLen)); + var db = xor(maskedDb, mgf(seed, k - hLen - 1)); + if (compare(iHash, db.slice(0, hLen))) { + throw new Error('decryption error'); + } + var i = hLen; + while (db[i] === 0) { + i++; + } + if (db[i++] !== 1) { + throw new Error('decryption error'); + } + return db.slice(i); +} + +function pkcs1(key, msg, reverse){ + var p1 = msg.slice(0, 2); + var i = 2; + var status = 0; + while (msg[i++] !== 0) { + if (i >= msg.length) { + status++; + break; + } + } + var ps = msg.slice(2, i - 1); + var p2 = msg.slice(i - 1, i); + + if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)){ + status++; + } + if (ps.length < 8) { + status++; + } + if (status) { + throw new Error('decryption error'); + } + return msg.slice(i); +} +function compare(a, b){ + a = new Buffer(a); + b = new Buffer(b); + var dif = 0; + var len = a.length; + if (a.length !== b.length) { + dif++; + len = Math.min(a.length, b.length); + } + var i = -1; + while (++i < len) { + dif += (a[i] ^ b[i]); + } + return dif; +}
\ No newline at end of file |