iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 29
3
Security

資料安全與簡單加密演算法見面會 系列 第 29

[Day29] 加密演算法在支付卡的應用(個人密碼)

個人密碼是一種個人識別碼,可以讓銀行識別我們的身分,英文縮寫是PIN,是由Personal Identification Number 第一個字母組合而來,金融業應用在自動櫃員機ATM或刷卡機外接PIN Pad輸入的個人密碼

第一次使用PIN的歷史要追溯到1967年的遠古時代,位在英國倫敦的巴克萊銀行,當時他們使用PIN來驗證支票的有效性;到了1972年,遍佈英格蘭及威爾斯的Lloyds 駿懋銀行發行了第一張要驗證PIN的磁條卡片。

2006年英女王伊麗莎白二世80歲的生日宴會上,PIN和ATM的發明人James Googfellow獲頒了象徵大英帝國榮耀的OBE勳章。

個人密碼是相當隱私的資訊,只能持卡人自己保管,所以銀行或是信用卡公司也不會在資料庫儲存,因此在持卡人預借現金或是在國外走PIN來確認消費時,取而代之使用的是使用密碼驗證值PVV(PIN Verify Value)確認。

PVV的概念很像雜湊,PVV也用上了對稱金鑰加密演算法,她使用了信用卡卡號、PVKI及持卡人設定的密碼值組成的明文進行加密,並將最終步驟的結果以頭4位數值取出作為驗證比較值,就像CVV,雖然PVV運算的步驟也是國際標準,也能很輕易的Google到,但運算加密的幾把特定加密金鑰都被保護在銀行的硬體加密設備中(HSM),每個發卡銀行不同、國際組織卡種也不同,依此來加密持卡人所輸入的PIN所產生的PVV是否與磁條、晶片或是資料庫內相符。

PVV運算步驟


1.將卡號 + PVKI(第幾組金鑰) + 個人密碼組成一個16 Byte的字串。
2.將步驟3結果進行3DEA運算。
3.依序取出小於10的3位數值,若不足4位數值,則將超過10以上的字元除以10後的餘數替代。

簡單畫PVV運算的步驟圖

http://ithelp.ithome.com.tw/upload/images/20170112/20103434XzS3IITj0u.png

明文資料


卡號:11位 + PVKI:1位 + 個人密碼:4位。

  • 卡號PAN 11位: 不含最後1位檢查碼,從右邊開始取11位
  • PVKI 1位: 0-6 ,用來表示使用哪一組PVK金鑰
  • PIN 4位: 密碼值的前4位。

準備PVV驗證所需要的方法


2TDEA加密

public static byte[] TEncryption(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);
    using (MemoryStream mStream = new MemoryStream())
    {
        using (CryptoStream cStream = new CryptoStream(mStream, ict, CryptoStreamMode.Write))
        {
            cStream.Write(plainText, 0, plainText.Length);
            cStream.FlushFinalBlock();
        }
        return mStream.ToArray();
    }
}

撰寫PVV運算步驟


使用卡號5234567899876543,PVKI=1,密碼=1234進行測試!

[TestMethod]
public void TesPVVGen()
{
    //Visa Methid PVV(PVKI:1 PIN:1234)

    //PVKA + PVKB
    string Deskey = "0123456789ABCDEFFEDCBA9876543210";
    //含PIN的明文資料 (卡號:11位 + PVKI:1位 + PIN前4位)
    string plainText = "5678998765411234";

    //取得加密演算結果
    byte[] b = TEncryption(Deskey.HexToByte(), plainText.HexToByte());

    List<int> hexInt = new List<int>();
    //依序取出小於10的數字並保留大於10的數字(ABCDEF)在小於10的數字區塊右方
    for (int i = 0; i < b.BToHex().Length; i++)
    {
        int p = Convert.ToInt32(b.BToHex().Substring(i, 1), 16);
        if (p < 10)
        {
            Console.WriteLine("PVV(number) Value: {0} ", p);
        }
        else
        {
            hexInt.Add(p % 10);
        }
    }
    foreach (int p in hexInt)
    {
        Console.WriteLine("PVV(hex) Value: {0} ", p);
    }

}

http://ithelp.ithome.com.tw/upload/images/20170112/20103434cKAJCXuta5.jpg

我們可以使用BP-Tools驗證我們運算寫的是否正確?

http://ithelp.ithome.com.tw/upload/images/20170112/20103434HrFNIffBng.png

驗證通過!

PVK金鑰的保護仍是關鍵。

根據ISO7813,通常PVV都會錄製在磁軌二(track2)中,變更密碼時也會重新錄製在磁條。

參考


ISO7811、ISO7813、ISO8583

Personal identification number
https://en.wikipedia.org/wiki/Personal_identification_number


http://ithelp.ithome.com.tw/upload/images/20170112/20103434tmwLZ6e1CI.jpg

2014.12攝於Barcelona,Catalunya


上一篇
[Day28] 加密演算法在支付卡的應用(卡片末三碼)
下一篇
[Day30] 資料安全與簡單加密演算法見面會Finish
系列文
資料安全與簡單加密演算法見面會 30

尚未有邦友留言

立即登入留言