上一篇筆記了MAC的演算法,接下來筆記PIN Block。
- MAC(ISO9807、CNS13526)
- PIN Block(ISO9564-1、CNS13798)
- ARQC/ARPC
PIN是Personal Identification Number的縮寫而來,中文為個人識別碼,金融業卡片交易應用在ATM或POS外接PIN Pad輸入的個人密碼。
- 個人密碼是相當隱私的資訊,交易設備在傳輸前就會將PIN以適當的演算法遮蓋及加密起來,也和MAC的運算類似,PIN也用上DES或3DES Encryption algorithm,透過一定期間的工作基碼(Working Key)交換(AWK/IWK),來確保機密資訊的安全性。
- 發行卡片的金融機構收到ATM/POS端授權請求後再將加密後的密碼解開進行驗證值確認。
在ISO8583中,加密後的密碼區塊放在DE(52) Element中,也稱之為PIN Block,運算方式依照國際ISO9564標準或國家CNS13798標準。
這邊先筆記加密流程,假設使用ISO9564-1 Format 0標準(ANSI X9.8, VISA-1, and ECI-0)
Step1、Step2明文準備範例:
運算元1:PIN字串組
Element | Length | Sample |
ISO9564版本 format 0 | 1 | 0 |
PIN Length(16進位) | 1 | 6 |
PIN | 4-12 | 123456 |
Padding(位數不足補F) | 2-10 | FFFFFFFF |
總長 | 16 | 06123456FFFFFFFF |
運算元2:卡號字串組
Element | Length | Sample |
fIxed character | 4 | 0000 |
card number(不含檢查碼,從右取12位) | 12 |
4567890123456789 789012345678 |
總長 | 16 | 0000789012345678 |
3.將PIN字串與卡號字串進行Exclusive OR運算: Clear PIN Block。
Item | value |
運算元1 | 06123456FFFFFFFF |
運算元2 | 0000789012345678 |
XOR結果 | 06124CC6EDCBA987 |
肉眼上的安全,但還是不安全,繼續進行加密步驟
4.執行DES加密演算法,這邊假設以2TDEA運算。
程式部分需要XOR、Hex字串轉換、字串右取功能及DES演算功能,XOR參考這篇,Hex string與 Byte[]轉換、字串右取參考這篇,TripleDES演算法參考以下:
public static byte[] Encryption(byte[] Deskey, byte[] plainText)
{
SymmetricAlgorithm TdesAlg = new TripleDESCryptoServiceProvider();
//設定基碼
TdesAlg.Key = Deskey;
//加密工作模式:CBC
TdesAlg.Mode = CipherMode.CBC;
//補充字元方式:0
TdesAlg.Padding = PaddingMode.Zeros;
//初始向量IV = 0
TdesAlg.IV = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
ICryptoTransform ict = TdesAlg.CreateEncryptor(TdesAlg.Key, TdesAlg.IV);
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, ict, CryptoStreamMode.Write);
cStream.Write(plainText, 0, plainText.Length);
cStream.FlushFinalBlock();
cStream.Close();
return mStream.ToArray();
}
產生PIN Block程式碼
public static string GenPinBlock(string CardNbr, string PIN, string keyA, string KeyB)
{
//1.運算元1:將PIN依照規範組成16進位數值字串
//(0)ISO9564 Format version(Format 0固定為0)
//(1)PIN Length(最長12,超過時截掉後面的)
//(2)PIN
//(3)Padding value "F" (Format 0 固定結尾補F)
string PinPrepare = string.Format("{0}{1}{2}{3}",
"0",
PIN.Length.ToString("X"),
PIN,
"".PadRight(16 - 2 - PIN.Length, 'F'));
//2.運算元2:將PAN依照規範組成16進位數值字串
//(0)固定0000
//(1)卡片卡號PAN(去除檢查碼)
string CardNumberPrepare = string.Format("{0}{1}",
"0000",
CardNbr.Right(12, 1));
//3.進行XOR運算
byte[] ClearPinBlockByte = XOR(PinPrepare.HexToByte(), CardNumberPrepare.HexToByte());
//4.進行3DES加密運算
byte[] EncryptPinBlockByte = Encryption((keyA + KeyB).HexToByte(), ClearPinBlockByte);
//回傳16進位字串結果
return EncryptPinBlockByte.BToHex();
}
測試程式碼:
string CardNumber = "4567890123456789";
string ClearPin = "123456";
string KeyA = "1234567890123456";
string KeyB = "0123456789012345";
string PinBlock = GenPinBlock(CardNumber, ClearPin, KeyA, KeyB);
Console.WriteLine("ISO 9564-2 Format 0 (ISO-0) Encrypt"); //與ANSI X9.8相同
Console.WriteLine("===============================");
Console.WriteLine("PAN: {0}", CardNumber);
Console.WriteLine("Clear PIN: {0}", ClearPin);
Console.WriteLine("Encrypt PIN block: {0}", PinBlock);
Console.WriteLine("");
測試結果:
小結:
- 加密PIN所使用的DEA 基碼需要定期更換,二次世界大戰德國潛艦Enigma密碼機上的每日密碼本。
- 解密流程: 先執行TripleDES解密,解密結果 XOR 運算元2:卡號字串 即可演算回 PIN字串
獵殺U571
參考:
TripleDESCryptoServiceProvider 類別
ISO 9564-1, Banking — Personal Identification Number (PIN) management and security — Part 1: Basic
principles and requirements for online PIN handling in ATM and POS systems