1. 程式人生 > >【HAVENT原創】前端使用 jsrsasign 進行 RSA 加密、解密、簽名、驗籤

【HAVENT原創】前端使用 jsrsasign 進行 RSA 加密、解密、簽名、驗籤

最近因專案需求,需要配合 JAVA 後端返回的簽名,在 H5 網頁中做驗籤功能。網上搜了一下發現了 jsrsasign 滿足需求,所以順便研究了一下 jsrsasign 。

 

首先去官網下載壓縮包,解壓後只需要引用其中的 jsrsasign-all-min.js 檔案即可。

<!--引入jsrsasign.js-->
<script src="./jsrsasign-all-min.js"></script>

初始化一下公鑰和私鑰(實際可以根據業務需求只使用公鑰或者私鑰)

        // 公鑰
        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";

假設原文內容為如下:

        // 原文
        let src = "{我是測試明文}";

 

加密、解密套餐 ( 公鑰加密,私鑰解密 ):

        // 加密
        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}`);

 

輸出結果如圖:

 

最後總結一下,在與 Java 聯調的時候要注意演算法型別是什麼,我們這次匹配的演算法就不是 SHA1withRSA 而是 MD5withRSA。另外在簽名的時候字串是不能太長的,不然會報錯,所以需要先做一次雜湊。我們後端開發是用 sha1 對原文進行雜湊,然後再用 Sha1withRSA 簽名,前端開發使用 sha1 對原文雜湊,在用 Sha1withRSA 驗籤。另外如果 Java 用 fastjson 輸出 toJsonString 會出現轉義符,小數型別預設返回是 0.0 ,JSON.Stringify 小數預設返回 0,要注意保持前端和後端的原文絕對一致!

 

附錄:

使用 jsrsasign 進行 sha1 操作

        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}`)