js rsa sign using notes (encryption, decryption, signature, sign test)

You will reap:

  1. How js encryption, decryption
  2. How js signature, sign test
  3. Js how to interact with each other and Java to decrypt, verify sign (focus)

By Google, found that jsrsasignlibrary users more. Check api find this library function is perfect. As used herein, the method is a combination of online cookie-cutter stuff, plus my own view source summed up.

  • Common code:
  // 公钥
   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 encryption and decryption

encryption

  1. Incoming pem standard format string secret key, the secret key generating parse instance: RSAKey. Pem standard format containing keys 开始标记and 结束标记, as used herein, keys: -----BEGIN xxx-----, -----END xxx-----. As for the specific content is not too important xxx, automatically via a regular code cleaning U-turn and tail marks, so really written -----BEGIN xxx-----does not matter .
  2. Call encrypt, passing the public key and plaintext example, returns the encrypted value is a hexadecimal character string .
  3. Therefore, it needs to be converted to common Base64 encoding. If, for convenience on the URL, recommended the use of use hextob64u(enc), it will +replace -, /replace _, remove the tail of completion =. Do not recommend using encodeURIComponentthis coding will be greater expand the extent of the original volume data ( Base64 only increased by a third, and hexadecimal url used will be doubled, the specific reasons may additionally Google ).

Decryption

Substantially similar encryption process.

    // 加密
    // 读取解析pem格式的秘钥, 生成秘钥实例 (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 signature and signed inspection

General Process

RSA signature verification to check the basic flow, of course, will be packaged into two methods to get: test signature and check
signatures :

  1. Specify a digest algorithm, such as sha1 hash of the original text.
  2. Hash digest of the front padding on an algorithm identifier identifying the algorithm used to facilitate any sign when the test.
  3. The above-described hash is encrypted with the private key rsa.
  4. Complete the signature.

Test sign :

  1. Rsa public key to decrypt the signature used to obtain summary.
  2. Take the original summary.
  3. Summary comparison of the two, as signed by the experience, otherwise it does not pass inspection sign.

Use jsrsasign signature verification check

signature

Many compare similar information online, at the time of signing the code to open up more trouble.
Here we are usually given first step. Finally, I look at the source code to simplify the call summary way.

Method 1: Create a secret key example -> Build Signature example -> keys incoming instance, Initialization -> Signatures
    // 方式1: 先建立 key 对象, 构建 signature 实例, 传入 key 初始化 -> 签名
    var key = KEYUTIL.getKey(priK);
    console.log(key);
    // 创建 Signature 对象
    let signature=new KJUR.crypto.Signature({alg:"SHA1withRSA"}); // 传入key实例, 初始化signature实例 signature.init(key); // 传入待签明文 signature.updateString(src); // 签名, 得到16进制字符结果 let a = signature.sign(); let sign = hextob64(a); console.log(sign); 
Embodiment 2: My simplified manner: on the basis of Embodiment 1, the display read the private key is removed, remove the initialization step ( init(..))
    // 创建 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); 

Check test

Note that point of view comments.

    // 验签
    // !要重新new 一个Signature, 否则, 取摘要和签名时取得摘要不一样, 导致验签误报失败(原因不明)!
    let signatureVf = new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:pk}); signatureVf.updateString(src); // !接受的参数是16进制字符串! let b = signatureVf.verify(b64tohex(sign)); console.log("jsrsasign verify: "+b); 

jsrsasign and interact with Java

It is critical that any js easy to use plug-in, and if Java is not compatible, is no good. Prior to that through jsencrypt.jslibraries, but seemingly incompatible Java found in the signature verification check.

    // 解密Java的密文
    var prv = KEYUTIL.getKey(priK);
    // Java加密的密文(Base64Url)
    let encJava = "8S2KlcygY8eUvq_Dzro81IQd6oA5fxW9l9hsy8iOvtByMMJI1wKedO5sR_pJmJFYEZl6wfD4BQ-FzvSYftnO5xO8kJaHNtnrFE7R0mqpLIkf6aN02K4F9zWLad3emFTN8Ze_GqooVaa0oX6XHqpDFBQJF3kUB6cfS9mDJNq_boE"; // 解密 / Base64Url -> 16进制 / 私钥实例 var dec4Java = KJUR.crypto.Cipher.decrypt(b64utohex(encJava), prv); console.log("jsrsasign decrypt 4 java: "+dec4Java); // 验证Java的签名 // 构建Signature实例 // 这里 prvkeypem 放公钥pem看起来有点怪, 但是这是可行的, 内部还是使用的上文经常出现的 KEYUTIL.getKey(pk) 来生成公钥实例的 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); 

Run results of this test code:

jsrsasign signing: O6uEQFPPEmRfEiZcLQjMB7yYLpO2ohmCJvn95Izu8LveUWqFtoYJbvWRYwKCCV+Z3iurjpEw5nExvHQghwoYIxpB7p97G29WXWhfiaA0AUNlxDM2cOus+CIAq+Kyqee7vDsewp6ixaHThu0CxoPFGpBTpo5kuOFlPFR6CRS3Q9M=
jsrsasign verify: true
jsrsasign decrypt: 好厉害
jsrsasign decrypt 4 java: 好厉害
jsrsasign verify 4 java: true 

Appendix: jsrsasign source part of the method

I had wanted to talk about the source file attached to the test, but this seemingly does not support attachments, so the main part of the method code. By reading, with some of the comments, so api seems easier to understand . In addition, this method is invoked in a page js introduced method used, the use of other frameworks, might be called a slightly different, but the core api is unchanged.

/**
 * 
 * @param l RSAKey / ECDSA / DSA / 标准的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结束标记来判断传入的是什么类型的秘钥字符 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进制字符串 */ 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进制密文字符串
 * @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文件标识; 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) ...

Guess you like

Origin www.cnblogs.com/web-chuanfa/p/11096951.html