从信用卡轨道计算CVV?

时间:2015-12-24 17:31:33

标签: credit-card

我可以从3张信用卡追踪数据中计算出CVV吗? 当我扫描卡片时,没有CVV,只有与其他任何内容无关的数字,名称和服务号码。

参考:Parse Credit Card input from Magnetic Stripe

2 个答案:

答案 0 :(得分:3)

磁条上的CVV实际上是CVC1代码,它只会尝试验证磁条细节是否未被篡改/损坏。它与打印在卡片背面的CVV代码不同,也没有任何关联(正式称为CVC2代码。

打印在卡片背面的CVC2(按设计)仅用眼睛观看,而不是机器可读。

更多阅读:https://randomoracle.wordpress.com/2012/08/25/cvv1-cvv2-cvv3-demystifying-credit-card-data-12/

答案 1 :(得分:1)

您需要两个DES密钥(CVK),卡号,服务代码,有效期才能生成CVV。

CVV = Fun(CVK1, CVK2, card_no, service_code, expiry_YYMM);

有三个CVV

CVV1 : in magnetic stripe
CVV2 : back of card
ICVD : in chip data

每个CVV的服务代码不同

Service code for CVV1 : differs according to card type and usage 
Service code for CVV2 : 000 
Service code for ICVD : 999*

我已经实现了以下CVV生成算法

    /**
     * @param cvk1      : card verification key1
     * @param cvk2      : card verification key1
     * @param pan       : Account No
     * @param svc       : Service code CVV1(000), ICVV(999), CVV2(custom)
     * @param expiry    : Expiry date in YYMM format
     * @return          : CVV
     */
    public static final String calculateCVV(final String cvk1, final String cvk2, final String pan, final String svc, final String expiry) {
        String input = Strings.padRight(new StringBuilder().append(pan).append(expiry).append(svc), '0', 32);
        String data1 = input.substring(0, 16);
        String data2 = input.substring(16);
        String d1 = DES.encrypt(data1, cvk1, null, MODE.ECB, PADDING.NoPadding);
        String d2 = ByteHexUtil.byteToHex(ByteHexUtil.xor(ByteHexUtil.hexToByte(d1), ByteHexUtil.hexToByte(data2)));
        String d3 = TripleDES.encrypt(d2, cvk1 + cvk2, null, MODE.ECB, PADDING.NoPadding);
        return Decimalizer.decimalizeDigitsFirst(d3, 3);
    }

    public static final String decimalizeDigitsFirst(String data, final int outLen) {
        StringBuilder selected = new StringBuilder(outLen);
        int selectionCounter = 0;
        int len = data.length();
        for(int i=0; i<len && selectionCounter < outLen ; i++){
            if(hexToByte(data.charAt(i)) < 10) {
                selected.append(data.charAt(i));
                selectionCounter++;
            }
        }
        if(selectionCounter !=2) {
            for(int i=0; i<len && selectionCounter < outLen ; i++){
                if(hexToByte(data.charAt(i)) > 9) {
                    selected.append(decTable[hexToByte(data.charAt(i))]);
                    selectionCounter++;
                }
            }
        }
        return selected.toString();
    }