383 字
2 分鐘
[範例] Web Crypto API 轉換 Hash 值為 ASN.1 | 自然人憑證開發筆記

前一篇,講完了 RAW、DER、ASN.1,接著來動手做做看,用 JavaScript 來產生 DER 格式的 Hash。
Demo
HiPKI Local Server /sign
複習一下 HiPKI Local Server 做簽章,以下是我將 TBS字串做 SHA1,然後進行 PKCS1 簽章。
POST http://127.0.0.1:61161/signContent-Type: text/plain
tbsPackage={"tbs":"TBS","pin":"000000","signatureType":"PKCS1","hashAlgorithm":"SHA1"}透過上一篇原理將 TBS 的 SHA1 Hash 轉為DER 格式,結果為MCEwCQYFKw4DAhoFAAQU52AqDFox+uJOPeG8gd86df9UY3g=。你會發現上面兩個方法簽出來的簽章值會完全相同。至於到底要如何轉換,將會在本篇進行說明。
POST http://127.0.0.1:61161/signContent-Type: text/plain
tbsPackage={"tbs":"MCEwCQYFKw4DAhoFAAQU52AqDFox+uJOPeG8gd86df9UY3g=","pin":"000000","signatureType":"RAW"}範例程式
本範例將原文 tbs ,做完 Hash 後,轉為 DER 格式。支援 SHA1、SHA256、SHA384、SHA512。

程式碼解釋
1. 將資料轉換為 Uint8Array: 使用 TextEncoder 將文字字串 tbs 轉換為 Uint8Array,其中 tbs 是待處理的文字資料 。
const encoder = new TextEncoder();const dataUint8Array = encoder.encode(tbs);2. 計算 Hash: 使用 Web Crypto API 中的 crypto.subtle.digest 函式計算 Hash,Hash 演算法來自使用者的選擇。
crypto.subtle.digest(hash, dataUint8Array).then((hashBuffer) => {});3. 加入指定的前綴: 從先前計算的 Hash 中取得對應的前綴,然後將前綴與 Hash 值結合成一個新的 Uint8Array。
const prefix = hashPrefix[hash];const sha1Hash = new Uint8Array(hashBuffer);const prefixedData = new Uint8Array([...prefix, ...sha1Hash]);4. 將 Uint8Array 轉換為 Base64: 使用 btoa 函式將 Uint8Array 轉換為 Base64 字串。
const base64String = btoa(String.fromCharCode(...prefixedData));document.getElementById("b64Signature").value = base64String;結語
透過這邊產生的 DER,就可以到官方的RAW簽章範例進行簽章。同一個 TBS 使用 PKCS#1、RAW 簽章的結果會相同。
▶ 閱讀更多:深入淺出自然人憑證