あなたは刈り取ります:
- どのようにJSの暗号化、復号化
- どのようにJS署名、符号検定
- 記号(フォーカス)を確認し、復号化するためにお互いとJavaと対話する方法JS
Googleが、ことがわかったjsrsasign
ライブラリ、ユーザーがより多くの。APIは、このライブラリ関数は完璧です見つける確認してください。ここで使用されるように、この方法は、オンラインの組み合わせであるクッキーカッターのものに加えて、私自身のソースの表示をまとめました。
- 共通のコード:
// 公钥
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標準フォーマットストリング秘密鍵、秘密鍵生成解析インスタンス:
RSAKey
。キーを含むPEM標準フォーマット开始标记
と结束标记
、本明細書中で使用される、キー:-----BEGIN xxx-----
、-----END xxx-----
。特定のコンテンツのために定期的なコードを介して自動的に、あまりにも重要XXXないようUターンとテールマーク、そう本当に書かを清掃することは-----BEGIN xxx-----
重要ではありません。 - 呼び出し
encrypt
公開鍵と平文の例を渡して、暗号化された値が返されます16進文字列。 - したがって、それは一般的なBase64エンコーディングに変換する必要があります。URL上の便宜のために、場合推奨使用の使用を
hextob64u(enc)
、それがされます+
置き換える-
、/
置き換え_
、完了の尾を取り除く=
。お勧めしない使用してencodeURIComponent
、このコーディングを大きくなります元のボリュームのデータの範囲を拡大する(Base64でのみ第三の増加、及び使用進URLが倍増され、具体的な理由は、追加のGoogle)。
復号化
実質的に同様の暗号化プロセス。
// 加密
// 读取解析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署名と署名された検査
一般的なプロセス
テスト署名と確認:RSA署名検証は、もちろん、取得するための二つの方法にパッケージされ、基本的な流れを確認する
署名を。
- そのような元のテキストのSHA1ハッシュとして、ダイジェストアルゴリズムを指定します。
- ハッシュ兆候テストを容易にするために使用されるアルゴリズムを特定するアルゴリズム識別子にフロントパディングのダイジェスト。
- 上記のハッシュは秘密鍵RSAで暗号化されています。
- 署名を完了します。
テスト記号:
- 要約を取得するために使用される署名を復号化するRSA公開鍵。
- オリジナルの要約を取ります。
- 経験によって署名されたように、2つの要約比較は、それ以外の場合は、検査記号を渡しません。
jsrsasign署名検証チェックを使用します
署名
多くは、より多くのトラブルを開くために、コードに署名する時には、オンラインの同様の情報を比較する。
ここでは、通常、最初の一歩を与えられている。最後に、私は、コールサマリー方法を簡素化するため、ソースコードを見てください。
方法1:秘密鍵の例を作成します - >署名の例をビルド - >インスタンスを着信キー、初期設定 - >署名
// 方式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);
実施例2:私の簡略化:実施例1に基づいて、ディスプレイはプライベート鍵が除去される読み取り、(初期化ステップを削除します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);
テストをチェック
ビューのコメントのその点を注意してください。
// 验签
// !要重新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とJavaとの対話
簡単に任意のJSプラグインを使用することが重要である、とJavaは互換性がない場合、何も良い。を通じてそれ以前であるjsencrypt.js
図書館、一見相容れないJavaは、署名の検証チェックに見つかりませんでした。
// 解密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);
このテストコードの実行結果:
jsrsasign signing: O6uEQFPPEmRfEiZcLQjMB7yYLpO2ohmCJvn95Izu8LveUWqFtoYJbvWRYwKCCV+Z3iurjpEw5nExvHQghwoYIxpB7p97G29WXWhfiaA0AUNlxDM2cOus+CIAq+Kyqee7vDsewp6ixaHThu0CxoPFGpBTpo5kuOFlPFR6CRS3Q9M=
jsrsasign verify: true
jsrsasign decrypt: 好厉害
jsrsasign decrypt 4 java: 好厉害
jsrsasign verify 4 java: true
付録:メソッドのjsrsasignソース部分
私はテストに添付のソースファイルについて話をしたかったが、これは一見、添付ファイル、そのメソッドのコードの主要な部分をサポートしていません。コメントのいくつかと、読み取ることにより、そのAPIが理解しやすいようです。また、この方法は、ページに呼び出されます使用方法を紹介しjsが、他のフレームワークの使用は、若干異なると呼ばれるかもしれないが、コアAPIは変更されません。
/**
*
* @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) ...