Beispiel #1
0
/*****************************************************************************
 函 数 名  : 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;
}
Beispiel #2
0
/*****************************************************************************
 函 数 名  : 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);
}