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

首頁 > 系列文 > 自然人憑證開發筆記

前一篇,講完了 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/sign
Content-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/sign
Content-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 簽章的結果會相同。

▶ 閱讀更多:深入淺出自然人憑證