c5_labsci/web/admin/demo/dyn/rsa.html
2026-01-27 00:52:00 +08:00

181 lines
7.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<link href="/jscss/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" charset="utf-8" src="/jscss/theme.js"></script>
<style>
.container>div {
padding: 1em;
background: var(--bg1);
margin-bottom: 1em;
border: 1px solid var(--bg5);
}
</style>
</head>
<body>
<div class="container">
<blockquote>生成RSA密钥对</blockquote>
<div>
需在https协议下使用原理是调用现代浏览器的Web Crypto API。
<br /><button class='btn' onclick="gen()">生成密钥对</button>
<br />-----BEGIN PRIVATE KEY-----
<br /><textarea id="rsa_prikey" style="width: 100%; height: 5em;"></textarea>
-----END PRIVATE KEY-----
<br />
<br />-----BEGIN PUBLIC KEY-----
<br /><textarea id="rsa_pubkey" style="width: 100%; height: 5em;"></textarea>
-----END PUBLIC KEY-----
</div>
<blockquote>RSA签名</blockquote>
<div>
<textarea id="rsa_data" style="width: 100%; height: 5em;">待签名数据</textarea>
<br /><button class='btn' onclick="hashData()">数据hash</button>
<br />hash:<input id="rsa_hash" type="text" style="width: 100%;" />
<br /><button class='btn' onclick="rsasignjs()">RSA 前端签名</button>
<button class='btn' onclick="rsasignback()">RSA 后端签名</button>
<br /><span id="sign_from"></span>签名:
<br /><textarea id="rsa_signature" style="width: 100%; height: 5em;"></textarea>
</div>
<blockquote>RSA验签</blockquote>
<div>
<br /><button class='btn' onclick="checksignjs()">RSA 前端验签</button>
<button class='btn' onclick="checksignback()">RSA 后端验签</button>
<div id="check_result"></div>
</div>
</div>
<script type="text/javascript" src="/jscss/ciy.js"></script>
<script type="text/javascript" src="../common.js"></script>
<script type="text/javascript">
'use strict';
function rsasignback() {
var postparam = {};
postparam.prikey = document.getElementById("rsa_prikey").value;
postparam.hash = document.getElementById("rsa_hash").value;
ciyfn.callfunc("signrsa", postparam, function (json) {
document.getElementById("rsa_signature").value = json.sign;
$5('#sign_from').html(json.from);
});
}
function checksignback() {
var postparam = {};
postparam.sign = document.getElementById("rsa_signature").value;
postparam.pubkey = document.getElementById("rsa_pubkey").value;
postparam.hash = document.getElementById("rsa_hash").value;
ciyfn.callfunc("checkrsa", postparam, function (json) {
document.getElementById("check_result").innerHTML = `php验签结果: ${json.msg}`;
});
}
async function checksignjs() {
const signature = document.getElementById("rsa_signature").value;
var publicKeyPem = document.getElementById("rsa_pubkey").value;
const hash = document.getElementById("rsa_hash").value;
publicKeyPem = publicKeyPem.replace(/(-----(BEGIN|END) PUBLIC KEY-----|-----(BEGIN|END) RSA PUBLIC KEY-----|\r|\n)/g, '');
const binaryDerString = atob(publicKeyPem);
const binaryDer = new Uint8Array(binaryDerString.length);
for (let i = 0; i < binaryDerString.length; i++) {
binaryDer[i] = binaryDerString.charCodeAt(i);
}
const publicKey = await window.crypto.subtle.importKey(
"spki",
binaryDer,
{
name: "RSASSA-PKCS1-v1_5",
hash: { name: "SHA-256" }
},
true,
["verify"]
);
const dataBuffer = hexToArrayBuffer(hash);
const signatureBuffer = hexToArrayBuffer(signature);
const result = await window.crypto.subtle.verify(
"RSASSA-PKCS1-v1_5",
publicKey,
signatureBuffer,
dataBuffer
);
document.getElementById("check_result").innerHTML = `js验签结果: ${result ? '成功' : '失败'}`;
}
async function rsasignjs() {
var privateKeyPem = document.getElementById("rsa_prikey").value;
var data = document.getElementById("rsa_hash").value;
privateKeyPem = privateKeyPem.replace(/(-----(BEGIN|END) PRIVATE KEY-----|-----(BEGIN|END) RSA PRIVATE KEY-----|\r|\n)/g, '');
const binaryDerString = atob(privateKeyPem);
const binaryDer = new Uint8Array(binaryDerString.length);
for (let i = 0; i < binaryDerString.length; i++) {
binaryDer[i] = binaryDerString.charCodeAt(i);
}
const privateKey = await window.crypto.subtle.importKey(
"pkcs8",
binaryDer,
{
name: "RSASSA-PKCS1-v1_5",
hash: { name: "SHA-256" }
},
true,
["sign"]
);
const encoder = new TextEncoder();
const dataBuffer = hexToArrayBuffer(data);
const signature = await window.crypto.subtle.sign(
"RSASSA-PKCS1-v1_5",
privateKey,
dataBuffer
);
document.getElementById("rsa_signature").value = arrayBufferToHex(signature);
$5('#sign_from').html('js');
}
function hashData() {
const data = document.getElementById("rsa_data").value;
sha256(data).then(hash => document.getElementById("rsa_hash").value = hash);
}
async function gen() {
const keyPair = await window.crypto.subtle.generateKey({
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048, // RSA-2048
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // 65537
hash: { name: "SHA-256" }
},
true,
["sign", "verify"]
);
const exportedpub = await window.crypto.subtle.exportKey("spki", keyPair.publicKey);
document.getElementById("rsa_pubkey").value = btoa(String.fromCharCode.apply(null, new Uint8Array(exportedpub)));
const exportedpri = await window.crypto.subtle.exportKey("pkcs8", keyPair.privateKey);
document.getElementById("rsa_prikey").value = btoa(String.fromCharCode.apply(null, new Uint8Array(exportedpri)));
}
async function sha256(message) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
function hexToArrayBuffer(hexString) {
const bytes = new Uint8Array(hexString.length / 2);
for (let i = 0; i < hexString.length; i += 2) {
bytes[i / 2] = parseInt(hexString.substr(i, 2), 16);
}
return bytes.buffer;
}
function arrayBufferToHex(buffer) {
return Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, '0')).join('');
}
</script>
</body>
</html>