[.NET][C#]Parse ISO8583笔记(三)PIN Block

上一篇笔记了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


猜你喜欢

转载自www.cnblogs.com/petewell/p/11518104.html
今日推荐