日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js rsa验签_js rsa sign使用笔记(加密,解密,签名,验签)

發(fā)布時間:2025/3/20 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js rsa验签_js rsa sign使用笔记(加密,解密,签名,验签) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

你將會收獲:

js如何加密, 解密

js如何簽名, 驗(yàn)簽

js和Java交互如何相互解密, 驗(yàn)簽(重點(diǎn))

通過谷歌, 發(fā)現(xiàn)jsrsasign庫使用者較多. 查看api發(fā)現(xiàn)這個庫功能很健全. 本文使用方法, 是結(jié)合網(wǎng)上千篇一律的博文, 加上我自己查看源碼總結(jié)出來的.

公用代碼:

// 公鑰

let pk="-----BEGIN PUBLIC KEY-----\n" +

"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD3XSdz1MnzazBEN5KOfTx0IyVJ\n" +

"Z5wb57isrCuHDhnYXwtmdhQalgII0fozeeFpMpAvlnmHC1kpW7XVGvZnLx3bWbCE\n" +

"bf+pMSW4kmQuI+5cxRUJbCl7sdaODBrINgERHPICVC18AJLThEVMHyjuR6Jn4zQm\n" +

"yYNbReSktY/BrFTvMQIDAQAB\n" +

"-----END PUBLIC KEY-----";

// 私鑰

let priK = "-----BEGIN PRIVATE KEY-----\n" +

"MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAPddJ3PUyfNrMEQ3\n" +

"ko59PHQjJUlnnBvnuKysK4cOGdhfC2Z2FBqWAgjR+jN54WkykC+WeYcLWSlbtdUa\n" +

"9mcvHdtZsIRt/6kxJbiSZC4j7lzFFQlsKXux1o4MGsg2AREc8gJULXwAktOERUwf\n" +

"KO5HomfjNCbJg1tF5KS1j8GsVO8xAgMBAAECgYEA6eG1JMrj63jEmStmMb1txG1a\n" +

"mu4Q5z2QGgtr2HVXsIIlGEq6tWxyHf7TL4qkuz9onuYKn8n2Eqm44fZtVaBx+5ES\n" +

"zRpIvlTvaxmVu0HZ1hYAzUw1XyRnXNMKpL5tT4GCjm8+QGPzlGxgXI1sNg8r9Jaw\n" +

"9zRUYeA6LQR9RIMkHWUCQQD8QojjVoGjtiunoh/N8iplhUszZIavAEvmDIE+kVy+\n" +

"pA7hvlukLw6JMc7cfTcnHyxDo9iHVIzrWlTuKRq9KWVLAkEA+wgJS2sgtldnCVn6\n" +

"tJKFVwsHrWhMIU29msPPbNuWUD23BcKE/vehIyFu1ahNA/TiM40PEnzprQ5JfPxU\n" +

"16S78wJANTfMLTnYy7Lo7sqTLx2BuD0wqjzw9QZ4/KVytsJv8IAn65P/PVn4FRV+\n" +

"8KEx+3zmF7b/PT2nJRe/hycAzxtmlQJBAMrFwQxEqpXfoAEzx4lY2ZBn/nmaR/SW\n" +

"4VNEXCbocVC7qT1j1R5HVMgV13uKiTtq8dUGWmhqsi7x3XayNK5ECPUCQQDZaAN6\n" +

"tvIHApz9OLsXSw0jZirQ6KEYdharXbIVDy1W1sVE3lzLbqLdFp1bxAHQIvsYS5PM\n" +

"A9veSJh372RLJKkj\n" +

"-----END PRIVATE KEY-----";

// 原文

var src = "好厲害";

jsrsasign加密和解密

加密

傳入pem標(biāo)準(zhǔn)格式的秘鑰字符串, 解析生成秘鑰實(shí)例: RSAKey. 標(biāo)準(zhǔn)的pem格式秘鑰含有開始標(biāo)記和結(jié)束標(biāo)記, 如本文使用的秘鑰: -----BEGIN xxx-----, -----END xxx-----. 至于xxx的具體內(nèi)容不是太重要, 代碼里自動通過正則清洗掉頭和尾標(biāo)記, 所以真的寫成-----BEGIN xxx-----也沒有關(guān)系.

調(diào)用encrypt方法, 傳入明文和公鑰實(shí)例, 加密后的返回值是16進(jìn)制字符串.

所以, 需要將其轉(zhuǎn)為常用的Base64編碼. 如果為了方便放在URL上, 建議使用使用hextob64u(enc), 它會將+替換成-,/替換成_,去掉尾部補(bǔ)全的=. 不建議使用encodeURIComponent, 這種編碼方式會更大程度上擴(kuò)大原數(shù)據(jù)的體積(Base64只會增加1/3, 而url采用的16進(jìn)制方式, 會增加1倍, 具體原因可另外谷歌).

解密

基本類似加密流程.

// 加密

// 讀取解析pem格式的秘鑰, 生成秘鑰實(shí)例 (RSAKey)

var pub = KEYUTIL.getKey(pk);

var enc = KJUR.crypto.Cipher.encrypt(src,pub);

// console.log(enc);

// console.log(hextob64(enc));

// 解密

var prv = KEYUTIL.getKey(priK);

var dec = KJUR.crypto.Cipher.decrypt(enc,prv);

console.log("jsrsasign decrypt: "+dec);

jsrsasign簽名和驗(yàn)簽

通用流程

RSA簽名驗(yàn)簽基本流程如下, 當(dāng)然, 都會被封裝成兩個方法搞定: 簽名和驗(yàn)簽.

簽名:

指定一款摘要算法, 如sha1對原文哈希.

上述哈希前面填補(bǔ)上摘要算法標(biāo)識, 便于驗(yàn)簽時識別用的什么算法.

用rsa私鑰對上述哈希加密.

完成簽名.

驗(yàn)簽:

用rsa公鑰對簽名解密, 得到摘要.

原文取摘要.

對比兩個摘要, 一樣則驗(yàn)簽通過, 否則驗(yàn)簽不通過.

使用jsrsasign簽名驗(yàn)簽

簽名

網(wǎng)上資料很多比較雷同, 在簽名時代碼開起來比較麻煩.

這里先給出大家通常步驟, 最后給出我自己看源碼總結(jié)簡化調(diào)用方式.

方式1: 創(chuàng)建秘鑰實(shí)例 -> 構(gòu)建Signature實(shí)例 -> 傳入秘鑰實(shí)例, 初始化 -> 簽名

// 方式1: 先建立 key 對象, 構(gòu)建 signature 實(shí)例, 傳入 key 初始化 -> 簽名

var key = KEYUTIL.getKey(priK);

console.log(key);

// 創(chuàng)建 Signature 對象

let signature=new KJUR.crypto.Signature({alg:"SHA1withRSA"});

// 傳入key實(shí)例, 初始化signature實(shí)例

signature.init(key);

// 傳入待簽明文

signature.updateString(src);

// 簽名, 得到16進(jìn)制字符結(jié)果

let a = signature.sign();

let sign = hextob64(a);

console.log(sign);

方式2: 我的簡化方式: 方式1的基礎(chǔ)上, 去掉顯示讀取私鑰, 去掉初始化步驟(init(..))

// 創(chuàng)建 Signature 對象

let signature=new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:priK}); //!這里指定 私鑰 pem!

signature.updateString(src);

let a = signature.sign();

let sign = hextob64(a);

console.log(sign);

驗(yàn)簽

注意點(diǎn)看注釋.

// 驗(yàn)簽

// !要重新new 一個Signature, 否則, 取摘要和簽名時取得摘要不一樣, 導(dǎo)致驗(yàn)簽誤報失敗(原因不明)!

let signatureVf = new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:pk});

signatureVf.updateString(src);

// !接受的參數(shù)是16進(jìn)制字符串!

let b = signatureVf.verify(b64tohex(sign));

console.log("jsrsasign verify: "+b);

jsrsasign和Java交互

這是很關(guān)鍵的, 任何js插件在好用, 如果和Java不能兼容, 也是白搭. 之前就是過jsencrypt.js庫, 但是發(fā)現(xiàn)Java在簽名驗(yàn)簽時貌似不兼容.

// 解密Java的密文

var prv = KEYUTIL.getKey(priK);

// Java加密的密文(Base64Url)

let encJava = "8S2KlcygY8eUvq_Dzro81IQd6oA5fxW9l9hsy8iOvtByMMJI1wKedO5sR_pJmJFYEZl6wfD4BQ-FzvSYftnO5xO8kJaHNtnrFE7R0mqpLIkf6aN02K4F9zWLad3emFTN8Ze_GqooVaa0oX6XHqpDFBQJF3kUB6cfS9mDJNq_boE";

// 解密 / Base64Url -> 16進(jìn)制 / 私鑰實(shí)例

var dec4Java = KJUR.crypto.Cipher.decrypt(b64utohex(encJava), prv);

console.log("jsrsasign decrypt 4 java: "+dec4Java);

// 驗(yàn)證Java的簽名

// 構(gòu)建Signature實(shí)例

// 這里 prvkeypem 放公鑰pem看起來有點(diǎn)怪, 但是這是可行的, 內(nèi)部還是使用的上文經(jīng)常出現(xiàn)的 KEYUTIL.getKey(pk) 來生成公鑰實(shí)例的

var sign4Java = new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:pk});

sign4Java.updateString(src);

// Java生成簽名

var signByJava = "O6uEQFPPEmRfEiZcLQjMB7yYLpO2ohmCJvn95Izu8LveUWqFtoYJbvWRYwKCCV-Z3iurjpEw5nExvHQghwoYIxpB7p97G29WXWhfiaA0AUNlxDM2cOus-CIAq-Kyqee7vDsewp6ixaHThu0CxoPFGpBTpo5kuOFlPFR6CRS3Q9M";

var b2 = sign4Java.verify(b64utohex(signByJava));

console.log("jsrsasign verify 4 java: " + b2);

本文測試代碼的運(yùn)行結(jié)果:

jsrsasign signing: O6uEQFPPEmRfEiZcLQjMB7yYLpO2ohmCJvn95Izu8LveUWqFtoYJbvWRYwKCCV+Z3iurjpEw5nExvHQghwoYIxpB7p97G29WXWhfiaA0AUNlxDM2cOus+CIAq+Kyqee7vDsewp6ixaHThu0CxoPFGpBTpo5kuOFlPFR6CRS3Q9M=

jsrsasign verify: true

jsrsasign decrypt: 好厲害

jsrsasign decrypt 4 java: 好厲害

jsrsasign verify 4 java: true

附錄: jsrsasign部分方法源碼

本來想講測試用的源文件附上來, 但是這里貌似不支持附件, 所以部分主要的方法代碼. 通過閱讀, 加上了部分注釋, 所以api看起來更容易理解. 另外, 本文調(diào)用方式是在頁面引入js方式使用的, 若使用其他框架, 可能調(diào)用方式略有區(qū)別, 但是核心api是不變的.

/**

*

* @param l RSAKey / ECDSA / DSA / 標(biāo)準(zhǔn)的pem格式秘鑰Base64字符

* @param k

* @param n

* @returns {*}

*/

KEYUTIL.getKey = function (l, k, n) {

var G = ASN1HEX, L = G.getChildIdx, v = G.getV, d = G.getVbyList, c = KJUR.crypto, i = c.ECDSA, C = c.DSA,

w = RSAKey, M = pemtohex, F = KEYUTIL;

...

// 這里通過判斷pem結(jié)束標(biāo)記來判斷傳入的是什么類型的秘鑰字符

if (l.indexOf("-END PUBLIC KEY-") != -1) {

var O = pemtohex(l, "PUBLIC KEY");

return F._getKeyFromPublicPKCS8Hex(O)

}

if (l.indexOf("-END RSA PRIVATE KEY-") != -1 && l.indexOf("4,ENCRYPTED") == -1) {

var m = M(l, "RSA PRIVATE KEY");

return F.getKey(m, null, "pkcs5prv")

}

...

/**

*

* @param {String} e 明文

* @param {RSAKey} f 公鑰

* @param {String} d 算法名稱, 大寫, 如 RSA, 缺省 RSA

* @returns {String} 16進(jìn)制字符串

*/

KJUR.crypto.Cipher.encrypt = function (e, f, d) {

if (f instanceof RSAKey && f.isPublic) {

var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);

if (c === "RSA") {

return f.encrypt(e)

}

if (c === "RSAOAEP") {

return f.encryptOAEP(e, "sha1")

}

var b = c.match(/^RSAOAEP(\d+)$/);

if (b !== null) {

return f.encryptOAEP(e, "sha" + b[1])

}

throw"Cipher.encrypt: unsupported algorithm for RSAKey: " + d

} else {

throw"Cipher.encrypt: unsupported key or algorithm"

}

};

/**

*

* @param {String} e 16進(jìn)制密文字符串

* @param {RSAKey} f 私鑰

* @param {String} d 算法名稱, 大寫, 如 RSA, 缺省 RSA

* @returns {String} 明文

*/

KJUR.crypto.Cipher.decrypt = function (e, f, d) {

if (f instanceof RSAKey && f.isPrivate) {

var c = KJUR.crypto.Cipher.getAlgByKeyAndName(f, d);

if (c === "RSA") {

return f.decrypt(e)

}

if (c === "RSAOAEP") {

return f.decryptOAEP(e, "sha1")

}

var b = c.match(/^RSAOAEP(\d+)$/);

if (b !== null) {

return f.decryptOAEP(e, "sha" + b[1])

}

throw"Cipher.decrypt: unsupported algorithm for RSAKey: " + d

} else {

throw"Cipher.decrypt: unsupported key or algorithm"

}

};

/**

*

* @param {Object}o o.alg:算法名稱; o.prov:支持的js文件標(biāo)識; o.prvkeypem:pem格式秘鑰(base64);

* @constructor

*/

KJUR.crypto.Signature = function (o) {

var q = null;

...

/**簽名方法*/

this.sign = function () {

...

} else {

if (this.prvKey instanceof RSAKey && this.pubkeyAlgName === "rsa") {

this.hSign = this.prvKey.signWithMessageHash(this.sHashHex, this.mdAlgName)

...

總結(jié)

以上是生活随笔為你收集整理的js rsa验签_js rsa sign使用笔记(加密,解密,签名,验签)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 人妻少妇被粗大爽9797pw | 台湾佬成人中文网222vvv | 香蕉视频免费在线 | 国产二三区 | av在线免| 日韩精品一区二区三区久久 | 中文字幕有码在线视频 | 国产婷婷一区二区三区久久 | 91麻豆免费视频 | 玖玖成人| 亚洲天堂网一区 | 人妖ts福利视频一二三区 | 四季av国产一区二区三区 | 欧美少妇一级片 | 黄色大片在线免费观看 | 国产成人精品视频ⅴa片软件竹菊 | 牛av| 在线视频中文 | 性高潮久久久久久久久久 | 97香蕉碰碰人妻国产欧美 | 小嫩嫩精品导航 | 七仙女欲春2一级裸体片 | 蜜臀久久99精品久久久 | 免费的黄色小视频 | 国产不卡视频一区二区三区 | 小俊大肉大捧一进一出好爽 | 欧美日韩成人在线播放 | 久久青娱乐 | 免费观看视频一区二区 | 在线观看黄色 | 欧美中文在线观看 | 欧美片一区二区三区 | chinese hd av | 国产偷自拍| 一区二区免费在线播放 | 欧美成人黄色 | 国产宾馆自拍 | 成人动漫在线观看免费 | 久久一二三区 | 求欧美精品网址 | 国产成人高清 | 亚洲欧美第一页 | 天天爽天天干 | 丰满岳妇乱一区二区三区 | 欧美色图自拍 | 国产精品亚洲αv天堂无码 伊人性视频 | 尤物视频在线 | 日本高清www | 激情小说激情视频 | 免费在线看黄色片 | 香蕉成人网 | 人成免费 | 思思久久99 | a一级黄色 | 亚洲无毛视频 | 99精品区| 调教一区 | 在线免费观看污网站 | 国产成人小视频在线观看 | 国产精品免费视频一区二区 | 国产午夜免费视频 | 欧美激情videos | 影音先锋中文字幕资源 | 无遮挡又爽又刺激的视频 | 成人1区2区 | 亚洲免费观看高清完整 | 9色av| 青青草成人免费在线视频 | 国产日韩欧美二区 | 97超碰网 | 少妇高潮喷水在线观看 | 五月天婷婷激情网 | 啪网站| 爽妇网国产精品 | 亚洲色图网址 | 午夜大片在线观看 | 人人做人人爱人人爽 | 日本a级片在线播放 | 中文字幕1区2区 | 91蝌蚪网 | 国产精品无码中文 | 爱乃なみ加勒比在线播放 | 国产成人综合一区二区三区 | 亚洲一区二区三区蜜桃 | 2025国产精品 | 日本顶级大片 | 特黄做受又粗又大又硬老头 | 黑人操少妇 | 国产丝袜视频在线 | 顶弄h校园1v1 | 美女中文字幕 | av毛片一区| 男人的天堂97 | av黄色大片 | 婷婷视频一区 | 美女裸体网站久久久 | 秋霞毛片少妇激情免费 | av激情久久 | 亚洲一区二区三区四区不卡 |