/***************************************************************************** 函 数 名 : pboc_des3_encrypt 功能描述 : 以3DES-ECB(EDE)模式加密数据,加密过程如下, 2. 将第一步中生成的数据块分解成8字节数据块,标号为D1,D2,D3,D4等等。 最后一个数据块长度有可能不足8位。 3. 如果最后(或唯一)的数据块长度等于8字节,转入第四步;如果不足8字节, 在右边添加16进制数字 '80'。如果长度已达8字节,转入第四步;否则, 在其右边添加1字节16进制数字 '00', 直到长度达到8字节。 4. 每一个数据块使用8.3.3.1中描述的数据加密方式加密。 参见"PBOC 2.0 第一部分 卡片规范 8.3 数据可靠性" 输入参数 : const uint8_t enkey[DOUBLE_KEY_SIZE] 双长度(16字节)加密密钥 const uint8_t *inbuf 输入明文 int len 输入明文长度,注意,明文长度不能超过255字节 输出参数 : uint8_t *outbuf 输出密文 返 回 值 : int 返回 0 *****************************************************************************/ int pboc_des3_encrypt(const UINT8 enkey[DOUBLE_KEY_SIZE], const UINT8 *inbuf, int len, UINT8 *outbuf) { des3_context ctx = { { 0 }, { 0 } }; UINT8 buf[DES_BLOCK_SIZE] = { 0 }; UINT8 *pdata; /* compute length of encrypted data */ int enclen = (len + 1 + (DES_BLOCK_SIZE - 1)) & (~7); des3_set_2keys(&ctx, (UINT8 *) enkey, (UINT8 *) (enkey + DES_KEY_SIZE)); #if 0 /* use in pin encrpty */ /* encrypt the 1st block, prepad length UINT8 before data */ buf[0] = (UINT8)len; if(len < DES_BLOCK_SIZE - 1) { memcpy(buf + 1, (void *)inbuf, len); buf[len + 1] = 0x80; } else { memcpy(buf + 1, (void *)inbuf, DES_BLOCK_SIZE - 1); } #endif if (len < DES_BLOCK_SIZE - 1) { memcpy(buf, (void *) inbuf, len); buf[len] = 0x80; } else { memcpy(buf, (void *) inbuf, DES_BLOCK_SIZE); } des3_encrypt(&ctx, buf, outbuf); /* encrypt remaining blocks except the last one */ len -= DES_BLOCK_SIZE - 1; pdata = (UINT8 *) inbuf + DES_BLOCK_SIZE - 1; outbuf += DES_BLOCK_SIZE; while (len >= DES_BLOCK_SIZE) { des3_encrypt(&ctx, pdata, outbuf); len -= DES_BLOCK_SIZE; pdata += DES_BLOCK_SIZE; outbuf += DES_BLOCK_SIZE; } /* encrypt the last block, padding it with '80 00 ...' requested by PBOC STD. */ if (len > 0) { memset(buf, 0, DES_BLOCK_SIZE); memcpy(buf, pdata, len); buf[len] = 0x80; des3_encrypt(&ctx, buf, outbuf); } memset(&ctx, 0, sizeof(des3_context)); return enclen; }
/***************************************************************************** 函 数 名 : pboc_des3_decrypt 功能描述 : 以3DES-ECB(EDE)模式解密数据。 输入参数 : const uint8_t dekey[DOUBLE_KEY_SIZE] 双长度(16字节)解密密钥 const uint8_t *inbuf 输入密文 int len 输入密文长度,注意应为8的整数倍 输出参数 : uint8_t *outbuf 输出明文 返 回 值 : int 返回 0 修改历史 : *****************************************************************************/ int pboc_des3_decrypt(const UINT8 dekey[DOUBLE_KEY_SIZE], const UINT8 *inbuf, int len, UINT8 *outbuf) { des3_context ctx = { { 0 } }; int i; des3_set_2keys(&ctx, (UINT8 *) dekey, (UINT8 *) (dekey + DES_KEY_SIZE)); /* decrypt data in blocks */ for (i = 0; i < len / DES_BLOCK_SIZE; i++) { des3_decrypt(&ctx, (UINT8 *) (inbuf + i * DES_BLOCK_SIZE), outbuf + i*DES_BLOCK_SIZE); } memset(&ctx, 0, sizeof(des3_context)); return 0; }
// 握奇外部认证使用8字节随机数 int ks_zjvcc_cardtype::ExecExtAuthCmd8(byte ucExtAuthKey[16],int nKeyIndex) { byte ucRandom[9]= {0}; int nRet=GetRandomNum8(ucRandom); if(nRet) return nRet; des3_context ctx3; des3_set_2keys( &ctx3, ucExtAuthKey,ucExtAuthKey+8); byte ucBuff[64]= {0}; des3_encrypt(&ctx3,ucRandom,ucBuff); byte ucSendData[256]= {0}; memcpy(ucSendData,"\x00\x82\x00\x00\x08",5); ucSendData[3]=nKeyIndex; memcpy(ucSendData+5,ucBuff,8); byte ucRespData[256]= {0}; byte ucRespLen = 0; return Adpu(ucSendData,0x0D, ucRespData, ucRespLen); }