privateDecrypt.js 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. var parseKeys = require('parse-asn1');
  2. var mgf = require('./mgf');
  3. var xor = require('./xor');
  4. var bn = require('bn.js');
  5. var crt = require('browserify-rsa');
  6. var createHash = require('create-hash');
  7. var withPublic = require('./withPublic');
  8. module.exports = function privateDecrypt(private_key, enc, reverse) {
  9. var padding;
  10. if (private_key.padding) {
  11. padding = private_key.padding;
  12. } else if (reverse) {
  13. padding = 1;
  14. } else {
  15. padding = 4;
  16. }
  17. var key = parseKeys(private_key);
  18. var k = key.modulus.byteLength();
  19. if (enc.length > k || new bn(enc).cmp(key.modulus) >= 0) {
  20. throw new Error('decryption error');
  21. }
  22. var msg;
  23. if (reverse) {
  24. msg = withPublic(new bn(enc), key);
  25. } else {
  26. msg = crt(enc, key);
  27. }
  28. var zBuffer = new Buffer(k - msg.length);
  29. zBuffer.fill(0);
  30. msg = Buffer.concat([zBuffer, msg], k);
  31. if (padding === 4) {
  32. return oaep(key, msg);
  33. } else if (padding === 1) {
  34. return pkcs1(key, msg, reverse);
  35. } else if (padding === 3) {
  36. return msg;
  37. } else {
  38. throw new Error('unknown padding');
  39. }
  40. };
  41. function oaep(key, msg){
  42. var n = key.modulus;
  43. var k = key.modulus.byteLength();
  44. var mLen = msg.length;
  45. var iHash = createHash('sha1').update(new Buffer('')).digest();
  46. var hLen = iHash.length;
  47. var hLen2 = 2 * hLen;
  48. if (msg[0] !== 0) {
  49. throw new Error('decryption error');
  50. }
  51. var maskedSeed = msg.slice(1, hLen + 1);
  52. var maskedDb = msg.slice(hLen + 1);
  53. var seed = xor(maskedSeed, mgf(maskedDb, hLen));
  54. var db = xor(maskedDb, mgf(seed, k - hLen - 1));
  55. if (compare(iHash, db.slice(0, hLen))) {
  56. throw new Error('decryption error');
  57. }
  58. var i = hLen;
  59. while (db[i] === 0) {
  60. i++;
  61. }
  62. if (db[i++] !== 1) {
  63. throw new Error('decryption error');
  64. }
  65. return db.slice(i);
  66. }
  67. function pkcs1(key, msg, reverse){
  68. var p1 = msg.slice(0, 2);
  69. var i = 2;
  70. var status = 0;
  71. while (msg[i++] !== 0) {
  72. if (i >= msg.length) {
  73. status++;
  74. break;
  75. }
  76. }
  77. var ps = msg.slice(2, i - 1);
  78. var p2 = msg.slice(i - 1, i);
  79. if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)){
  80. status++;
  81. }
  82. if (ps.length < 8) {
  83. status++;
  84. }
  85. if (status) {
  86. throw new Error('decryption error');
  87. }
  88. return msg.slice(i);
  89. }
  90. function compare(a, b){
  91. a = new Buffer(a);
  92. b = new Buffer(b);
  93. var dif = 0;
  94. var len = a.length;
  95. if (a.length !== b.length) {
  96. dif++;
  97. len = Math.min(a.length, b.length);
  98. }
  99. var i = -1;
  100. while (++i < len) {
  101. dif += (a[i] ^ b[i]);
  102. }
  103. return dif;
  104. }