最近因項目需求,須要配合 JAVA 後端返回的簽名,在 H5 網頁中作驗籤功能。網上搜了一下發現了 jsrsasign 知足需求,因此順便研究了一下 jsrsasign 。javascript
首先去官網下載壓縮包,解壓後只須要引用其中的 jsrsasign-all-min.js 文件便可。前端
<!--引入jsrsasign.js--> <script src="./jsrsasign-all-min.js"></script>
初始化一下公鑰和私鑰(實際能夠根據業務需求只使用公鑰或者私鑰)java
// 公鑰 let pk="-----BEGIN PUBLIC KEY-----\n" + "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMF4B4aDnV6j+yXiiXBYJjHM8sEgRicQ\n" + "TsRndPKocf4PyNTcd9D1046wRMdtV5cijT3oVzBXQYupN+VXmMiM7MMCAwEAAQ==\n" + "-----END PUBLIC KEY-----"; // 私鑰 let priK = "-----BEGIN PRIVATE KEY-----\n" + "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAwXgHhoOdXqP7JeKJ\n" + "cFgmMczywSBGJxBOxGd08qhx/g/I1Nx30PXTjrBEx21XlyKNPehXMFdBi6k35VeY\n" + "yIzswwIDAQABAkA+Zcj/kFlkGb05pcuwCS4gZ7pvoUoe9TqCS9/DF6LUTpFgsDlj\n" + "6AiXRng6BzlWqdn7//E/+BIInuh7Wn0q/j0hAiEA4xrWytU7EFCfilvy63oXzem2\n" + "um9fSqa4fksezyXtERECIQDaFZ0nIDdcACabh5JD7dEseqw85IMKUyfFNtLKaqog\n" + "kwIgKvg5C8eslTmr9hHPtJ41QtClskDAVu+UmNC905PpdwECIQCv4u60N49ua9C3\n" + "b0fP8WXacbWoBsSI9zgEHoszJYPAcQIhAIdENiYBXqHxVQByKZoRS4uG0UrRskxI\n" + "zMnAPlDWNOap\n" + "-----END PRIVATE KEY-----\n";
假設原文內容爲以下:git
// 原文 let src = "{我是測試明文}";
加密、解密套餐 ( 公鑰加密,私鑰解密 ):github
// 加密 let pub = KEYUTIL.getKey(pk); let enc = KJUR.crypto.Cipher.encrypt(src, pub); console.log(`公鑰加密結果:${enc}`); // console.log(hextob64(enc)); // 解密 let prv = KEYUTIL.getKey(priK); let dec = KJUR.crypto.Cipher.decrypt(enc, prv); console.log(`私鑰解密結果:${dec}`);
簽名、驗籤套餐 ( 私鑰簽名,公鑰驗籤 ):算法
// 簽名 let signature=new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:priK}); signature.updateString(src); // 簽名返回結果是16進制字符串,注意轉碼 let a = signature.sign(); let sign = hextob64(a); console.log(`私鑰簽名:${sign}`); // 驗籤 let signatureVf = new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:pk}); signatureVf.updateString(src); // 驗簽入參是16進制字符串,注意轉碼 let b = signatureVf.verify(b64tohex(sign)); console.log(`公鑰驗籤:${b}`);
輸出結果如圖:json
最後總結一下,在與 Java 聯調的時候要注意算法類型是什麼,咱們此次匹配的算法就不是 SHA1withRSA 而是 MD5withRSA。另外在簽名的時候字符串是不能太長的,否則會報錯,因此須要先作一次哈希。咱們後端開發是用 sha1 對原文進行哈希,而後再用 Sha1withRSA 簽名,前端開發使用 sha1 對原文哈希,在用 Sha1withRSA 驗籤。另外若是 Java 用 fastjson 輸出 toJsonString 會出現轉義符,小數類型默認返回是 0.0 ,JSON.Stringify 小數默認返回 0,要注意保持前端和後端的原文絕對一致!後端
附錄:app
使用 jsrsasign 進行 sha1 操做ide
let sha1 = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"}); sha1.updateString('須要sha1處理的明文字符串') let sha1Str = sha1.digest() console.log(`src: ${src}`) console.log(`sha1: ${sha1Str}`)
Here is a basic example for 'SHA1' hash calculation.
// initialize var md = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"}); // update data md.updateString('aaa') // SHA1 hash result of string aaa which will be 7e240de74fb1ed08fa08d38063f6a6a91462a815 var hashValueHex = md.digest()
You can also update a hexadecimal string as hash input.
var md = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"}); md.updateHex('5f6de0'); var hashValueHex = md.digest();
The 'updateHex' and 'updateString' method can be called one or more times.
var md = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"}); md.updateHex('9a3bcd345793173'); md.updateHex('5f6de0'); md.updateString('abcdefg'); md.updateHex('01341571fg56ab'); md.updateString('apple'); var hashValueHex = md.digest();
To update and digest in a one method you can use 'digestHex' or 'digestString' method.
var md = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"}); var hashValueHex = md.digestHex('1afcdd'); var md = new KJUR.crypto.MessageDigest({"alg": "sha1", "prov": "cryptojs"}); var hashValueHex = md.digestString('orange');
MessageDigest class supports combinations of following providers and hash algorithms.
Here is a basic example for 'SHA1withRSA' signature calculation.
// initialize var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); // initialize for signature generation sig.init(rsaPrivateKey); // rsaPrivateKey of RSAKey object // update data sig.updateString('aaa') // calculate signature var sigValueHex = sig.sign()
Here is a example for signature validation.
// initialize var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); // initialize for signature validation sig.init("-----BEGIN CERTIFICATE-----(snip)"); // signer's certificate // update data sig.updateString('aaa') // verify signature var isValid = sig.verify(sigValueHex)
You can also update a hexadecimal string as hash input.
var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); sig.init(rsaPrivateKey); sig.updateHex('5f6de0'); var sigValueHex = sig.sign()
The 'updateHex' and 'updateString' method can be called one or more times.
var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); sig.init(rsaPrivateKey); sig.updateHex('5f6de0'); sig.updateHex('9a3bcd345793173'); sig.updateHex('5f6de0'); sig.updateString('abcdefg'); sig.updateHex('01341571fg56ab'); sig.updateString('apple'); var sigValueHex = sig.sign()
To update and digest in a one method you can use 'signHex' or 'signString' method.
var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); sig.init(rsaPrivateKey); var sigValueHex = sig.signString('aaa') var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA"}); sig.init(rsaPrivateKey); var sigValueHex = sig.signHex('1bdeff')
Here is a list of supported cryptographic providers and signature algorithms.
To use Signature class following codes will be required.
<script src="http://kjur.github.io/jsrsasign/jsrsasign-latest-all-min.js"></script>