You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							105 lines
						
					
					
						
							2.4 KiB
						
					
					
				
			
		
		
	
	
							105 lines
						
					
					
						
							2.4 KiB
						
					
					
				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 | 
						|
}
 | 
						|
 |