⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdes.cpp

📁 用C语言实现的智能卡关键加密解密算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  作       者:	邹德强
  更 新 日 期:	2003.12.19
/*******************************************************************/
bool CDES::RunDes(bool bType,bool bMode,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen)
{
	//判断输入合法性
	if(!(In && Out && Key && datalen && keylen>=8))
		return false;
	//只处理8的整数倍,不足长度自己填充
	if(datalen & 0x00000007)
		return false;
	
	bool				m_SubKey[3][16][48];		//秘钥
	//构造并生成SubKeys
	unsigned char nKey	=	(keylen>>3)>3 ? 3: (keylen>>3);
	for(int i=0;i<nKey;i++)
	{
		SetSubKey(&m_SubKey[i],&Key[i<<3]);
	}

	if(bMode == ECB)	//ECB模式
	{
		if(nKey	==	1)	//单Key
		{
			for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
			{
				DES(Out,In,&m_SubKey[0],bType);
			}
		}
		else
		if(nKey == 2)	//3DES 2Key
		{
			for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
			{
				DES(Out,In,&m_SubKey[0],bType);
				DES(Out,Out,&m_SubKey[1],!bType);
				DES(Out,Out,&m_SubKey[0],bType);
			}
		}
		else			//3DES 3Key
		{
			for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
			{
				DES(Out,In,&m_SubKey[bType? 2 : 0],bType);
				DES(Out,Out,&m_SubKey[1],!bType);
				DES(Out,Out,&m_SubKey[bType? 0 : 2],bType);	
			}
		}
	}	
	else				//CBC模式
	{
		char	cvec[8]	=	"";	//扭转向量
		char	cvin[8]	=	""; //中间变量

		if(nKey == 1)	//单Key
		{
			for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
			{
				if(bType	==	CDES::ENCRYPT)
				{
					for(int j=0;j<8;++j)		//将输入与扭转变量异或
					{
						cvin[j]	=	In[j] ^ cvec[j];
					}
				}
				else
				{
					memcpy(cvin,In,8);
				}

				DES(Out,cvin,&m_SubKey[0],bType);

				if(bType	==	CDES::ENCRYPT)
				{
					memcpy(cvec,Out,8);			//将输出设定为扭转变量
				}
				else
				{
					for(int j=0;j<8;++j)		//将输出与扭转变量异或
					{
						Out[j]	=	Out[j] ^ cvec[j];
					}
					memcpy(cvec,cvin,8);			//将输入设定为扭转变量
				}
			}
		}
		else
		if(nKey == 2)	//3DES CBC 2Key
		{
			for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
			{
				if(bType	==	CDES::ENCRYPT)
				{
					for(int j=0;j<8;++j)		//将输入与扭转变量异或
					{
						cvin[j]	=	In[j] ^ cvec[j];
					}
				}
				else
				{
					memcpy(cvin,In,8);
				}
				
				DES(Out,cvin,&m_SubKey[0],bType);
				DES(Out,Out,&m_SubKey[1],!bType);
				DES(Out,Out,&m_SubKey[0],bType);
				
				if(bType	==	CDES::ENCRYPT)
				{
					memcpy(cvec,Out,8);			//将输出设定为扭转变量
				}
				else
				{
					for(int j=0;j<8;++j)		//将输出与扭转变量异或
					{
						Out[j]	=	Out[j] ^ cvec[j];
					}
					memcpy(cvec,cvin,8);			//将输入设定为扭转变量
				}
			}
		}
		else			//3DES CBC 3Key
		{
			for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
			{
				if(bType	==	CDES::ENCRYPT)
				{
					for(int j=0;j<8;++j)		//将输入与扭转变量异或
					{
						cvin[j]	=	In[j] ^ cvec[j];
					}
				}
				else
				{
					memcpy(cvin,In,8);
				}
				
				DES(Out,cvin,&m_SubKey[bType ? 2 : 0],bType);
				DES(Out,Out,&m_SubKey[1],!bType);
				DES(Out,Out,&m_SubKey[bType ? 0 : 2],bType);
				
				if(bType	==	CDES::ENCRYPT)
				{
					memcpy(cvec,Out,8);			//将输出设定为扭转变量
				}
				else
				{
					for(int j=0;j<8;++j)		//将输出与扭转变量异或
					{
						Out[j]	=	Out[j] ^ cvec[j];
					}
					memcpy(cvec,cvin,8);			//将输入设定为扭转变量
				}
			}
		}
	}
	
	return true;
}




/*******************************************************************/
/*
  函 数 名 称:	RunPad
  功 能 描 述:	根据协议对加密前的数据进行填充
  参 数 说 明:	bType	:类型:PAD类型
				In		:数据串指针
				Out		:填充输出串指针
				datalen	:数据的长度
				padlen	:(in,out)输出buffer的长度,填充后的长度

  返回值 说明:	bool	:是否填充成功
  作       者:	邹德强
  修 改 历 史:	

  更 新 日 期:	2003.12.19
/*******************************************************************/
bool	CDES::RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen)
{
	int res = (datalen & 0x00000007);
	
	
	if(padlen< (datalen+8-res))
	{
		return false;
	}
	else
	{
		padlen	=	(datalen+8-res);
		memcpy(Out,In,datalen);
	}
	
	
	if(nType	==	PAD_ISO_1)
	{
		memset(Out+datalen,0x00,8-res);
	}
	else
	if(nType	==	PAD_ISO_2)
	{
		memset(Out+datalen,0x80,1);
		memset(Out+datalen,0x00,7-res);
	}
	else
	if(nType	==	PAD_PKCS_7)
	{
		memset(Out+datalen,8-res,8-res);
	}
	else
	{
		return false;
	}

	return true;
}




//计算并填充子密钥到SubKey数据中
void CDES::SetSubKey(PSubKey pSubKey, const char Key[8])
{
	bool K[64], *KL=&K[0], *KR=&K[28];
    ByteToBit(K, Key, 64);
    Transform(K, K, PC1_Table, 56);
    for(int i=0; i<16; ++i) {
        RotateL(KL, 28, LOOP_Table[i]);
        RotateL(KR, 28, LOOP_Table[i]);
        Transform((*pSubKey)[i], K, PC2_Table, 48);
    }
}



//DES单元运算
void CDES::DES(char Out[8], char In[8], const PSubKey pSubKey, bool Type)
{
    bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
    ByteToBit(M, In, 64);
    Transform(M, M, IP_Table, 64);
    if( Type == ENCRYPT )
	{
        for(int i=0; i<16; ++i)
		{
            memcpy(tmp, Ri, 32);		//Ri[i-1] 保存
            F_func(Ri, (*pSubKey)[i]);	//Ri[i-1]经过转化和SBox输出为P
            Xor(Ri, Li, 32);			//Ri[i] = P XOR Li[i-1]
            memcpy(Li, tmp, 32);		//Li[i] = Ri[i-1]
        }
    }
	else
	{
        for(int i=15; i>=0; --i) 
		{
			memcpy(tmp, Ri, 32);		//Ri[i-1] 保存
            F_func(Ri, (*pSubKey)[i]);	//Ri[i-1]经过转化和SBox输出为P
            Xor(Ri, Li, 32);			//Ri[i] = P XOR Li[i-1]
            memcpy(Li, tmp, 32);		//Li[i] = Ri[i-1]
        }
	}
	RotateL(M,64,32);					//Ri与Li换位重组M
    Transform(M, M, IPR_Table, 64);		//最后结果进行转化
    BitToByte(Out, M, 64);				//组织成字符
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -