上一篇笔记了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 类
CNS国家标准
Complete list of PIN-blocks
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
原文:大专栏 [.NET][C#]Parse ISO8583笔记(三)PIN Block