妹妹別這樣!
868 字
5 分鐘
🚩 國密算法格式對照表

主要格式
格式類型 | 描述 | 示例/特點 | 格式特點 | 適用場景 |
---|---|---|---|---|
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 帳號登入參與討論