金融系統採用**三層密鑰體系**,實現密鑰分級管理、職責分離與合規審計:
| 密鑰類型 | 用途 | 加密算法 | 管理層級 |
|---|---|---|---|
| 主密鑰 (TMK/ZMK) | 加密下發 PIN Key、MAC Key | 3DES (ECB) | 最高,儲於 HSM,分佈保管 |
| PIN Key (TPK/PEK) | 加密 PIN Block(磁條/EMV/非接) | 3DES (ECB/CBC) | 中,主密鑰加密下發,ATM/終端內部解密使用 |
| MAC Key (TMK/MAK) | 報文完整性校驗 (ANSI X9.19) | DES/3DES (CBC-MAC) | 中,主密鑰加密下發,雙方獨立計算比對 |
// 十六進制字符串 ↔ 二進制數組
void hex2bin(unsigned char *bin, const char *hex, int hex_len);
void bin2hex(char *hex, const unsigned char *bin, int bin_len);
// 3DES ECB 模式:雙長鑰 (K1, K2, K1) 或三長鑰 (K1, K2, K3)
// iflag: 0=加密, 1=解密
void des_ecb3(const unsigned char *in, unsigned char *out,
const DES_key_schedule *ks1, const DES_key_schedule *ks2,
const DES_key_schedule *ks3, int iflag);
// 密鑰分派:16字節雙長鑰 → K1(8), K2(8), K3=K1
void setup_3des_keys(const char *hex_key, DES_key_schedule *ks1,
DES_key_schedule *ks2, DES_key_schedule *ks3) {
unsigned char key[16];
hex2bin(key, hex_key, 32);
DES_set_key_unchecked((DES_cblock*)(key + 0), ks1); // K1
DES_set_key_unchecked((DES_cblock*)(key + 8), ks2); // K2
DES_set_key_unchecked((DES_cblock*)(key + 0), ks3); // K3 = K1
}
結構:8 字節 = 1 字節長度 + 最多 12 位 PIN (每 4 位一字節) + 填充 0xF
// PIN 明文 → PIN Block 明文 (8 bytes)
void build_pin_block(const char *pin, unsigned char *pin_block) {
int len = strlen(pin);
pin_block[0] = len & 0x0F; // 低 4 位存長度
for (int i = 0; i < len; ++i) {
int idx = 1 + i/2;
int shift = (i%2 == 0) ? 4 : 0;
pin_block[idx] |= ((pin[i] - '0') & 0x0F) << shift;
}
for (int i = 1 + (len+1)/2; i < 8; ++i) pin_block[i] = 0xFF; // 填充 F
}
// PAN (主帳號) → PAN Block (8 bytes)
// 取右 12 位(不含校驗位),左補 0
void build_pan_block(const char *pan, unsigned char *pan_block) {
int len = strlen(pan);
int start = (len >= 13) ? len - 13 : 0; // 跳過校驗位
memset(pan_block, 0, 8);
pan_block[0] = 0x00; pan_block[1] = 0x00;
for (int i = 0; i < 12; ++i) {
int idx = 2 + i/2;
int shift = (i%2 == 0) ? 4 : 0;
char c = (start+i < len-1) ? pan[start+i] : '0';
pan_block[idx] |= ((c - '0') & 0x0F) << shift;
}
}
// PIN Block 明文 = PIN Block ⊕ PAN Block (逐字節異或)
void xor_blocks(const unsigned char *a, const unsigned char *b, unsigned char *out, int len) {
for (int i = 0; i < len; ++i) out[i] = a[i] ^ b[i];
}
算法流程:雙長鑰 (K1, K2) + 零向量 IV
void ansi_x919_mac(const char *hex_key, const unsigned char *data, int len, unsigned char *mac) {
DES_key_schedule ks1, ks2, ks3;
setup_3des_keys(hex_key, &ks1, &ks2, &ks3); // K1, K2, K1
unsigned char block[8], iv[8] = {0}, temp[8];
int blocks = (len + 7) / 8;
for (int i = 0; i < blocks; ++i) {
memset(block, 0, 8);
memcpy(block, data + i*8, (i == blocks-1 && len%8) ? len%8 : 8);
xor_blocks(iv, block, temp, 8);
DES_ecb_encrypt((DES_cblock*)temp, (DES_cblock*)iv, &ks1, DES_ENCRYPT);
}
DES_ecb_encrypt((DES_cblock*)iv, (DES_cblock*)temp, &ks2, DES_DECRYPT);
DES_ecb_encrypt((DES_cblock*)temp, (DES_cblock*)mac, &ks1, DES_ENCRYPT);
}
銀行密鑰體系以 **主密鑰保護工作密鑰** 為核心,配合 **ANSI X9.8 PIN Block**、**ANSI X9.19 MAC**、**3DES 雙長鑰** 標準算法,構建了經得起實戰考驗的金融安全基礎設施。理解其分層職責、數據流向、算法細節、合規要求,是支付系統、ATM/POST 終端、核心銀行系統開發人員的必修課。隨著 3DES 退役,AES-256 + GCM/CMAC 正成為新一代標準,遷移工作已在全球範圍內推進。