mirror of
https://github.com/moparisthebest/mailiverse
synced 2024-11-06 17:35:04 -05:00
212 lines
7.6 KiB
JavaScript
212 lines
7.6 KiB
JavaScript
/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
|
|
*/
|
|
//
|
|
// rsa-sign.js - adding signing functions to RSAKey class.
|
|
//
|
|
//
|
|
// version: 1.2.1 (08 May 2012)
|
|
//
|
|
// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
|
|
//
|
|
// This software is licensed under the terms of the MIT License.
|
|
// http://kjur.github.com/jsrsasign/license/
|
|
//
|
|
// The above copyright and license notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
|
|
//
|
|
// Depends on:
|
|
// function sha1.hex(s) of sha1.js
|
|
// jsbn.js
|
|
// jsbn2.js
|
|
// rsa.js
|
|
// rsa2.js
|
|
//
|
|
|
|
// keysize / pmstrlen
|
|
// 512 / 128
|
|
// 1024 / 256
|
|
// 2048 / 512
|
|
// 4096 / 1024
|
|
|
|
/**
|
|
* @property {Dictionary} _RSASIGN_DIHEAD
|
|
* @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
|
|
* You can add any DigestInfo hash algorith for signing.
|
|
* See PKCS#1 v2.1 spec (p38).
|
|
*/
|
|
var _RSASIGN_DIHEAD = [];
|
|
_RSASIGN_DIHEAD['sha1'] = "3021300906052b0e03021a05000414";
|
|
_RSASIGN_DIHEAD['sha256'] = "3031300d060960864801650304020105000420";
|
|
_RSASIGN_DIHEAD['sha384'] = "3041300d060960864801650304020205000430";
|
|
_RSASIGN_DIHEAD['sha512'] = "3051300d060960864801650304020305000440";
|
|
_RSASIGN_DIHEAD['md2'] = "3020300c06082a864886f70d020205000410";
|
|
_RSASIGN_DIHEAD['md5'] = "3020300c06082a864886f70d020505000410";
|
|
_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
|
|
|
|
/**
|
|
* @property {Dictionary} _RSASIGN_HASHHEXFUNC
|
|
* @description Array of functions which calculate hash and returns it as hexadecimal.
|
|
* You can add any hash algorithm implementations.
|
|
*/
|
|
var _RSASIGN_HASHHEXFUNC = [];
|
|
_RSASIGN_HASHHEXFUNC['sha1'] = function(s){return hex_sha1(s);}; // http://pajhome.org.uk/crypt/md5/md5.html
|
|
_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
|
|
_RSASIGN_HASHHEXFUNC['sha512'] = function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
|
|
_RSASIGN_HASHHEXFUNC['md5'] = function(s){return hex_md5(s);}; // http://pajhome.org.uk/crypt/md5/md5.html
|
|
_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);}; // http://pajhome.org.uk/crypt/md5/md5.html
|
|
|
|
//_RSASIGN_HASHHEXFUNC['sha1'] = function(s){return sha1.hex(s);} // http://user1.matsumoto.ne.jp/~goma/js/hash.html
|
|
//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;} // http://user1.matsumoto.ne.jp/~goma/js/hash.html
|
|
|
|
var _RE_HEXDECONLY = new RegExp("");
|
|
_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
|
|
|
|
// ========================================================================
|
|
// Signature Generation
|
|
// ========================================================================
|
|
|
|
function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
|
|
var pmStrLen = keySize / 4;
|
|
var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
|
|
var sHashHex = hashFunc(s);
|
|
|
|
var sHead = "0001";
|
|
var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
|
|
var sMid = "";
|
|
var fLen = pmStrLen - sHead.length - sTail.length;
|
|
for (var i = 0; i < fLen; i += 2) {
|
|
sMid += "ff";
|
|
}
|
|
sPaddedMessageHex = sHead + sMid + sTail;
|
|
return sPaddedMessageHex;
|
|
}
|
|
|
|
function _zeroPaddingOfSignature(hex, bitLength) {
|
|
var s = "";
|
|
var nZero = bitLength / 4 - hex.length;
|
|
for (var i = 0; i < nZero; i++) {
|
|
s = s + "0";
|
|
}
|
|
return s + hex;
|
|
}
|
|
|
|
/**
|
|
* sign for a message string with RSA private key.<br/>
|
|
* @name signString
|
|
* @memberOf RSAKey#
|
|
* @function
|
|
* @param {String} s message string to be signed.
|
|
* @param {String} hashAlg hash algorithm name for signing.<br/>
|
|
* @return returns hexadecimal string of signature value.
|
|
*/
|
|
function _rsasign_signString(s, hashAlg) {
|
|
//alert("this.n.bitLength() = " + this.n.bitLength());
|
|
var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
|
|
var biPaddedMessage = parseBigInt(hPM, 16);
|
|
var biSign = this.doPrivate(biPaddedMessage);
|
|
var hexSign = biSign.toString(16);
|
|
return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
|
|
}
|
|
|
|
function _rsasign_signStringWithSHA1(s) {
|
|
return _rsasign_signString(s, 'sha1');
|
|
}
|
|
|
|
function _rsasign_signStringWithSHA256(s) {
|
|
return _rsasign_signString(s, 'sha256');
|
|
}
|
|
|
|
// ========================================================================
|
|
// Signature Verification
|
|
// ========================================================================
|
|
|
|
function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
|
|
var rsa = new RSAKey();
|
|
rsa.setPublic(hN, hE);
|
|
var biDecryptedSig = rsa.doPublic(biSig);
|
|
return biDecryptedSig;
|
|
}
|
|
|
|
function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
|
|
var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
|
|
var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
|
|
return hDigestInfo;
|
|
}
|
|
|
|
function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
|
|
for (var algName in _RSASIGN_DIHEAD) {
|
|
var head = _RSASIGN_DIHEAD[algName];
|
|
var len = head.length;
|
|
if (hDigestInfo.substring(0, len) == head) {
|
|
var a = [algName, hDigestInfo.substring(len)];
|
|
return a;
|
|
}
|
|
}
|
|
return [];
|
|
}
|
|
|
|
function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
|
|
var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
|
|
var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
|
|
if (digestInfoAry.length == 0) return false;
|
|
var algName = digestInfoAry[0];
|
|
var diHashValue = digestInfoAry[1];
|
|
var ff = _RSASIGN_HASHHEXFUNC[algName];
|
|
var msgHashValue = ff(sMsg);
|
|
return (diHashValue == msgHashValue);
|
|
}
|
|
|
|
function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
|
|
var biSig = parseBigInt(hSig, 16);
|
|
var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
|
|
this.n.toString(16),
|
|
this.e.toString(16));
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* verifies a sigature for a message string with RSA public key.<br/>
|
|
* @name verifyString
|
|
* @memberOf RSAKey#
|
|
* @function
|
|
* @param {String} sMsg message string to be verified.
|
|
* @param {String} hSig hexadecimal string of siganture.<br/>
|
|
* non-hexadecimal charactors including new lines will be ignored.
|
|
* @return returns 1 if valid, otherwise 0
|
|
*/
|
|
function _rsasign_verifyString(sMsg, hSig) {
|
|
hSig = hSig.replace(_RE_HEXDECONLY, '');
|
|
if (hSig.length != this.n.bitLength() / 4) return 0;
|
|
hSig = hSig.replace(/[ \n]+/g, "");
|
|
var biSig = parseBigInt(hSig, 16);
|
|
var biDecryptedSig = this.doPublic(biSig);
|
|
var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
|
|
var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
|
|
|
|
if (digestInfoAry.length == 0) return false;
|
|
var algName = digestInfoAry[0];
|
|
var diHashValue = digestInfoAry[1];
|
|
var ff = _RSASIGN_HASHHEXFUNC[algName];
|
|
var msgHashValue = ff(sMsg);
|
|
return (diHashValue == msgHashValue);
|
|
}
|
|
|
|
RSAKey.prototype.signString = _rsasign_signString;
|
|
RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
|
|
RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
|
|
RSAKey.prototype.sign = _rsasign_signString;
|
|
RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
|
|
RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
|
|
|
|
RSAKey.prototype.verifyString = _rsasign_verifyString;
|
|
RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
|
|
RSAKey.prototype.verify = _rsasign_verifyString;
|
|
RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
|
|
|
|
/**
|
|
* @name RSAKey
|
|
* @class
|
|
* @description Tom Wu's RSA Key class and extension
|
|
*/
|