MPOS银行卡磁条信息加密规范

1.磁条卡原始数据

 

MPOS需要保证从磁条卡满足《GBT_19584-2010_银行卡磁条信息格式和使用规范》中规定的数据格式。以二磁道为例,设备读取的磁道数据为:

;6227003390501149081=50125204813420000?

 

2.加密算法

 

磁条信息加密采用标准的DESede,双倍长密钥,ECB,NoPadding模式进行加解密。用于磁条信息加密的双倍长密钥在MPOS进行设备签到时进行获取。在进行加密前,需要将磁道数据变换为标准的ASCII码字节流,如果字节流长度不是8的整数倍,在字节流后先补一个字节0x80,然后继续补0x00直到字节流的长度为8的整数倍,最后将补位的数据进行3DES加密。

 

3.加解密的java实现:

package com.qdone;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.ArrayUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Main {

    public static void main(String[] args) throws Exception {
        // 磁道2数据
        String track2=";6227003390501149081=50125204813420000?";
        System.out.println("磁道原始数据:"+track2);
        byte[] track2Bytes=track2.getBytes("ASCII");
        // 补字节80
        track2Bytes=ArrayUtils.add(track2Bytes,(byte)0x80);
        //判断补多少字节是8的整数倍
        int pad=8-track2Bytes.length % 8;
        // 用字节0补全
        for(int i=0;i<pad;i++) {
            track2Bytes=ArrayUtils.add(track2Bytes,(byte)0x00);
        }
        String track2BytesHex=Hex.encodeHexString(track2Bytes);
        System.out.println("处理后的数据:"+track2BytesHex);
        // 磁道密钥,双倍长,32位,16字节
        String key="12345678ABCDEF00ABCDEF0012345678";
        // 将密钥变为三倍长,48位,24字节
        key=key+ key.substring(0, 16);
        byte[] keyBytes=Hex.decodeHex(key.toCharArray());
        // 构造密钥
        SecretKey keySpec = new SecretKeySpec(keyBytes, "DESede");
        // 生成加密算法
        Cipher cipher=Cipher.getInstance("DESede/ECB/NoPadding");
        // 初始化为加密模式
        cipher.init(Cipher.ENCRYPT_MODE,keySpec);
        // 加密
        byte[] encData=cipher.doFinal(track2Bytes);
        String encHex=Hex.encodeHexString(encData);
        System.out.println("磁道加密数据:"+encHex);
        // 解密
        cipher.init(Cipher.DECRYPT_MODE,keySpec);
        byte[] decData=cipher.doFinal(encData);
        String decHex=Hex.encodeHexString(decData);
        System.out.println("磁道解密数据:"+decHex);
        // 找到最后出现的80
        int idx=ArrayUtils.lastIndexOf(decData,(byte)0x80);
        // 去掉补位数据
        decData=ArrayUtils.subarray(decData,0,idx);
        // 字节流转字符串
        String track2Data=new String(decData,"ASCII");
        System.out.println("磁道原始数据:"+track2Data);
    }
}

运行后的输出:

磁道原始数据:;6227003390501149081=50125204813420000?
处理后的数据:3b363232373030333339303530313134393038313d35303132353230343831333432303030303f800000000000000000
磁道加密数据:9b9346badaab1ba09fb5174b1e49c1d669876fb57bc3731828997b61ca97050de00d35dee3ce79b8f48ab9725bb20af1
磁道解密数据:3b363232373030333339303530313134393038313d35303132353230343831333432303030303f800000000000000000
磁道原始数据:;6227003390501149081=50125204813420000?

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MAX·WOODS

感谢您的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值