178 lines
5.3 KiB
JavaScript
178 lines
5.3 KiB
JavaScript
function SM2Cipher(cipherMode) {
|
||
this.ct = 1;
|
||
this.p2 = null;
|
||
this.sm3keybase = null;
|
||
this.sm3c3 = null;
|
||
this.key = new Array(32);
|
||
this.keyOff = 0;
|
||
if (typeof (cipherMode) != 'undefined') {
|
||
this.cipherMode = cipherMode
|
||
} else {
|
||
this.cipherMode = SM2CipherMode.C1C2C3//Ĭ<><C4AC>0
|
||
}
|
||
}
|
||
SM2Cipher.prototype = {
|
||
Reset : function() {
|
||
this.sm3keybase = new SM3Digest();
|
||
this.sm3c3 = new SM3Digest();
|
||
var xWords = this.GetBigIntegerByteArray(this.p2.getX().toBigInteger());
|
||
var yWords = this.GetBigIntegerByteArray(this.p2.getY().toBigInteger());
|
||
this.sm3keybase.BlockUpdate(xWords, 0, xWords.length);
|
||
this.sm3c3.BlockUpdate(xWords, 0, xWords.length);
|
||
this.sm3keybase.BlockUpdate(yWords, 0, yWords.length);
|
||
this.ct = 1;
|
||
this.NextKey()
|
||
},
|
||
NextKey : function() {
|
||
var sm3keycur = new SM3Digest(this.sm3keybase);
|
||
sm3keycur.Update((this.ct >> 24 & 0x00ff));
|
||
sm3keycur.Update((this.ct >> 16 & 0x00ff));
|
||
sm3keycur.Update((this.ct >> 8 & 0x00ff));
|
||
sm3keycur.Update((this.ct & 0x00ff));
|
||
sm3keycur.DoFinal(this.key, 0);
|
||
this.keyOff = 0;
|
||
this.ct++
|
||
},
|
||
InitEncipher : function(userKey) {
|
||
var k = null;
|
||
var c1 = null;
|
||
var ec = new KJUR.crypto.ECDSA({
|
||
"curve" : "sm2"
|
||
});
|
||
var keypair = ec.generateKeyPairHex();
|
||
k = new BigInteger(keypair.ecprvhex, 16);
|
||
var pubkeyHex = keypair.ecpubhex;
|
||
c1 = ECPointFp.decodeFromHex(ec.ecparams['curve'], pubkeyHex);
|
||
this.p2 = userKey.multiply(k);
|
||
this.Reset();
|
||
return c1
|
||
},
|
||
EncryptBlock : function(data) {
|
||
this.sm3c3.BlockUpdate(data, 0, data.length);
|
||
for (var i = 0; i < data.length; i++) {
|
||
if (this.keyOff == this.key.length) {
|
||
this.NextKey()
|
||
}
|
||
data[i] ^= this.key[this.keyOff++]
|
||
}
|
||
},
|
||
InitDecipher : function(userD, c1) {
|
||
this.p2 = c1.multiply(userD);
|
||
this.Reset()
|
||
},
|
||
DecryptBlock : function(data) {
|
||
for (var i = 0; i < data.length; i++) {
|
||
if (this.keyOff == this.key.length) {
|
||
this.NextKey()
|
||
}
|
||
data[i] ^= this.key[this.keyOff++]
|
||
}
|
||
this.sm3c3.BlockUpdate(data, 0, data.length)
|
||
},
|
||
Dofinal : function(c3) {
|
||
var yWords = this.GetBigIntegerByteArray(this.p2.getY().toBigInteger());
|
||
this.sm3c3.BlockUpdate(yWords, 0, yWords.length);
|
||
this.sm3c3.DoFinal(c3, 0);
|
||
this.Reset()
|
||
},
|
||
Encrypt : function(pubKey, tData) {
|
||
var data = new Array(tData.length);
|
||
copyArray(tData, 0, data, 0, tData.length);
|
||
var c1 = this.InitEncipher(pubKey);
|
||
this.EncryptBlock(data);
|
||
var c3 = new Array(32);
|
||
this.Dofinal(c3);
|
||
var hexString = bytesToHex(c1.getEncoded(false)) + bytesToHex(data) + bytesToHex(c3);
|
||
console.log(this.cipherMode )
|
||
if (this.cipherMode == SM2CipherMode.C1C3C2) {
|
||
hexString = bytesToHex(c1.getEncoded(false)) + bytesToHex(c3) + bytesToHex(data)
|
||
}
|
||
return hexString
|
||
},
|
||
Decrypt : function(privateKey, ciphertext) {
|
||
var hexString = ciphertext;
|
||
var c1X = hexString.substr(0, 130);
|
||
var encrypData = hexString.substr(c1X.length,
|
||
hexString.length - c1X.length - 64);
|
||
var c3 = hexString.substr(hexString.length - 64);
|
||
if (this.cipherMode == SM2CipherMode.C1C3C2) {
|
||
c3 = hexString.substr(c1X.length, 64);
|
||
encrypData = hexString.substr(c1X.length + 64)
|
||
}
|
||
var data = hexToBytes(encrypData);
|
||
var c1 = this.CreatePoint(c1X);
|
||
this.InitDecipher(privateKey, c1);
|
||
this.DecryptBlock(data);
|
||
var c3_ = new Array(32);
|
||
this.Dofinal(c3_);
|
||
var isDecrypt = bytesToHex(c3_) == c3;
|
||
// if (isDecrypt) {
|
||
// var wordArray = CryptoJS.enc.Hex.parse(this.GetHex(data).toString());
|
||
// var decryptData = CryptoJS.enc.Utf8.stringify(wordArray);
|
||
// return decryptData
|
||
// } else {
|
||
// return ''
|
||
// }
|
||
return isDecrypt ? data : null;
|
||
},
|
||
CreatePoint : function(pubkeyHex) {
|
||
var ec = new KJUR.crypto.ECDSA({
|
||
"curve" : "sm2"
|
||
});
|
||
var ecc_curve = ec.ecparams['curve'];
|
||
var point = ECPointFp.decodeFromHex(ec.ecparams['curve'], pubkeyHex);
|
||
return point
|
||
},
|
||
|
||
|
||
GetBigIntegerByteArray : function(bi) {
|
||
//BigIntger.toByteArray()תΪ<D7AA>з<EFBFBD><D0B7>ŵĶ<C5B5><C4B6><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3>˷<EFBFBD><CBB7><EFBFBD>תΪ<D7AA><EFBFBD><DEB7>ŵĶ<C5B5><C4B6><EFBFBD><EFBFBD>Ʋſ<C6B2><C5BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̨Java<76>˵ļӽ<C4BC><D3BD>ܵ<EFBFBD>Ч
|
||
var tmpd = [];
|
||
if (bi == null) {
|
||
return tmpd;
|
||
}
|
||
if (bi.toByteArray().length == 33) {
|
||
tmpd = new Array(32);
|
||
copyArray(bi.toByteArray(), 1, tmpd, 0, 32);
|
||
} else if(bi.toByteArray().length == 32) {
|
||
tmpd = bi.toByteArray();
|
||
} else {
|
||
tmpd = new Array(32);
|
||
for(var i = 0; i < 32 - bi.toByteArray().length; i++) {
|
||
tmpd[i] = 0;
|
||
}
|
||
copyArray(bi.toByteArray(), 0, tmpd, 32 - bi.toByteArray().length, bi.toByteArray().length);
|
||
}
|
||
for (var i=0; i < 32; i++) {
|
||
tmpd[i] &= 0xFF;
|
||
}
|
||
return tmpd
|
||
}
|
||
};
|
||
window.SM2CipherMode = {
|
||
C1C2C3 : '0',
|
||
C1C3C2 : '1'
|
||
};
|
||
|
||
function SM2CipherUtil() {
|
||
var cipher = new SM2Cipher();
|
||
//<2F><>ȡ<EFBFBD><C8A1>Կ<EFBFBD><D4BF>˽Կ
|
||
this.sm2GengenerateKeys = function() {
|
||
var ec = new KJUR.crypto.ECDSA({"curve": "sm2"});
|
||
var keypair = ec.generateKeyPairHex();
|
||
return {"privateKey" : keypair.ecprvhex, "publicKey" : keypair.ecpubhex};
|
||
};
|
||
this.sm2Encrypt = function(publicKey, text) {
|
||
var userKey = cipher.CreatePoint(publicKey);
|
||
var msgData = strToUtf8Bytes(text);
|
||
return cipher.Encrypt(userKey, msgData);
|
||
};
|
||
this.sm2Decrypt = function(privateKey, cipherText) {
|
||
var priKey = new BigInteger(privateKey, 16);
|
||
var data = cipher.Decrypt(priKey, cipherText);
|
||
if (!data) {
|
||
return null;
|
||
}
|
||
return bytesToUtf8Str(data);
|
||
};
|
||
} |