Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80542 views
1
var parseKeys = require('parse-asn1');
2
var randomBytes = require('randombytes');
3
var createHash = require('create-hash');
4
var mgf = require('./mgf');
5
var xor = require('./xor');
6
var bn = require('bn.js');
7
var withPublic = require('./withPublic');
8
var crt = require('browserify-rsa');
9
10
var constants = {
11
RSA_PKCS1_OAEP_PADDING: 4,
12
RSA_PKCS1_PADDIN: 1,
13
RSA_NO_PADDING: 3
14
};
15
16
module.exports = function publicEncrypt(public_key, msg, reverse) {
17
var padding;
18
if (public_key.padding) {
19
padding = public_key.padding;
20
} else if (reverse) {
21
padding = 1;
22
} else {
23
padding = 4;
24
}
25
var key = parseKeys(public_key);
26
var paddedMsg;
27
if (padding === 4) {
28
paddedMsg = oaep(key, msg);
29
} else if (padding === 1) {
30
paddedMsg = pkcs1(key, msg, reverse);
31
} else if (padding === 3) {
32
paddedMsg = new bn(msg);
33
if (paddedMsg.cmp(key.modulus) >= 0) {
34
throw new Error('data too long for modulus');
35
}
36
} else {
37
throw new Error('unknown padding');
38
}
39
if (reverse) {
40
return crt(paddedMsg, key);
41
} else {
42
return withPublic(paddedMsg, key);
43
}
44
};
45
46
function oaep(key, msg){
47
var k = key.modulus.byteLength();
48
var mLen = msg.length;
49
var iHash = createHash('sha1').update(new Buffer('')).digest();
50
var hLen = iHash.length;
51
var hLen2 = 2 * hLen;
52
if (mLen > k - hLen2 - 2) {
53
throw new Error('message too long');
54
}
55
var ps = new Buffer(k - mLen - hLen2 - 2);
56
ps.fill(0);
57
var dblen = k - hLen - 1;
58
var seed = randomBytes(hLen);
59
var maskedDb = xor(Buffer.concat([iHash, ps, new Buffer([1]), msg], dblen), mgf(seed, dblen));
60
var maskedSeed = xor(seed, mgf(maskedDb, hLen));
61
return new bn(Buffer.concat([new Buffer([0]), maskedSeed, maskedDb], k));
62
}
63
function pkcs1(key, msg, reverse){
64
var mLen = msg.length;
65
var k = key.modulus.byteLength();
66
if (mLen > k - 11) {
67
throw new Error('message too long');
68
}
69
var ps;
70
if (reverse) {
71
ps = new Buffer(k - mLen - 3);
72
ps.fill(0xff);
73
} else {
74
ps = nonZero(k - mLen - 3);
75
}
76
return new bn(Buffer.concat([new Buffer([0, reverse?1:2]), ps, new Buffer([0]), msg], k));
77
}
78
function nonZero(len, crypto) {
79
var out = new Buffer(len);
80
var i = 0;
81
var cache = randomBytes(len*2);
82
var cur = 0;
83
var num;
84
while (i < len) {
85
if (cur === cache.length) {
86
cache = randomBytes(len*2);
87
cur = 0;
88
}
89
num = cache[cur++];
90
if (num) {
91
out[i++] = num;
92
}
93
}
94
return out;
95
}
96