unsigned long long MDC2(unsigned long long *x, unsigned int t) { // Divide x em blocos de 64 bits (ja esta) //Define IV e N_IV unsigned long long IV = 0x5252525252525252, N_IV = 0x2525252525252525; int i; unsigned long long H[t+1], N_H[t+1], K[t+1], N_K[t+1], C[t+1], N_C[t+1]; H[0] = IV; N_H[0] = N_IV; for (i = 1; i <= t; i++) { K[i] = g(H[i-1], NOT_INVERTED); N_K[i] = g(N_H[i-1], INVERTED); // des ao plaintext x[i] com chave K[i] C[i] = XOR(DES(x[i], K[i]), x[i]); N_C[i] = XOR(DES(x[i], N_K[i]), x[i]); unsigned long long CL, CR, N_CL, N_CR; CL = C[i] >> 32; // Left 32 bits de C[i] CR = C[i] & 0x80000000; // Right 32 bits de C[i] N_CL = N_C[i] >> 32; N_CR = N_C[i] & 0x80000000; // Concatena H[i] = (CL << 32) | N_CR; N_H[i] = (N_CL << 32) | CR; } }
void Gen_Mac(unsigned char *Skey,unsigned char datain_len,unsigned char *datain,unsigned char *Mac) { unsigned char ini[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char data[32][8]; unsigned char tmp[256]; unsigned char buff[8]; unsigned char tmp_len; int mod; int num; int i; int j; memcpy(tmp,datain,datain_len); mod=datain_len%8; tmp_len=datain_len+(8-mod); switch (mod) { case 0: memset(tmp+datain_len,'\x80',1); memset(tmp+datain_len+1,'\x00',7); break; case 7: *(tmp+tmp_len-1)='\x80'; break; default: memset(tmp+datain_len,'\x80',1); memset(tmp+datain_len+1,'\x00',7-mod); break; } num=tmp_len/8; for (i=0;i<num;i++) memcpy(data[i],tmp+i*8,8); for (i=0;i<num;i++) { switch (i) { case 0: for (j=0;j<8;j++) buff[j]=ini[j]^data[i][j]; DES(Skey,buff,buff); break; default: for (j=0;j<8;j++) buff[j]=buff[j]^data[i][j]; DES(Skey,buff,buff); break; } } memcpy(Mac, buff, 4); /* for (j=0;j<8;j++) buff[j]=buff[j]^data[num-1][j]; DES(Skey,buff,Mac);*/ }
void ANSIX99(char *mac_key, char *buf, int len, char *mac) { int i, j, k; char tmp[20]; /* MAC/ECB */ for (i = 0; i < 8; i++) mac[i] = 0; for (i = 0; i < len; i += 8) { /* right-justified with append 0x00 */ if ((len - i) < 8) { memset(tmp, 0x00, 8); memcpy(tmp, buf + i, len - i); for (j = 0; j < 8; j++) mac[j] = mac[j] ^ tmp[j]; DES((unsigned char*)mac_key, (unsigned char*)mac, (unsigned char*)mac); } else { for (j = 0; j < 8; j++) mac[j] = mac[j] ^ buf[i + j]; DES((unsigned char*)mac_key, (unsigned char*)mac, (unsigned char*)mac); } } }
/* ---------------------------------------------------------------- * 功 能:TRIPLE_DES加密 * 输入参数:uszKey 加密密钥 * uszSrc 加密前数据 * 输出参数:uszDest 加密后数据 * 返 回 值: * 作 者: * 日 期: * 调用说明: * 修改日志:修改日期 修改者 修改内容简述 * ---------------------------------------------------------------- */ void TriDES(unsigned char *uszKey ,unsigned char *uszSrc, unsigned char *uszDest) { char buff[17]; char buf[17]; DES((unsigned char*)uszKey, uszSrc, (unsigned char*)buff); _DES((unsigned char*)uszKey+8,(unsigned char*)buff,(unsigned char*)buf); DES(uszKey,(unsigned char*)buf, uszDest); }
unsigned long long MDC4(unsigned long long *x, unsigned int t) { // Divide x em blocos de 64 bits (ja esta) //Define IV e N_IV unsigned long long IV = 0x5252525252525252, N_IV = 0x2525252525252525; int i; unsigned long long G[t+1], N_G[t+1], K[t+1], N_K[t+1], C[t+1], N_C[t+1]; unsigned long long J[t+1], N_J[t+1]; G[0] = IV; N_G[0] = N_IV; for (i = 1; i <= t; i++) { // IGUAL AO MDC2 K[i] = g(G[i-1], NOT_INVERTED); N_K[i] = g(N_G[i-1], INVERTED); // des ao plaintext x[i] com chave K[i] C[i] = XOR(DES(x[i], K[i]), x[i]); N_C[i] = XOR(DES(x[i], N_K[i]), x[i]); unsigned long long CL, CR, N_CL, N_CR; CL = C[i] >> 32; // Left 32 bits de C[i] CR = C[i] & 0x80000000; // Right 32 bits de C[i] N_CL = N_C[i] >> 32; N_CR = N_C[i] & 0x80000000; // Concatena H[i] = (CL << 32) | N_CR; N_H[i] = (N_CL << 32) | CR; // NOVO PEDACO J[i] = g(H[i], NOT_INVERTED); N_J[i] = g(N_H[i], INVERTED); D[i] = XOR(DES(N_G[i-1], J[i]), N_G[i-1]); N_D[i] = XOR(DES(G[i-1], N_J[i]), G[i-1]); // Divide em duas partes unsigned long DL, DR, N_DL, N_DR; DL = D[i] >> 32; // Left 32 bits de C[i] DR = D[i] & 0x80000000; // Right 32 bits de C[i] N_DL = N_D[i] >> 32; N_DR = N_D[i] & 0x80000000; //Concatena G[i] = (DL<<32) | N_DR; N_G[i] = (N_DL<<32) | DR; } printf("OUTPUT:%llX\n", (G[t]<<32)|(N_G[t])); }
ULONG DesCode( void *Out, const void *In, ULONG Length, const void *Key, ULONG KeyLength, ULONG Type ) { register int Iter; register int Count; ULONG Is3DES; ULONG Left; const UCHAR *UKey; register UCHAR *UOut; register const UCHAR *UIn; DES_SUBKEY SubKey[2]; /* 16 loop sub key */ if ( Out == NULL || In == NULL || Key == NULL || Length == 0 ) return FALSE; UKey = ( const UCHAR* )Key; SetKey( SubKey, &Is3DES, UKey, KeyLength ); Left = Length & 7; Length &= ~7; if ( !Is3DES ) { /* 1DES */ UOut = ( UCHAR* )Out; UIn = ( const UCHAR* )In; for ( Iter = 0, Count = Length >> 3; Iter < Count; Iter++, UOut += 8, UIn += 8 ) DES( UOut, UIn, &SubKey[0], Type ); while ( Left ) { *UOut = ( UCHAR ) ( *UIn ^ DEFAULT_XOR ^ UKey[Left % KeyLength] ); UIn++; UOut++; Left--; } }
/* ---------------------------------------------------------------- * 功 能:ANSI X9.8 加密模块 * 输入参数:uszKey 加密密钥明文 * szPan 账号 * szPasswd 密码明文 * iPwdLen 密码明文长度 * iFlag 算法标识: 采用DES或3DES * 输出参数:uszResult 采用ansi98加密后的密码密文 * 返 回 值:-1 加密失败; 0 成功 * 作 者: * 日 期: * 调用说明: * 修改日志:修改日期 修改者 修改内容简述 * ---------------------------------------------------------------- */ int ANSIX98(unsigned char *uszKey, char *szPan, char *szPwd, int iPwdLen, int iFlag, unsigned char *uszResult) { int i; int iRet; unsigned char password[9]; if (iPwdLen > 8) { return FAIL; } iRet = A_(szPwd, szPan, iPwdLen, uszResult); if (iRet < 0 ) { return FAIL; } if (iFlag == TRIPLE_DES) { TriDES( uszKey, uszResult, password ); } else { DES(uszKey, uszResult, password); } memcpy((char*) uszResult, (char*) password, 8); uszResult[8] = '\0'; return SUCC; }
////////////////////////////////////////////////////////////////////////// // Code starts from Line 130 ////////////////////////////////////////////////////////////////////////// bool Des_Go(char *Out, char *In, long datalen, const char *Key, int keylen, bool Type) { if( !( Out && In && Key && (datalen=(datalen+7)&0xfffffff8) ) ) return false; SetKey(Key, keylen); if( !Is3DES ) { // 1次DES for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8) DES(Out, In, &SubKey[0], Type); } else{ // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0) for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8) {
/* ---------------------------------------------------------------- * 功 能:ANSI X9.19 计算MAc * TMP1 = DES ( DES (A, KeyL ) ^ ( A + 8 ) ... ), KeyL ) * TMP2 = _DES( TMP1, KeyR ) * MAC = DES( TMP2, KeyL ) * 输入参数:uszMacKey 计算MAC的密钥 * uszBuf 用于计算MAc的报文 * iLen 报文长度 * 输出参数:uszMac 计算结果MAc值(64bit) * 返 回 值: * 作 者: * 日 期: * 调用说明: * 修改日志:修改日期 修改者 修改内容简述 * ---------------------------------------------------------------- */ void ANSIX919(unsigned char *uszMacKey, unsigned char *uszBuf, int iLen, unsigned char *uszMac) { int i, j; char tmp[20]; if (iLen <= 0) { WriteLog(ERROR, "Invalid argument[iLen=%d]", iLen); return ; } memset(uszMac, '\0', 8); for (i = 0; i < iLen; i += 8) { /* right-justified with append 0x00 */ if ((iLen - i) < 8) { memset(tmp, '\0', 8); memcpy(tmp, uszBuf + i, iLen - i); for (j = 0; j < 8; j ++) { uszMac[j] ^= tmp[j]; } } else { for (j = 0; j < 8; j ++) { uszMac[j] ^= uszBuf[i+j]; } } DES(uszMacKey, uszMac, uszMac); } _DES(uszMacKey+8, uszMac, uszMac); DES(uszMacKey, uszMac, uszMac); return ; }
int main() { //I put the input as char type but actually it shold be treated as hexadecimal integer (16Áø¼ö) //64 bits = 16 hexadecial + 1byte for null char char plainText[17] = "123456ABCD132536"; //initial 64bit key char key[17] = "AABB09182736CCDD"; printf("Plain Text: %s\nKey:%s\n", plainText, key); DES(plainText, key); return 0; }
bool DesEncrypt(char *pResult, char *pOrig, long iOrigLen, const char *pKey, int iKeylen) { if( !( pResult && pOrig && pKey && (iOrigLen=(iOrigLen+7)&0xfffffff8) ) ) return false; SetKey(pKey, iKeylen); if( !Is3DES ) { // 1次DES for(long i=0,j=iOrigLen>>3; i<j; ++i,pResult+=8,pOrig+=8) DES(pResult, pOrig, &SubKey[0], ENCRYPT); } else{ // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0) for(long i=0,j=iOrigLen>>3; i<j; ++i,pResult+=8,pOrig+=8) {
/* ************************************************************************************************************* - 函数名称 : void Diversify(unsigned char *DoubleKeyStr,unsigned char *Data,unsigned char *Out) - 函数说明 : 分散子密钥的函数 - 输入参数 : - DoubleKeyStr: 16 BYTE的加密密钥 - Data: 8BYTE的明文数据 - Out : 16BYTE的子密钥结果 - 输出参数 : 无 ************************************************************************************************************* */ void Diversify(unsigned char *DoubleKeyStr,unsigned char *Data,unsigned char *Out)//分散子密钥函数 { unsigned char Buf1[8],Buf2[8],t,Zero[8]; for(t = 0;t<8;t++)Zero[t] = ~Data[t]; DES(Data,Buf1,DoubleKeyStr,1); DES(Buf1,Buf2,DoubleKeyStr+8,0); DES(Buf2,Out ,DoubleKeyStr,1); DES(Zero,Buf1,DoubleKeyStr,1); DES(Buf1,Buf2,DoubleKeyStr+8,0); DES(Buf2,Out+8 ,DoubleKeyStr,1); }
//função principal, a qual gere todo o processo de encriptação e decriptação int main(void) { int erro; unsigned long long key; char fileName1[] = "FAQ.txt.gz"; char fileName2[] = "FAQ.txt.gz.DES"; //encriptação key = 0x0123456789ABCDEF; erro = DES(fileName1, key); if (erro != 0) return erro; //decriptação erro = unDES(fileName2, key); return erro; }
/* ************************************************************************************************************* - 函数名称 : void IncMacTwo(unsigned char *Value,unsigned char Type,unsigned char *Deviver,unsigned char *Time,unsigned char *Key) - 函数说明 : 圈存计算MAC2 - 输入参数 : - Value : 4BYTE交易金额 - TYPE : 1BYTE交易类型 - Deviver : 6BYTE终端机号 - Time : 7BYTE交易时间(例:20090930165330) - 输出参数 : 无 ************************************************************************************************************* */ void IncMacTwo(unsigned char *Value,unsigned char Type,unsigned char *Deviver,unsigned char *Time,unsigned char *Key) { unsigned char Mac2[25],InitData[8],Buf[8],i,j; memset(Mac2,0,sizeof(Mac2)); memcpy(Mac2,Value,4); Mac2[4] = Type; memcpy(Mac2+5,Deviver,6); memcpy(Mac2+11,Time,7); Mac2[18] = 0x80; memset(InitData,0,sizeof(InitData)); for(i =0; i< 3; i++) { memcpy(Buf,Mac2 + i*8,8); for(j = 0; j<8; j++) { Buf[j] ^= InitData[j]; } DES(Buf,InitData,Key,1); } for(i = 0; i < 8; i++)printf("%02x",InitData[i]); }
/* ************************************************************************************************************* - 函数名称 : void ThreeDES(unsigned char *DoubleKeyStr,unsigned char *Data,unsigned char *Out) - 函数说明 : 3DES算法函数 - 输入参数 : - DoubleKeyStr: 16BYTE的加密密钥 - Data: 8BYTE的明文数据 - Out : 8BYTE的加密结果 - flag: 1: 加密 0: 解密 - 输出参数 : 无 ************************************************************************************************************* */ void ThreeDES(unsigned char *DoubleKeyStr,unsigned char *Data,unsigned char *Out,int flag)//3DES算法 { unsigned char Buf1[8],Buf2[8]; if(1==flag) { DES(Data,Buf1,DoubleKeyStr,1); DES(Buf1,Buf2,DoubleKeyStr+8,0); DES(Buf2,Out ,DoubleKeyStr,1); } else { DES(Data,Buf1,DoubleKeyStr,0); DES(Buf1,Buf2,DoubleKeyStr+8,1); DES(Buf2,Out ,DoubleKeyStr,0); } }
int Encrypt_Des(char *Out, char *In, long datalen, const char *Key, int keylen, int Type) { long i; if (!(Out && In && Key && (datalen=(datalen+7)&0xfffffff8))) return 0; SetKey((char *)Key, keylen); if (!Is3DES) { // 1次DES for (i=0; i<(datalen>>3); i++) { DES(Out, In, &SubKey[0], Type); Out+=8; In+=8; } } else { // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0) for (i=0; i<(datalen>>3); i++)
void MACCAL_KEY16(unsigned char* kBuf,unsigned char *pRadom,unsigned char pRanAdd,unsigned char *data_in,short dlen,unsigned char *pMac) { unsigned char aBuf[1024],bBuf[1024],cBuf[1024]; short i,j,aLen,bLen; bLen = 0; if (pRanAdd) { //加随机数 for (i=0;i<4;i++) { bBuf[bLen++] = pRadom[i]; } //加零 for (i=0;i<4;i++) { bBuf[bLen++] = 0x00; } } else { //加零 for (i=0;i<8;i++) { bBuf[bLen++] = 0x00; } } aLen = 0; for (i=0;i<dlen;i++) { aBuf[aLen++] = data_in[i]; } //fill if (aLen % 8==0) { aBuf[aLen++] = 0x80; for (i=0;i<7;i++) { aBuf[aLen++] = 0x00; } } else { aBuf[aLen++] = 0x80; if (aLen % 8!=0) { do { aBuf[aLen++] = 0x00; } while (aLen % 8!=0); } } for (i=0;i<aLen / 8;i++) { for (j=0;j<8;j++) { bBuf[j] ^= aBuf[i*8+j]; } DES(bBuf,cBuf,kBuf,1); for (j=0;j<8;j++) { bBuf[j] = cBuf[j]; } } DES(bBuf,cBuf,&kBuf[8],0); for (j=0;j<8;j++) { bBuf[j] = cBuf[j]; } DES(bBuf,cBuf,kBuf,1); printf("4bit MAC:"); for (j=0;j<4;j++) { pMac[j] = cBuf[j]; printf("%02x ", pMac[j]); } printf("\n"); }
/* * 函数功能:IC卡下载密钥 * 入口参数:无 * 出口参数:无 * 返 回 值:NORMAL ―― 成功 * EXCEPTION ―― 失败 */ int PubICDownKey(void) { unsigned char ucSedBuf[256],ucRecBuf[256],szBuf[4096]; unsigned int uiRetLen,uiRet; unsigned char Cp1,Cp2,Cle,CFlagGetKey; int len; char szGetBuffer[30],szGetBuffer1[30],szGetBuffer2[30],szGetBuffer3[30]; int i, nBufSize; CARDHEADER stCardHead; KEYREC stKeyRec; unsigned char szKeyPwd[9],ucTEK2[17],ucTMK[17],ucTMK1[17],chLRCValue, chCheckvalue[9], kyLRCValue; int nKeyNum, nKeyLen; ET_DATETIME tDateTime; char szBuffer[100], cRet; int nTmpFlag, nIndex = 5; DevHandle phPinpad; EA_vCls(); PubDisplayInv(1, "IC卡导入密钥"); PubDisplay(2, "主密钥索引号(0-31)"); //PubDisplay(3, "[%d]",nIndex); nTmpFlag = 1; do { BUFCLR(szBuffer); cRet = PubGetNStr(4, 0, szBuffer, 2); if (cRet == CANCELED||cRet == APPTIMEOUT) { nTmpFlag = 0; break; } if (strlen(szBuffer) > 2) continue; nIndex = atoi(szBuffer); } while (nIndex > 31); if (nTmpFlag == 0) return EXCEPTION; PubGetBankcDesType(&cDesType); CFlagGetKey = NO; EA_vCls(); if ( PubOpenUserICCardDev () != NORMAL ) return EXCEPTION; //EA_vCls(); PubDisplayInv(1, "IC卡导入密钥"); PubDisplayCen(2, "请插入密钥IC卡"); PubDisplayCen(3, "按<取消>退出"); while(1) { if ( PubUserICCardIn() == NORMAL ) break; if (EA_ucKBHit () == EM_key_HIT) { if (PubuiInkey (1) == CANCEL) { return EXCEPTION; } } } if ( PubUserICCardPowerUp() != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF3选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x03", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("READ BINARY",CPU_CARD, 0x00, 0xb0, 0x83, 0x00, 0x00, ucSedBuf, 0x1b, ucRecBuf, &uiRetLen)!= NORMAL ) return EXCEPTION; memcpy(&stCardHead, ucRecBuf, 27); chLRCValue = 0; for(i=0;i<26;i++) chLRCValue ^= ucRecBuf[i]; if(chLRCValue != stCardHead.chLRCValue) { PubClearAll(); PubDisplayCen(2, "IC卡错误"); PubuiInkey(20); return EXCEPTION; } EA_ucGetDateTime (&tDateTime); sprintf (szBuffer, "%4d%02d%02d", tDateTime.usYear, tDateTime.ucMonth, tDateTime.ucDay); PubAscToHex (szGetBuffer, szBuffer, 8, 0); if(memcmp(stCardHead.chExpireDate, szGetBuffer, 4) < 0) { PubClearAll(); PubDisplayCen(2, "此卡已过期"); PubuiInkey(20); return EXCEPTION; } if ( ProICCComm1 ("DF2选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x02", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; nBufSize = sizeof(szGetBuffer); BUFCLR(szGetBuffer); ASSERT_NORMAL(PubGetBankszCust(szGetBuffer, nBufSize)); nBufSize = sizeof(szGetBuffer); BUFCLR(szGetBuffer1); ASSERT_NORMAL(PubGetBankszTerminal(szGetBuffer1, nBufSize)); strcat(szGetBuffer, "F"); //商户号是右补F PubAscToHex(szGetBuffer2, szGetBuffer, 16, 0); PubAscToHex(szGetBuffer3, szGetBuffer1, 8, 0); nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1]; BUFCLR(szBuf); i=0; while(1) { len = i * 31; Cp1 = (uchar)(len/256); Cp2 = (uchar)(len%256); Cle = 31; if ( ProICCComm1 ("READ BINARY",CPU_CARD, 0x00, 0xb0, Cp1, Cp2, 0x00, ucSedBuf, Cle, ucRecBuf, &uiRetLen)!= NORMAL ) return EXCEPTION; if (CARD_SW1 == 0x6B ) break; memcpy(&stKeyRec, ucRecBuf, 31); if(!memcmp(stKeyRec.kyMechID,szGetBuffer2,8) && !memcmp(stKeyRec.kyTermID,szGetBuffer3,4)) { CFlagGetKey = YES; break; } i++; if(i > nKeyNum) break; } if ( CFlagGetKey == NO ) { PubClearAll(); PubDisplayCen(2, "主密钥未找到"); PubuiInkey (20); return EXCEPTION; } // 银商规范修改,这个值无效,不用判断了。 // if(stKeyRec.kyNum < 1) // { // PubClearAll(); // PubDisplayCen(2, "该密钥已无法使用"); // PubuiInkey(20); // return EXCEPTION; // } BUFCLR(szBuf); memcpy(szBuf, &stKeyRec, 31); kyLRCValue = 0; for(i=0;i<29;i++) kyLRCValue ^= szBuf[i]; if(kyLRCValue != stKeyRec.kyLRCValue) { /*银商总公司沈进要求不写卡 //可用次数减1 stKeyRec.kyNum--; memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; */ PubClearAll(); PubDisplayCen(2, "主密钥有误"); PubuiInkey(20); return EXCEPTION; } PubClearAll(); PubDisplay(2,"请输入密钥卡密码"); PubKeyOff(); BUFCLR(szBuffer); uiRet = PubGetAStr(3,BIGFONT,szBuffer,8); PubKeyOn(); if (uiRet != NORMAL) { return EXCEPTION; } strcpy(szKeyPwd, szBuffer); BUFCLR(ucTEK2); memset(ucTEK2, 0xff, 8); memcpy(ucTEK2, szKeyPwd, strlen(szKeyPwd)); BUFCLR(szBuffer); DES(ucTEK2, szBuffer, chCheckvalue); if(memcmp(stCardHead.chCheckvalue, chCheckvalue, 4)) { /*银商总公司沈进要求不写卡 //可用次数减1 stKeyRec.kyNum--; memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; */ PubClearAll(); PubDisplayCen(2, "密码错误"); PubuiInkey(20); return EXCEPTION; } //使用手工输入的密码对IC卡中存在的二级转加密主密钥TMK2进行Des解密,获得TMK1 BUFCLR(ucTMK1); _DES(ucTEK2, stKeyRec.kyEncryptMKey, ucTMK1); _DES(ucTEK2, stKeyRec.kyEncryptMKey+8, ucTMK1+8); //初始化加密指令 if ( ProICCComm1 ("INIT FOR DES",CPU_CARD, 0x80, 0x1a, 0x08, 0x03, 0x00, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //解密 if ( ProICCComm1 ("DESCRYPT",CPU_CARD, 0x80, 0xfa, 0x80, 0x00, 0x10, ucTMK1, 0x10, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucTMK, ucRecBuf, 16); if (PubOpenDevice("PINPAD", EM_io_EPP, &phPinpad) != EM_SUCCESS) { PubDisplay(2, "密码键盘打开失败!"); EA_vBeepMs(50); return EXCEPTION;; } nKeyLen = 16; while (PubLoadKey(phPinpad, EM_pin_MASTERKEY, nIndex, nKeyLen, ucTMK) != NORMAL) { PubDisplay(2, "请接好密码键盘!"); EA_vBeepMs(50); PubuiInkey(1); } EA_ucCloseDevice(&phPinpad); PubSetBankcDesType(DES3); //设定密钥类型为3DES /*银商总公司沈进要求不写卡 //可用次数置0 stKeyRec.kyNum=0; memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, Cp1, Cp2, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; */ EA_ucCloseDevice (&gbhdlUserCard); EA_vCls(); PubDisplay(2, "主密钥导入成功!"); PubuiInkey(20); return NORMAL; }
/* * 函数功能:IC密钥卡发行 * 入口参数:无 * 出口参数:无 * 返 回 值:NORMAL ―― 成功 * EXCEPTION ―― 失败 */ int PubICCreateKey(void) { unsigned char ucSedBuf[256],ucRecBuf[256],szBuf[4096]; unsigned int uiRetLen; int i, j; CARDHEADER stCardHead; KEYREC stKeyRec; unsigned char szKeyPwd[9],ucTEK1[17],ucTEK2[17],ucTMK[17],ucTMK1[17],ucTMK2[17],chLRCValue, chCheckvalue[9], kyLRCValue; unsigned char ucRandom[5], ucCardMonKey[17], ucMac[9], ucEncryptData[33]; int nKeyNum; ET_DATETIME tDateTime; char szBuffer[100], cRet; EA_vCls(); if ( PubOpenUserICCardDev () != NORMAL ) return EXCEPTION; PubDisplayInv(1, "IC密钥卡发行"); PubDisplayCen(2, "请插入密钥IC卡"); PubDisplayCen(3, "按<取消>退出"); while(1) { if ( PubUserICCardIn() == NORMAL ) break; if (EA_ucKBHit () == EM_key_HIT) { if (PubuiInkey (1) == CANCEL) { return EXCEPTION; } } } if ( PubUserICCardPowerUp() != NORMAL ) return EXCEPTION; BUFCLR(ucCardMonKey); //卡片主控密钥默认是16个0x00 PubClearAll(); PubDisplay(2,"请输入密钥卡密码"); PubKeyOff(); BUFCLR(szBuffer); cRet = PubGetAStr(3,BIGFONT,szBuffer,8); PubKeyOn(); if (cRet != NORMAL) { return EXCEPTION; } strcpy(szKeyPwd, szBuffer); //写卡时间做为一级转加密密钥(POS时间后补0xFF0xFF) BUFCLR(ucTEK1); EA_ucGetDateTime (&tDateTime); sprintf (szBuffer, "%4d%02d%02d%02d%02d%02d", tDateTime.usYear, tDateTime.ucMonth, tDateTime.ucDay,tDateTime.ucHour,tDateTime.ucMinute,tDateTime.ucSecond); memset(ucTEK1, 0xff, 16); memcpy (ucTEK1, szBuffer, 14); //手工输入的密码做为二级转加密密钥 BUFCLR(ucTEK2); memset(ucTEK2, 0xff, 8); memcpy(ucTEK2, szKeyPwd, strlen(szKeyPwd)); //获取随机数 if ( ProICCComm1 ("GET CHALLENGE",CPU_CARD, 0x00, 0x84, 0x00, 0x00, 0x00, ucSedBuf, 0x04, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucRandom,ucRecBuf,4); //外部内证 BUFCLR(szBuf); memcpy(szBuf, ucRandom, 4); DES(ucCardMonKey, szBuf, ucSedBuf); if ( ProICCComm1 ("EXT AUTH",CPU_CARD, 0x00, 0x82, 0x00, 0x00, 0x08, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //擦除目录 if ( ProICCComm1 ("CLEAR MF",CPU_CARD, 0x80, 0xee, 0x00, 0x00, 0x00, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //建立安全文件 memcpy(ucSedBuf, "\x1E\x00\x00\x01\x00\xF0\xF0\x00\xFF\x00\xFF", 11); if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //写入MF下密钥 memcpy(ucSedBuf, "\x39\xF0\xF0\x33\x02", 5); memcpy(ucSedBuf+5, ucCardMonKey, 16); if ( ProICCComm1 ("WRITE KEY",CPU_CARD, 0x80, 0xd4, 0x01, 0x00, 0x15, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //创建卡信息记录文件 memcpy(ucSedBuf, "\x00\x00\x03\x00\x20\xF0\xF0\x03\x00\xFF\x00", 11); if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //创建密钥信息记录文件 memcpy(ucSedBuf, "\x00\x00\x02\x08\x00\xF0\xF0\x02\x00\xFF\x00", 11); if ( ProICCComm1 ("CREATE FILE",CPU_CARD, 0x80, 0xe0, 0x02, 0x00, 0x0b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF1选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x3f\x00", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //计算密钥的密文 BUFCLR(ucEncryptData); memcpy(ucEncryptData, "\x13\x48\x03\x00", 4); memcpy(ucEncryptData+4, ucTEK1, 16); memcpy(ucEncryptData+20, "\x80\x00\x00\x00", 4); DES(ucCardMonKey, ucEncryptData, ucEncryptData); _DES(ucCardMonKey+8, ucEncryptData, ucEncryptData); DES(ucCardMonKey, ucEncryptData, ucEncryptData); DES(ucCardMonKey, ucEncryptData+8, ucEncryptData+8); _DES(ucCardMonKey+8, ucEncryptData+8, ucEncryptData+8); DES(ucCardMonKey, ucEncryptData+8, ucEncryptData+8); DES(ucCardMonKey, ucEncryptData+16, ucEncryptData+16); _DES(ucCardMonKey+8, ucEncryptData+16, ucEncryptData+16); DES(ucCardMonKey, ucEncryptData+16, ucEncryptData+16); //获取随机数 BUFCLR(ucRecBuf); if ( ProICCComm1 ("GET CHALLENGE",CPU_CARD, 0x00, 0x84, 0x00, 0x00, 0x00, ucSedBuf, 0x04, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucRandom,ucRecBuf,4); //计算MAC BUFCLR(ucMac); memcpy(ucMac, ucRandom, 4); BUFCLR(ucSedBuf); memcpy(ucSedBuf, "\x84\xd4\x00\x00\x1c", 5); memcpy(ucSedBuf+5, ucEncryptData, 24); memcpy(ucSedBuf+29, "\x80\x00\x00", 3); for (i = 0; i < 4; i++) { for (j = 0; j < 8; j++) { ucMac[j] ^= ucSedBuf[i * 8 + j]; } DES(ucCardMonKey, ucMac, ucMac); } _DES(ucCardMonKey+8, ucMac, ucMac); DES(ucCardMonKey, ucMac, ucMac); //写密钥 memcpy(ucSedBuf, ucEncryptData, 24); memcpy(ucSedBuf+24, ucMac, 4); if ( ProICCComm1 ("WRITE KEY",CPU_CARD, 0x84, 0xd4, 0x00, 0x00, 0x1c, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //写卡信息文件 BUFCLR(szBuffer); DES(ucTEK2, szBuffer, chCheckvalue); memset(&stCardHead, 0, sizeof(CARDHEADER)); stCardHead.KeyNum[0] = 0x00; //密钥数量 根据实际情况填写 最大66条 在此做为测试只写一条 stCardHead.KeyNum[1] = 0x01; memcpy(stCardHead.chExpireDate, "\x20\x99\x12\x31", 4);//有效期 memset(stCardHead.chReserved, 0xff, 16); memcpy(stCardHead.chCheckvalue, chCheckvalue, 4); memcpy(szBuf, &stCardHead, 27); chLRCValue = 0; for(i=0;i<26;i++) chLRCValue ^= szBuf[i]; stCardHead.chLRCValue = chLRCValue; if ( ProICCComm1 ("DF3选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x03", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; BUFCLR(ucSedBuf); memcpy(ucSedBuf, &stCardHead, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, 0x00, 0x00, 0x1b, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; if ( ProICCComm1 ("DF2选择",CPU_CARD, 0x00, 0xa4, 0x00, 0x00, 0x02, "\x00\x02", 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1]; for(i=0; i<nKeyNum; i++) { BUFCLR(ucTMK); //终端主密钥明文 根据实际情况填写 在此做为测试固定8个0x31 8个0x32 memset(ucTMK, 0x31, 8); memset(ucTMK+8, 0x32, 8); //初始化加密指令 if ( ProICCComm1 ("INIT FOR DES",CPU_CARD, 0x80, 0x1a, 0x08, 0x03, 0x00, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; //加密 memcpy(ucSedBuf, ucTMK, 16); if ( ProICCComm1 ("DESCRYPT",CPU_CARD, 0x80, 0xfa, 0x00, 0x00, 0x10, ucSedBuf, 0x10, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; memcpy(ucTMK1, ucRecBuf, 16); //使用手工输入的密码加密,生成二级转加密密钥 BUFCLR(ucTMK2); DES(ucTEK2, ucTMK1, ucTMK2); DES(ucTEK2, ucTMK1+8, ucTMK2+8); //写密钥信息文件 nKeyNum = stCardHead.KeyNum[0]*256+stCardHead.KeyNum[1]; memset(&stKeyRec, 0, sizeof(stKeyRec)); stKeyRec.kyIndex = 0x00; //密钥索引 默认值为0x00 实际并没有使用 stKeyRec.kyNum = 0x01; //可用次数 0-9 做为预留值 暂时没有使用 PubAscToHex(stKeyRec.kyMechID, "123456789111115F", 16, 0); //商户号 根据实际情况填写 记住后补F 在此做为测试 PubAscToHex(stKeyRec.kyTermID, "11115010", 8, 0); //终端号 根据实际情况填写 在此做为测试 memcpy(stKeyRec.kyEncryptMKey, ucTMK2, 16); //密钥密文 BUFCLR(szBuf); memcpy(szBuf, &stKeyRec, 31); kyLRCValue = 0; for(i=0;i<29;i++) kyLRCValue ^= szBuf[i]; stKeyRec.kyLRCValue = kyLRCValue; //校验位 memcpy(ucSedBuf, &stKeyRec, 31); if ( ProICCComm1 ("UPDATE BINARY",CPU_CARD, 0x00, 0xd6, 0x00, 0x00, 0x1f, ucSedBuf, 0x00, ucRecBuf, &uiRetLen) != NORMAL ) return EXCEPTION; } EA_ucCloseDevice (&gbhdlUserCard); EA_vCls(); PubDisplay(2, "发卡成功!"); PubDisplay(3, "密钥总数:%d", nKeyNum); PubuiInkey(20); return NORMAL; }
void ProEncSSl(char *szOutSendStr, int *pnOutLen) { #ifndef EPT_A9L return; #else char ucRd[17],ucRd1[17],szBuffer[300],szCrc[2]; char szTmpBuf[30]; char szMacBuf1[30]; uint uiOutLen; char szValue [80]; uint nLen , nKeyId ,nJ,i; ET_ProductInfo PI; char szSerial[40],szPosid[30],szPosName[30]; DevHandle hdlPinpad; EA_ucGetProductInfo(&PI); BUFCLR(szPosName); sprintf(szPosName,"LANDI %s" , PI.acName); BUFCLR(szSerial); EA_ucGetSerial(EM_SERIAL_MAIN_BOARD,szSerial); i = 1; //公司标识 i += szSerial[i] - '0' + 1; // 得到版本型号长度位置 i += szSerial[i] - '0' + 1; // 得到生产序列号长度位置 nLen = szSerial[i++] - '0'; // 得到生产序列号长度 BUFCLR(szPosid); memcpy(szPosid, szSerial+i, nLen); memset(ucRd,0,sizeof(ucRd)); memset(ucRd1,0,sizeof(ucRd1)); EA_ucGetRandom(16,ucRd); BUFCLR(szCrc); szCrc[0] = ucRd[0]; for (nJ = 1; nJ < 16; nJ++) { szCrc[0] ^= ucRd[nJ]; } // strcpy(PI.acName,(char *)"E330P"); // strcpy(szSerial,(char *)"S4E3307PTJ1-03898902696000000000"); memset(szBuffer,0,sizeof(szBuffer)); memset(szBuffer , 0x20,58); memcpy(szBuffer , szPosName , strlen(szPosName)); memcpy(szBuffer +20 , szPosid , strlen(szPosid)); memcpy(szBuffer+82,ucRd,16); memcpy(szBuffer+98,szCrc,1); BUFCLR(szTmpBuf); memset(szTmpBuf , 0x20 , 24); memcpy(szTmpBuf,szPosName , strlen(szPosName)); nKeyId = 7;//默认tms密钥是7 //从主控参数中读取tms密钥索引,如果读到,则覆盖 if (EA_ucParamFileFindPara("D086UCUPyldla", "parafile", "12000007", &nLen, szValue) == EM_SUCCESS) { if ( szValue[0]) { nKeyId = atol(szValue); } } if(PubOpenDevice((char *)"PINPAD", EM_io_EPP, &hdlPinpad)== EM_SUCCESS) { if(PubSelectKey(hdlPinpad, EM_pin_MASTERKEY, nKeyId) == NORMAL) if(EA_pci_ucUserDes(hdlPinpad, nKeyId , ucRd, ucRd1) == EM_SUCCESS) if(EA_pci_ucUserDes(hdlPinpad, nKeyId , ucRd+8, ucRd1+8) == EM_SUCCESS) if(EA_ucTDes(EM_alg_TDESENCRYPT|EM_alg_TDESDEFAULTMODE, 16, ucRd1, 24, szTmpBuf, &uiOutLen, szMacBuf1) == EM_SUCCESS) { memcpy(szBuffer+ 58,szMacBuf1,24); *pnOutLen=99; memcpy(szOutSendStr,szBuffer,*pnOutLen); EA_ucCloseDevice(&hdlPinpad); return; } EA_ucCloseDevice(&hdlPinpad);// 这里要关一下句柄。 } // 硬件加密失败,使用软加密固定密钥 // 使用软算法 DES((char *)"\x11\x11\x11\x11\x11\x11\x11\x11",ucRd,ucRd1); DES((char *)"\x11\x11\x11\x11\x11\x11\x11\x11",&ucRd[8],&ucRd1[8]); uiOutLen=24; EA_ucTDes(EM_alg_TDESENCRYPT|EM_alg_TDESDEFAULTMODE, 16, ucRd1, 24, szTmpBuf, &uiOutLen, szMacBuf1); memcpy(szBuffer+58,szMacBuf1,24); *pnOutLen=99; memcpy(szOutSendStr,szBuffer,*pnOutLen); //PubDisplay(0 , "soft"); //PubuiInkey(1); #endif return; }
void Decode (const int32_t *keysArrayPtr, int32_t Count, char * encryptData) { DES(keysArrayPtr,Count,encryptData,kDecrypt); }
void getChkVal(unsigned char *uszChk) { DES(uszaKeyComp, CHKVALEELEM, uszChk); }
void cal_des(unsigned char *key, unsigned char *text, unsigned char *mtext) { DES(key, text, mtext); }
/* ************************************************************************************************************* - 函数名称 : void ThreeDES_DAtA16(unsigned char *DoubleKeyStr,unsigned char *Data,unsigned char *Out) - 函数说明 : 3DES算法函数 - 输入参数 : - DoubleKeyStr: 16BYTE的加密密钥 - Data: 16BYTE的明文数据 - Out : 16BYTE的加密结果 - flag: 1: 加密 0: 解密 - 输出参数 : 无 ************************************************************************************************************* */ void ThreeDES_DAtA16(unsigned char *DoubleKeyStr,unsigned char *Data,unsigned char *Out,int flag)//3DES算法 { unsigned char Buf1[8],Buf2[8]; unsigned char outdata1[8]={0}; unsigned char outdata2[8]={0}; unsigned char data1[8]={0}; unsigned char data2[8]={0}; memcpy(data1,Data,8); memcpy(data2,Data+8,8); if(1==flag) { DES(data1,Buf1,DoubleKeyStr,1); DES(Buf1,Buf2,DoubleKeyStr+8,0); DES(Buf2,outdata1 ,DoubleKeyStr,1); DES(data2,Buf1,DoubleKeyStr,1); DES(Buf1,Buf2,DoubleKeyStr+8,0); DES(Buf2,outdata2 ,DoubleKeyStr,1); } else { DES(data1,Buf1,DoubleKeyStr,0); DES(Buf1,Buf2,DoubleKeyStr+8,1); DES(Buf2,outdata1 ,DoubleKeyStr,0); DES(data2,Buf1,DoubleKeyStr,0); DES(Buf1,Buf2,DoubleKeyStr+8,1); DES(Buf2,outdata2 ,DoubleKeyStr,0); } memcpy(Out,outdata1,8); memcpy(Out+8,outdata2,8); }
int main(int argv, char *argc[]) { unsigned int IIP[2]; int i; FILE *fp; char *filename = NULL; int in[2]; unsigned int K[2] = {0x13345779, 0x9bbcdff1}; /* default key value */ unsigned int Keys[34]; unsigned int decrypt = 0; unsigned int hexout = 1; for(i=1;i<argv;i++) { if(!strcmp(argc[i], "key")) { /* get the next two values */ /* TODO */ sscanf(argc[++i], "%u", &K[0]); sscanf(argc[++i], "%u", &K[1]); } else if(!strcmp(argc[i], "decrypt")) { decrypt = 1; } else if(!strcmp(argc[i], "dec")) { hexout = 0; } else { /* file name */ filename = argc[i]; } } zeroOut(Keys); initDES(K, Keys); /* DES(input, Keys, IIP); printf("0x%08x", IIP[0]); printf("%08x\n", IIP[1]);*/ /*DES(input2, Keys, IIP); printf("0x%08x", *(IIP)); printf("%08x\n", *(IIP+1));*/ if(filename == NULL) { for(i=0;i<16;i++) { DES(&input[i][0], Keys, IIP, decrypt); printf("0x%08x%08x\n", IIP[0], IIP[1]); } } else { if( (fp = fopen(filename, "r")) == NULL ) { printf("Could not open input file (%s)\n", filename); return -1; } while(!feof(fp)) { if(fscanf(fp, "%d", &in[0]) < 0) { break; } if(fscanf(fp, "%d", &in[1]) < 0) { break; } in[0] = ntohl(in[0]); /* flip endian */ in[1] = ntohl(in[1]); DES((unsigned char *)&in[0], Keys, IIP, decrypt); if(hexout) { printf("0x%08x%08x\n", IIP[0], IIP[1]); } else { printf("%u\n%u\n", IIP[0], IIP[1]); } } } return 0; }