blob: 645bf28c48a6de3cc3740bd8fc6e47349cf6f83e [file] [log] [blame]
Meki Cherkaoui88d59cd2012-05-14 07:34:58 -07001/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
2 */
3//
4// rsa-sign.js - adding signing functions to RSAKey class.
5//
6//
7// version: 1.2.1 (08 May 2012)
8//
9// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
10//
11// This software is licensed under the terms of the MIT License.
12// http://kjur.github.com/jsrsasign/license/
13//
14// The above copyright and license notice shall be
15// included in all copies or substantial portions of the Software.
16
17//
18// Depends on:
19// function sha1.hex(s) of sha1.js
20// jsbn.js
21// jsbn2.js
22// rsa.js
23// rsa2.js
24//
25
26// keysize / pmstrlen
27// 512 / 128
28// 1024 / 256
29// 2048 / 512
30// 4096 / 1024
31
32/**
33 * @property {Dictionary} _RSASIGN_DIHEAD
34 * @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
35 * You can add any DigestInfo hash algorith for signing.
36 * See PKCS#1 v2.1 spec (p38).
37 */
38var _RSASIGN_DIHEAD = [];
39_RSASIGN_DIHEAD['sha1'] = "3021300906052b0e03021a05000414";
40_RSASIGN_DIHEAD['sha256'] = "3031300d060960864801650304020105000420";
41_RSASIGN_DIHEAD['sha384'] = "3041300d060960864801650304020205000430";
42_RSASIGN_DIHEAD['sha512'] = "3051300d060960864801650304020305000440";
43_RSASIGN_DIHEAD['md2'] = "3020300c06082a864886f70d020205000410";
44_RSASIGN_DIHEAD['md5'] = "3020300c06082a864886f70d020505000410";
45_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
46
47/**
48 * @property {Dictionary} _RSASIGN_HASHHEXFUNC
49 * @description Array of functions which calculate hash and returns it as hexadecimal.
50 * You can add any hash algorithm implementations.
51 */
52var _RSASIGN_HASHHEXFUNC = [];
53_RSASIGN_HASHHEXFUNC['sha1'] = function(s){return hex_sha1(s);}; // http://pajhome.org.uk/crypt/md5/md5.html
54_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
55_RSASIGN_HASHHEXFUNC['sha512'] = function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
56_RSASIGN_HASHHEXFUNC['md5'] = function(s){return hex_md5(s);}; // http://pajhome.org.uk/crypt/md5/md5.html
57_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);}; // http://pajhome.org.uk/crypt/md5/md5.html
58
59//_RSASIGN_HASHHEXFUNC['sha1'] = function(s){return sha1.hex(s);} // http://user1.matsumoto.ne.jp/~goma/js/hash.html
60//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;} // http://user1.matsumoto.ne.jp/~goma/js/hash.html
61
62var _RE_HEXDECONLY = new RegExp("");
63_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
64
65// ========================================================================
66// Signature Generation
67// ========================================================================
68
69function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
70 var pmStrLen = keySize / 4;
71 var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
72 var sHashHex = hashFunc(s);
73
74 var sHead = "0001";
75 var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
76 var sMid = "";
77 var fLen = pmStrLen - sHead.length - sTail.length;
78 for (var i = 0; i < fLen; i += 2) {
79 sMid += "ff";
80 }
81 sPaddedMessageHex = sHead + sMid + sTail;
82 return sPaddedMessageHex;
83}
84
85
86//@author: ucla-cs
87function _rsasign_getHexPaddedDigestInfoForStringHEX(s, keySize, hashAlg) {
88 var pmStrLen = keySize / 4;
89 var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
90 var sHashHex = hashFunc(s);
91
92 var sHead = "0001";
93 var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
94 var sMid = "";
95 var fLen = pmStrLen - sHead.length - sTail.length;
96 for (var i = 0; i < fLen; i += 2) {
97 sMid += "ff";
98 }
99 sPaddedMessageHex = sHead + sMid + sTail;
100 return sPaddedMessageHex;
101}
102
103function _zeroPaddingOfSignature(hex, bitLength) {
104 var s = "";
105 var nZero = bitLength / 4 - hex.length;
106 for (var i = 0; i < nZero; i++) {
107 s = s + "0";
108 }
109 return s + hex;
110}
111
112/**
113 * sign for a message string with RSA private key.<br/>
114 * @name signString
115 * @memberOf RSAKey#
116 * @function
117 * @param {String} s message string to be signed.
118 * @param {String} hashAlg hash algorithm name for signing.<br/>
119 * @return returns hexadecimal string of signature value.
120 */
121function _rsasign_signString(s, hashAlg) {
122 //alert("this.n.bitLength() = " + this.n.bitLength());
123 var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
124 var biPaddedMessage = parseBigInt(hPM, 16);
125 var biSign = this.doPrivate(biPaddedMessage);
126 var hexSign = biSign.toString(16);
127 return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
128}
129
130//@author: ucla-cs
131function _rsasign_signStringHEX(s, hashAlg) {
132 //alert("this.n.bitLength() = " + this.n.bitLength());
133 var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
134 var biPaddedMessage = parseBigInt(hPM, 16);
135 var biSign = this.doPrivate(biPaddedMessage);
136 var hexSign = biSign.toString(16);
137 return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
138}
139
140
141function _rsasign_signStringWithSHA1(s) {
142 return _rsasign_signString(s, 'sha1');
143}
144
145function _rsasign_signStringWithSHA256(s) {
146 return _rsasign_signString(s, 'sha256');
147}
148
149// ========================================================================
150// Signature Verification
151// ========================================================================
152
153function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
154 var rsa = new RSAKey();
155 rsa.setPublic(hN, hE);
156 var biDecryptedSig = rsa.doPublic(biSig);
157 return biDecryptedSig;
158}
159
160function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
161 var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
162 var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
163 return hDigestInfo;
164}
165
166function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
167 for (var algName in _RSASIGN_DIHEAD) {
168 var head = _RSASIGN_DIHEAD[algName];
169 var len = head.length;
170 if (hDigestInfo.substring(0, len) == head) {
171 var a = [algName, hDigestInfo.substring(len)];
172 return a;
173 }
174 }
175 return [];
176}
177
178function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
179 var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
180 var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
181 if (digestInfoAry.length == 0) return false;
182 var algName = digestInfoAry[0];
183 var diHashValue = digestInfoAry[1];
184 var ff = _RSASIGN_HASHHEXFUNC[algName];
185 var msgHashValue = ff(sMsg);
186 return (diHashValue == msgHashValue);
187}
188
189function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
190 var biSig = parseBigInt(hSig, 16);
191 var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
192 this.n.toString(16),
193 this.e.toString(16));
194 return result;
195}
196
197/**
198 * verifies a sigature for a message string with RSA public key.<br/>
199 * @name verifyString
200 * @memberOf RSAKey#
201 * @function
202 * @param {String} sMsg message string to be verified.
203 * @param {String} hSig hexadecimal string of siganture.<br/>
204 * non-hexadecimal charactors including new lines will be ignored.
205 * @return returns 1 if valid, otherwise 0
206 */
207function _rsasign_verifyString(sMsg, hSig) {
208 hSig = hSig.replace(_RE_HEXDECONLY, '');
209
210 if(LOG>3)console.log('n is '+this.n);
211 if(LOG>3)console.log('e is '+this.e);
212
213 if (hSig.length != this.n.bitLength() / 4) return 0;
214 hSig = hSig.replace(/[ \n]+/g, "");
215 var biSig = parseBigInt(hSig, 16);
216 var biDecryptedSig = this.doPublic(biSig);
217 var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
218 var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
219
220 if (digestInfoAry.length == 0) return false;
221 var algName = digestInfoAry[0];
222 var diHashValue = digestInfoAry[1];
223 var ff = _RSASIGN_HASHHEXFUNC[algName];
224 var msgHashValue = ff(sMsg);
225 return (diHashValue == msgHashValue);
226}
227
228RSAKey.prototype.signString = _rsasign_signString;
229
230RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
231RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
232RSAKey.prototype.sign = _rsasign_signString;
233RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
234RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
235
236
237/*RSAKey.prototype.signStringHEX = _rsasign_signStringHEX;
238RSAKey.prototype.signStringWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
239RSAKey.prototype.signStringWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
240RSAKey.prototype.signHEX = _rsasign_signStringHEX;
241RSAKey.prototype.signWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
242RSAKey.prototype.signWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
243*/
244
245
246RSAKey.prototype.verifyString = _rsasign_verifyString;
247RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
248RSAKey.prototype.verify = _rsasign_verifyString;
249RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
250
251/*
252RSAKey.prototype.verifyStringHEX = _rsasign_verifyStringHEX;
253RSAKey.prototype.verifyHexSignatureForMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
254RSAKey.prototype.verifyHEX = _rsasign_verifyStringHEX;
255RSAKey.prototype.verifyHexSignatureForByteArrayMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
256*/
257
258
259/**
260 * @name RSAKey
261 * @class
262 * @description Tom Wu's RSA Key class and extension
263 */