+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ async function signMessage() {
+ const message = document.getElementById("message").value;
+ const privateKeyPEM = document.getElementById("privateKey").value;
+ const statusDiv = document.getElementById("status");
+ const signatureSection = document.getElementById("signatureSection");
+ const signatureTextarea = document.getElementById("signature");
+
+ try {
+ // Extract the base64-encoded key material
+ const pemHeader = "-----BEGIN PRIVATE KEY-----";
+ const pemFooter = "-----END PRIVATE KEY-----";
+ const pemContents = privateKeyPEM
+ .substring(
+ privateKeyPEM.indexOf(pemHeader) + pemHeader.length,
+ privateKeyPEM.indexOf(pemFooter),
+ )
+ .replace(/\s/g, "");
+
+ // Convert base64 to binary
+ const binaryDer = str2ab(atob(pemContents));
+
+ // Import the key
+ const cryptoKey = await window.crypto.subtle.importKey(
+ "pkcs8",
+ binaryDer,
+ {
+ name: "RSASSA-PKCS1-v1_5",
+ hash: "SHA-256",
+ },
+ false,
+ ["sign"],
+ );
+
+ // Sign the message
+ const encoder = new TextEncoder();
+ const data = encoder.encode(message);
+ const signature = await window.crypto.subtle.sign(
+ "RSASSA-PKCS1-v1_5",
+ cryptoKey,
+ data,
+ );
+
+ // Convert to base64
+ const signatureBase64 = btoa(
+ String.fromCharCode(...new Uint8Array(signature)),
+ );
+
+ signatureSection.style.display = "block";
+ signatureTextarea.value = signatureBase64;
+
+ statusDiv.className = "success";
+ statusDiv.textContent = "Message signed successfully!";
+ } catch (error) {
+ statusDiv.className = "error";
+ statusDiv.textContent = `Error signing message: ${error.message}`;
+ signatureSection.style.display = "none";
+ }
+ }
+
+ // Helper function to convert string to ArrayBuffer
+ function str2ab(str) {
+ const buf = new ArrayBuffer(str.length);
+ const bufView = new Uint8Array(buf);
+ for (let i = 0, strLen = str.length; i < strLen; i++) {
+ bufView[i] = str.charCodeAt(i);
+ }
+ return buf;
+ }
+
+
+