868 字
5 分鐘
🚩 國密算法格式對照表
Cover image for 🚩 國密算法格式對照表

#主要格式

格式類型描述示例/特點格式特點適用場景
HEX格式十六進制字元串0123456789abcdef...• 只能包含0-9、a-f字元
• 沒有G及之後的字母
• 長度必須為偶數
• 大小寫不敏感
最常用,便於存儲傳輸
位元組陣列二進制陣列[0x01, 0x23, 0x45, ...]• 每個元素0-255
• 直接映射二進制
• 無需編碼解碼
程式內部處理
Base64Base64編碼ASNFZ4mrze8=• 使用A-Z、a-z、0-9、+、/
• 可能有=填充符
• 長度必須是4的倍數
文本傳輸
Base64URLURL安全的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 支援格式

演算法支援格式長度要求技術細節備註
SM2HEX、位元組陣列私鑰64位,公鑰66/130位(64+2,128+2)• 支援公鑰壓縮
• 自動補充04前綴
• 相容多種密文模式
公鑰可壓縮互轉
SM3HEX、位元組陣列密鑰任意長度• 支援 HMAC 模式
• 輸出固定 256 位
• 建議密鑰≥256位
雜湊演算法
SM4HEX、位元組陣列固定128位• 密鑰長度嚴格 128 位
• 支援 CBC/ECB 模式
• 支援 PKCS7 填充
對稱加密演算法

#格式驗證規則

驗證項HEX格式位元組陣列其他格式
字元集只能0-9、a-f0-255整數各自規範
長度檢查必須偶數長度任意長度固定規則
大小寫不敏感不適用敏感/不敏感
前綴檢查SM2公鑰需02/03/04對應位元組值格式標識

#前導零與固定長度

  • 私鑰 Hex 固定為 64 位,不足時須於左側補 0
  • 公鑰座標 X/Y 固定 32 bytes;十六進位表示時各自須滿 64 個字元,不足同樣左側補 0

#PEM / DER 互轉(公鑰)

Terminal window
# 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/資安向/國密算法格式對照表/
作者
𝑰𝒍𝒍𝒖𝒎𝒊糖糖
發布於
2025-09-06
許可協議
🔒CC BY-NC-ND 4.0
💬 參與討論
使用 GitHub 帳號登入參與討論