jsrsasign很好用但没支持sm2的椭圆曲线,可以自己加一下支持。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0; minimum-scale=1.0; maximum-scale=2.0">
<title>国密SM2的x509证书读公钥XY</title>
<style>
*{margin:0; padding:0; font-size:12px; font-family:微软雅黑;}
div{word-break: break-all; padding:10px;}
</style>
<script language="JavaScript" type="text/javascript" src="../../res/js/jsrsasign-all-min.js"></script>
<script type="text/javascript">
//基础js使用:https://kjur.github.io/jsrsasign/
//椭圆曲线参数:https://github.com/wechat-miniprogram/sm-crypto/
//html转义
//HtmlUtil.htmlEncodeByRegExp(data)
var HtmlUtil = {
/*1.用正则表达式实现html转码*/
htmlEncodeByRegExp:function (str){
var s = "";
if(str.length == 0) return "";
s = str.replace(/&/g,"&");
s = s.replace(/</g,"<");
s = s.replace(/>/g,">");
s = s.replace(/ /g," ");
s = s.replace(/\'/g,"'");
s = s.replace(/\"/g,""");
return s;
},
/*2.用正则表达式实现html解码*/
htmlDecodeByRegExp:function (str){
var s = "";
if(str.length == 0) return "";
s = str.replace(/&/g,"&");
s = s.replace(/</g,"<");
s = s.replace(/>/g,">");
s = s.replace(/ /g," ");
s = s.replace(/'/g,"\'");
s = s.replace(/"/g,"\"");
return s;
}
};
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
KJUR.crypto.ECParameterDB.regist(
"sm2p256v1", // name / p = 2^128 - 2^97 - 1
256,
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", // p
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", // a
"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", // b
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", // n
"1", // h
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", // gx
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", // gy
[], // alias
"", // oid
"sm2p256v1 : sm2"); // info
KJUR.crypto.ECDSA.getName = function(s) {
if (s === "2a811ccf5501822d") return "sm2p256v1";
if (s === "2b8104001f") return "secp192k1"; // 1.3.132.0.31
if (s === "2a8648ce3d030107") return "secp256r1"; // 1.2.840.10045.3.1.7
if (s === "2b8104000a") return "secp256k1"; // 1.3.132.0.10
if (s === "2b81040021") return "secp224r1"; // 1.3.132.0.33
if (s === "2b81040022") return "secp384r1"; // 1.3.132.0.34
if ("|secp256r1|NIST P-256|P-256|prime256v1|".indexOf(s) !== -1) return "secp256r1";
if ("|secp256k1|".indexOf(s) !== -1) return "secp256k1";
if ("|secp224r1|NIST P-224|P-224|".indexOf(s) !== -1) return "secp224r1";
if ("|secp384r1|NIST P-384|P-384|".indexOf(s) !== -1) return "secp384r1";
return null;
};
var openFile2 = function(event) { //https://www.javascripture.com/FileReader
var input = event.target;
var file = input.files[0];
if(file === undefined) return;
var name = file.name;
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function(){
var arrayBuffer = reader.result;
var text = new TextDecoder("utf-8").decode(arrayBuffer);
if(text.indexOf("-----BEGIN") != -1){
var key = KEYUTIL.getKey(text);
}
if(key == null){
var key = KEYUTIL.getKey(ArrayBuffertohex(arrayBuffer), null, "x509pub");
}
if(key == null){
alert("解析失败");
return;
}
//console.log(key);
if (!key.getPublicKeyXYHex) {
alert("证书能解析,但公钥非sm2公钥");
return;
}
var xy = key.getPublicKeyXYHex();
//console.log(xy);
//console.log(xy.x);
//console.log(xy.y);
var outputElmt = document.getElementById('output2');
var outStr = "结果:\nx:" + xy.x + "\ny:" + xy.y;
outputElmt.innerHTML = HtmlUtil.htmlEncodeByRegExp(outStr).replace(/\n/g, "<br>");
}
}
var clearResult = function() {
var outputElmt = document.getElementById('output2');
outputElmt.innerHTML = "";
}
</script>
</head>
<body>
<div>
国密SM2的x509证书读公钥XY(๑•́ωก̀๑)<br>
浏览器要求较高,建议用高版本chrome。<br>
--------------------<br>
</div>
<div>
<input type='file' onchange='openFile2(event)'> <input type="button" value="清空结果" onclick="clearResult()"/>
</div>
<div id='output2'></div>
</body>
</html>