银行密钥体系

银行系统的密钥有三种,主密钥/pinkey/Mackey,其中pinkey是用来加密密码的,而mackey是用来校验报文是否有错码,主密钥是用来加密pinkey和mackey的.

其中主密钥加密pinkey和mackey是是用3des来加解密的

代码如下:

/*
param:
    pKey:密钥(十六进制)
    strPlainAKey:需要加解密的字符串(十六进制)
    ciperAKey:返回值
    iflag:1解密 0加密
*/
void getCiper(char* pKey, char* strPlainAKey, char* ciperAKey,  int iflag)
{
    unsigned char binPlainAKey[64] = {0};
    hex2binary(binPlainAKey, strPlainAKey, strlen(strPlainAKey));
    ASCIIStr2BinCharStrBy3DES(pKey,(unsigned char*)binPlainAKey,strlen(strPlainAKey)/2, (unsigned char*)ciperAKey, iflag);
}

/*
param:
    pKey:密钥(十六进制)
    inBinary:加解密字符串的字节形式
    inLen:加解密字符串的长度
    binCharString:返回值
    iflag:1解密 0加密
*/
void ASCIIStr2BinCharStrBy3DES(char* pKey, unsigned char* inBinary, int inLen, unsigned char* binCharString,int iflag)
{
    unsigned char targetIdBin[DESBINARY_LEN] = {0}; //TargetIdLen=8
    // 3DES encription
    unsigned char key[LEN_OF_KEY];
    unsigned char block_key[9];
    memset(key, 0, LEN_OF_KEY);
    hex2binary(key, pKey, strlen(pKey));
    DES_key_schedule ks,ks2,ks3;

    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, key + 0, 8);
    DES_set_key_unchecked((const_DES_cblock*)block_key, &ks);
    memcpy(block_key, key + 8, 8);
    DES_set_key_unchecked((const_DES_cblock*)block_key, &ks2);
    memcpy(block_key, key + 0, 8);
    DES_set_key_unchecked((const_DES_cblock*)block_key, &ks3); 

    unsigned char input[8];
    memset(input, 0, sizeof(input));
    unsigned char encryptedOutBinary[DESBINARY_LEN];
    memset(encryptedOutBinary, 0, sizeof(encryptedOutBinary));
    for(int i=0; i<inLen/8; i++)
    {
        memset(targetIdBin, 0, sizeof(targetIdBin));
        memcpy((void*)targetIdBin, (const void*)(inBinary+i*8), 8);
        DES_ecb3_encrypt((const_DES_cblock*)targetIdBin, (DES_cblock*)encryptedOutBinary, &ks, &ks2, &ks3, iflag);
        binary2char((char*)binCharString+i*16, encryptedOutBinary, DESBINARY_LEN);
    }
}

//
// A public function: convert binary string to character string, the character string‘s length = 2 // binary string.
// @param charArray: character array. output.
// @param binArray: binary array. input.
// @param binLen: length of binary array.
//
void binary2char(char* charArray, const unsigned char* binArray, int binLen)
{
        int i;
        for(i = 0; i < binLen; i++)
        {
                sprintf(charArray + 2*i, "%02X", binArray[i]);
        }
        charArray[2*i] = ‘\0‘;
}

//
// A public function: convert hex string to binary string, the hex string‘s length = 2 * binary string.
// @param binArray: binary array. output.
// @param hexCharArray: character array contains hex string. input.
// @param hexLen: length of hex string array. input.
//
void hex2binary(unsigned char* binArray, const char* hexCharArray, int hexLen)
{
        if (hexLen%2 != 0)
        {
            printf("hex2binary(): length of input parameter hexCharArray should be even number!\n");
            return;
        }

        int i, j;
        //convert two hex chars to one byte
        char atom[2 + 1] = "\0";
        for (i = 0, j = 0; i < hexLen/2; i++, j+=2)
        {
            strncpy(atom, hexCharArray + j, sizeof(atom) - 1);
            atom[sizeof(atom) - 1] = ‘\0‘;
            binArray[i] = (unsigned char)strtol(atom, NULL, 16);
        }
}

一般来说,ATM拿到pinkey密文会使用主密钥解密,得到pinkey明文,然后是用帐号+密码生成pinblock明文,然后使用pinkey使用3des加密,然后传给后端

生成pinblock明文的算法为:

char uniteBytes(char a,char b)
{
    char c = (int(a-‘0‘)<<4)+b-‘0‘;
    return c;
}
/**
    * getHPin
    * 对密码进行转换
    * PIN格式
    * BYTE 1 PIN的长度
    * BYTE 2 – BYTE 3/4/5/6/7 4--12个PIN(每个PIN占4个BIT)
    * BYTE 4/5/6/7/8 – BYTE 8 FILLER “F” (每个“F“占4个BIT)
    * @param pin String
    * @return byte[]
    */
void getHPin(char* pin, char* encode)
{
    encode[0] = 6;
    encode[1] = uniteBytes(pin[0], pin[1]);
    encode[2] = uniteBytes(pin[2], pin[3]);
    encode[3] = uniteBytes(pin[4], pin[5]);
    encode[4] = 255;
    encode[5] = 255;
    encode[6] = 255;
    encode[7] = 255;
}

    /**
    * getHAccno
    * 对帐号进行转换
    * BYTE 1 — BYTE 2 0X0000
    * BYTE 3 — BYTE 8 12个主帐号
    * 取主帐号的右12位(不包括最右边的校验位),不足12位左补“0X00”。
    * @param accno String
    * @return byte[]
    */
char* getHAccno(char* accno,char* encode)
{
    int len = strlen(accno);
    int beginPos = len < 13 ? 0 : len - 13;
    char arrTemp[13] = {0};
    memcpy(arrTemp, accno+beginPos, len-beginPos-1);
    char arrAccno[12];
    for(int i=0; i<12; i++)
    {
    arrAccno[i] = (i <= strlen(arrTemp) ? arrTemp[i] : 0);
    }

    encode[0] = 0;
    encode[1] = 0;
    encode[2] = uniteBytes(arrAccno[0], arrAccno[1]);
    encode[3] = uniteBytes(arrAccno[2], arrAccno[3]);
    encode[4] = uniteBytes(arrAccno[4], arrAccno[5]);
    encode[5] = uniteBytes(arrAccno[6], arrAccno[7]);
    encode[6] = uniteBytes(arrAccno[8], arrAccno[9]);
    encode[7] = uniteBytes(arrAccno[10], arrAccno[11]);
    return encode;
}

/**
    * getPinBlock
    * 标准ANSI X9.8 Format(带主帐号信息)的PIN BLOCK计算
    * PIN BLOCK 格式等于 PIN 按位异或 主帐号;
    * @param pin String
    * @param accno String
    * @return byte[]
    */
void process(char* pin, char* accno,char* pHexRet)
{
    char arrAccno[128]={0};
    getHAccno(accno,arrAccno);
    char arrPin[128]={0};
    getHPin(pin, arrPin);
    unsigned char arrRet[8]={0};
    for(int i=0; i<8; i++){
    arrRet[i] = (unsigned char)(arrPin[i] ^ arrAccno[i]);
    }

    binary2char(pHexRet, arrRet, 8);
}

Mac运算:

ATM拿到mackey,通过主密钥解密得到密钥明文,使用一串双方协议好的macdata格式,通过ANSI 9.19得到macblock,随报文发到后端,后端也会做同样的操作,然后比对,得到校验结果

Ansi 9.19的算法如下

void xor(unsigned char *input1,unsigned char *input2,unsigned char *output,int len)
{
    while (len) {
        *output++=*input1++^*input2++;
        len--;
    }
}

/*
*@brief: 根据输入数据计算MAC,初始IV向量默认为"x00x00x00x00x00x00x00x00"
*@param: sMacKey 密钥
*@param: pInData 输入数据
*@param: pRetData 计算出来的MAC
*@调用自定义xor和des函数
*/

void MacArithmetic(char *sMacKey,char *inBinary,char *pRetData)
{
//MAC算法:
//将字符串pInata分为8字节为单位的数据块,不足补x00,分别标号为D1,D2,D3,...,Dn
//设置初始向量E0="x00x00x00x00x00x00x00x00"
//将E0^D1 —---->E1(E0,D1异或的后结果经使用密钥左8位des加密得到E1)
//将E1^D2 ----->E2
//如此类推,知道得出En结束,
//使用密钥右8位des解密En得到En0
//使用密钥左8位加密En0得到En1
//En1即是计算出来的MAC

    unsigned char sUpData[512];
    unsigned char sData[20];
    unsigned char sXorData[20];
    unsigned char sDesData[20];
    int i,n,iNum,iInLen;

    unsigned char key[16];
    unsigned char block_key[9];
    iInLen=strlen(inBinary);
    memset(key, 0, sizeof(key));
    hex2binary(key, sMacKey, strlen(sMacKey));
    DES_key_schedule ks,ks2,ks3;

    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, key + 0, 8);
    DES_set_key_unchecked((const_DES_cblock*)block_key, &ks);
    memcpy(block_key, key + 8, 8);
    DES_set_key_unchecked((const_DES_cblock*)block_key, &ks2);
    memcpy(block_key, key + 0, 8);
    DES_set_key_unchecked((const_DES_cblock*)block_key, &ks3); 

    memset(sUpData,0,sizeof(sUpData));
    memset(sData,0,sizeof(sData));
    memset(sXorData,0,sizeof(sXorData));
    memset(sDesData,0,sizeof(sDesData));

//补全要加密数据成8倍数到sUpData,不足补x00
    memcpy(sUpData,inBinary,iInLen);
    iNum = iInLen%8;
    if (iNum == 0)
        n=iInLen/8;
    else {
        n=iInLen/8+1;
        memcpy(sUpData+iInLen,"\0\0\0\0\0\0\0\0",8-iNum);
    }

    printf("n=%dnsUpData=[%s]n",n,sUpData);

    memset(sDesData,0,sizeof(sDesData)); //初始向量赋给sDesData
    for (i=0;i<n;i++) {
        memcpy(sData,sUpData+i*8,8);
        xor(sDesData,sData,sXorData,8); //异或
        DES_ecb_encrypt((const_DES_cblock*)sXorData, (DES_cblock*)sDesData, &ks,1);
    }
    DES_ecb_encrypt((const_DES_cblock*)sDesData, (DES_cblock*)sXorData, &ks2,0);
    DES_ecb_encrypt((const_DES_cblock*)sXorData, (DES_cblock*)sDesData, &ks,1);

    binary2char(pRetData, sDesData, 8);

    return ;
}

银行密钥体系

时间: 2024-10-16 20:25:09

银行密钥体系的相关文章

金融行业密钥体系介绍(转)

金融行业因为对数据比较敏感,所以对数据的加密也相应的重视.在其中有关密钥及加密方面的文章很少,并且散发在各个银行及公司的手中,在网上没有专门对这部分进行介绍的文章.本文对金融行业的密钥进行较深入的介绍,包括像到底什么是主密钥(MasterKey).传输密钥(MacKey),为什么我们需要这些东西等. 本文采取追源溯本的方式,力求让对这些感兴趣的人达到知其然,同时也知其所以然,而不是模模糊糊的知道几个概念和名词.因为本文主要是针对那些对金融行业的密钥体系不是很熟悉的人,所以如果你对密钥很熟悉就不必

密钥体系

1.一级的三个主控密钥(ARQC KEY),(安全报文MAC KEY),(PIN加密KEY),都是16字节长.银行控制 2.二级的三个应用子密钥(一般是L[8000]给的明文),也是16字节长度,分别由三个一级的主密钥分散得来的,是与具体的卡(BIN号的后7个字节+5F34(一般是00或01)组成分散因子),根据具体的算法得来的.这是卡片级别的,最终存储在卡片的安全区域. 3.具体的行业应用的ADF的应用主密钥

转:一个计算机专业毕业的银行员工工作感受

先介绍一下我国现在整个银行业及和它相关的行业(证券,保险,IT业)的一些大概情况. 最近几年是我国银行业改革的关键几年,因为2005年我国金融业将全面开放,外资银行将和中国的银行展开全面的竞争.外资银行在管理水平.金融创新能力方面要优于我们.所以,我国的银行只能利用这点时间,积极改革,加快自身的发展,尽快形成自己的核心竞争力. 我国的银行体系如下: 中国人民银行(央行)------执行国家货币政策,发行并控制货币,为其他商业银行提供贷款,作为最后贷款人来稳定金融市场 银监会------对整个银行

浅谈IM软件业务知识——非对称加密,银行U盾的原理

概述 首先了解一下相关概念:RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数论:将两个大素数相乘非常容易,但要对这个乘积的结果进行 因式分解却非常困难,因此可以把乘积公开作为公钥,该算法能够抵抗目前已知的所有密码攻击.RSA算法是一种非对称算法,算法需要一对密钥,使用其中一个 加密,需要使用另外一个才能解密.我们在进行RSA加密通讯时,就把公钥放在客户端,私钥留在服务器. RSA非对称加密算法,可以验

RSA体系 c++/java相互进行加签验签--转

在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java对客户端的签名进行验签操作.这就涉及到c++ openssl和java之间交互加签验签对客户端身份进行验证的过程. 如果你通过搜索查到我这边文章,相信你一定发现,采用openssl加签后的 数据,在java端却验签不成功,使用openssl验签可以通过.问题在于openssl的公钥发在服务端转换成j

【转】银行核心与前置系统的区别

目前行业界对银行核心的定义是传统业务的集中处理,这些传统业务的核心都是基于数据记录为基础的业务集中交易. 一.从历史的演变看银行核心和前置系统的诞生 从银行电子化发展的历史我们可以清楚的看到银行核心与银行前置系统的发展和演变. 上世纪80年代,IBM PC XT.苹果机.王安电脑初步深入到银行界的应用,许多商业银行各分行或各分行的储蓄所以这些电脑设备搭建银行记账系统,交易种类在非常窄的应用范围内. 到80年代末期,国家对中国金融电子化领域的优先政策,以中国银行为代表的商业银行引进IBM系统360

“聚合支付”增值盛宴:打通银行垂直账户壁垒

近年来,"聚合支付"行业迎来井喷式的大爆发,商业银行.第三方支付机构.收单代理商等纷纷加入到这一领域的竞争. 所谓"聚合支付"也称"融合支付",是指从事支付.结算.清算服务之外的支付服务商,借助银行.非银机构或清算组织的支付通道与清结算能力,利用自身的技术与服务集成,将一个以上的银行.非银机构或清算组织的支付服务整合到一起,为商户提供"支付通道"."集合对账"."技术对接"."

BANK &amp;&amp; IT

我国现在整个银行业及和它相关的行业(证券,保险,IT业)的一些大概情况 分类: BANKING 2010-07-29 08:58 1710人阅读 评论(2) 收藏 举报 金融工作产品消息中间件开发工具sap 先介绍一下我国现在整个银行业及和它相关的行业(证券,保险,IT业)的一些大概情况.  最近几年是我国银行业改革的关键几年,因为2005年我国金融业将全面开放,外资银行将和中国的银行展开全面的竞争.外资银行在管理水平.金融创新能力方面要优于我们.所以,我国的银行只能利用这点时间,积极改革,加快

2:银联业务

1:三级密钥体系和二级密钥体系: 终端上有几种密钥,就是几级密钥体系 2:发卡行和收单行关系区别 pos机分为银联pos机和银行pos机两类: 如果是银联pos,一笔交易中的角色有发卡行.收单行.卡组织,这里面收单行和卡组织都是银联,所以银联能收到30%的手续费: 如果是收单银行的pos机,一般要支持跨行支付的,这里面的手续费按7:2:1分别给发卡银行.收单银行.银联. 假设发卡行和收单行相同,即pos机是银行pos机.如果该POS机只支持一家银行用(付费),那不经过银联了,手续费100%拿走.