868 字
5 分鐘
請注意,本文編寫於 111 天前,其中某些信息可能已經過時。
🚩 國密算法格式對照表
主要格式
| 格式類型 | 描述 | 示例/特點 | 格式特點 | 適用場景 |
|---|---|---|---|---|
| HEX格式 | 十六進制字元串 | 0123456789abcdef... | • 只能包含0-9、a-f字元 • 沒有G及之後的字母 • 長度必須為偶數 • 大小寫不敏感 | 最常用,便於存儲傳輸 |
| 位元組陣列 | 二進制陣列 | [0x01, 0x23, 0x45, ...] | • 每個元素0-255 • 直接映射二進制 • 無需編碼解碼 | 程式內部處理 |
| Base64 | Base64編碼 | ASNFZ4mrze8= | • 使用A-Z、a-z、0-9、+、/ • 可能有=填充符 • 長度必須是4的倍數 | 文本傳輸 |
| Base64URL | URL安全的Base64變體 | ASNFZ4mrze8(常見無=) | • 使用A-Z、a-z、0-9、-、_ • 通常移除 =填充• 可能需解碼時補齊至4的倍數 | URL、Cookie、表單欄位 |
| PEM格式 | ASCII文本格式 | -----BEGIN PUBLIC KEY----- | • 有固定頭尾標識 • 內容是Base64編碼 • 每行最多64字元 | 標準證書格式 |
| DER格式 | 二進制編碼 | 二進制數據 | • ASN.1編碼規則 • 緊湊無冗餘 • 不可讀文本 | 緊湊存儲 |
公鑰長度格式
| 格式 | 長度 | 前綴 | 格式特點 | 說明 |
|---|---|---|---|---|
| 完整公鑰 | 130位 | 04 | • 包含完整x,y坐標 • 固定以04開頭 • 長度固定130個字元 | 未壓縮格式,相容性最好 |
| 壓縮公鑰 | 66位 | 02/03 | • 只保存x坐標 • 02表示y為偶數 • 03表示y為奇數 • 節省50%空間 | 壓縮格式,節省存儲 |
小貼士(長度換算):
- 未壓縮(Uncompressed)= 65 bytes =
0x04+ 32B X + 32B Y = 130 hex - 壓縮(Compressed)= 33 bytes =
0x02/0x03+ 32B X = 66 hex
sm-crypto 支援格式
| 演算法 | 支援格式 | 長度要求 | 技術細節 | 備註 |
|---|---|---|---|---|
| SM2 | HEX、位元組陣列 | 私鑰64位,公鑰66/130位(64+2,128+2) | • 支援公鑰壓縮 • 自動補充 04前綴• 相容多種密文模式 | 公鑰可壓縮互轉 |
| SM3 | HEX、位元組陣列 | 密鑰任意長度 | • 支援 HMAC 模式 • 輸出固定 256 位 • 建議密鑰≥256位 | 雜湊演算法 |
| SM4 | HEX、位元組陣列 | 固定128位 | • 密鑰長度嚴格 128 位 • 支援 CBC/ECB 模式 • 支援 PKCS7 填充 | 對稱加密演算法 |
格式驗證規則
| 驗證項 | HEX格式 | 位元組陣列 | 其他格式 |
|---|---|---|---|
| 字元集 | 只能0-9、a-f | 0-255整數 | 各自規範 |
| 長度檢查 | 必須偶數長度 | 任意長度 | 固定規則 |
| 大小寫 | 不敏感 | 不適用 | 敏感/不敏感 |
| 前綴檢查 | SM2公鑰需02/03/04 | 對應位元組值 | 格式標識 |
前導零與固定長度
- 私鑰 Hex 固定為 64 位,不足時須於左側補
0。 - 公鑰座標 X/Y 固定 32 bytes;十六進位表示時各自須滿 64 個字元,不足同樣左側補
0。
PEM / DER 互轉(公鑰)
# DER → PEM(公鑰)openssl ec -inform DER -in pubkey.der -pubin -outform PEM -out pubkey.pem
# PEM → DER(公鑰)openssl ec -inform PEM -in pubkey.pem -pubin -outform DER -out pubkey.der提示:PEM 是以 Base64 包裹 DER 的 ASCII 形式;互轉不改變實際金鑰內容。
實用驗證範例(TypeScript)
/** * 檢查字串是否為合法 Hex(偶數長度) */export const isHex = (s: string): boolean => /^[0-9a-fA-F]+$/.test(s) && s.length % 2 === 0;
/** * 正規化私鑰 Hex 至 64 位(左側補 0) */export const normalizePrivHex = (hex: string): string => { const s = hex.trim().toLowerCase(); if (!isHex(s)) throw new Error("Invalid hex"); return s.padStart(64, "0");};
/** * 檢測 EC 公鑰格式 * 回傳:'compressed' | 'uncompressed' | 'invalid' */export const detectEcPubKeyType = (hex: string) => { const s = hex.trim().toLowerCase(); if (!isHex(s)) return "invalid"; if (s.length === 130 && s.startsWith("04")) return "uncompressed"; if (s.length === 66 && (s.startsWith("02") || s.startsWith("03"))) return "compressed"; return "invalid";}; 🚩 國密算法格式對照表
https://illumi.love/posts/資安向/國密算法格式對照表/ 參與討論
使用 GitHub 帳號登入參與討論