|
|
- 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')
- var Buffer = require('safe-buffer').Buffer
-
- module.exports = function privateDecrypt (privateKey, enc, reverse) {
- var padding
- if (privateKey.padding) {
- padding = privateKey.padding
- } else if (reverse) {
- padding = 1
- } else {
- padding = 4
- }
-
- var key = parseKeys(privateKey)
- 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 = Buffer.alloc(k - msg.length)
- 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 k = key.modulus.byteLength()
- var iHash = createHash('sha1').update(Buffer.alloc(0)).digest()
- var hLen = iHash.length
- 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)
-
- 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 = Buffer.from(a)
- b = Buffer.from(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
- }
|