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

📄 rijndael.cpp

📁 很好的文件加密程序,用vc++编的,适合初学者!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}

//DESTRUCTOR
CRijndael::~CRijndael()
{
}

//Expand a user-supplied key material into a session key.
// key        - The 128/192/256-bit user-key to use.
// chain      - initial chain block for CBC and CFB modes.
// keylength  - 16, 24 or 32 bytes
// blockSize  - 16, 24 or 32 bytes
void CRijndael::Initialize(char const* keydata, int keydatalength, char const* chain, int keylength,
	int blockSize, int iMode, int iPadding)
{
	//Check Initialization Data
	if(NULL == keydata)
		throw runtime_error(string(sm_szErrorMsg4));
	if(keydatalength < 1)
		throw runtime_error(string(sm_szErrorMsg5));
	if(!(KL16==keylength || KL24==keylength || KL32==keylength))
		throw runtime_error(string("Illegal Key Length!"));
	if(!(BS16==blockSize || BS24==blockSize || BS32==blockSize))
		throw runtime_error(string(sm_szErrorMsg6));
	if(iMode<ECB || iMode>CFB)
		throw runtime_error(string(sm_szErrorMsg2));
	if(iPadding<ZEROES || iPadding>PKCS7)
		throw runtime_error(string(sm_szErrorMsg3));
	m_iMode = iMode;
	m_iPadding = iPadding;
	//Create the Key from Key Data
	int i, j;
	char key[KL32];
	for(i=0,j=0; i<keylength; i++,j=(j+1)%keydatalength)
		key[i] = keydata[j];
	//Initialize the chain
	m_blockSize = blockSize;
	memcpy(m_chain0, chain, m_blockSize);
	memcpy(m_chain, m_chain0, m_blockSize);
	//Initialize the key
	m_keylength = keylength;
	memcpy(m_acKey, key, m_keylength);
	//Calculate Number of Rounds
	switch(m_keylength)
	{
		case 16:
			m_iROUNDS = (m_blockSize == 16) ? 10 : (m_blockSize == 24 ? 12 : 14);
			break;

		case 24:
			m_iROUNDS = (m_blockSize != 32) ? 12 : 14;
			break;

		default: // 32 bytes = 256 bits
			m_iROUNDS = 14;
	}
	int BC = m_blockSize / 4;
	//Encryption round keys
	//Initialize to 0
	for(i=0; i<=m_iROUNDS; i++)
	{
		for(j=0; j<BC; j++)
			m_Ke[i][j] = 0;
	}
	//Decryption round keys
	//Initialize to 0
	for(i=0; i<=m_iROUNDS; i++)
	{
		for(j=0; j<BC; j++)
			m_Kd[i][j] = 0;
	}
	int ROUND_KEY_COUNT = (m_iROUNDS + 1) * BC;
	int KC = m_keylength/4;
	//Copy user material bytes into temporary ints
	int* pi = tk;
	char const* pc = key;
	for(i=0; i<KC; i++)
	{
		*pi = (unsigned char)*(pc++) << 24;
		*pi |= (unsigned char)*(pc++) << 16;
		*pi |= (unsigned char)*(pc++) << 8;
		*(pi++) |= (unsigned char)*(pc++);
	}
	//Copy values into round key arrays
	int t = 0;
	for(j=0; (j<KC)&&(t<ROUND_KEY_COUNT); j++,t++)
	{
		m_Ke[t/BC][t%BC] = tk[j];
		m_Kd[m_iROUNDS - (t/BC)][t%BC] = tk[j];
	}
	int tt, rconpointer = 0;
	while(t < ROUND_KEY_COUNT)
	{
		//Extrapolate using phi (the round key evolution function)
		tt = tk[KC-1];
		tk[0] ^= (sm_S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^
			(sm_S[(tt >>  8) & 0xFF] & 0xFF) << 16 ^
			(sm_S[ tt & 0xFF] & 0xFF) <<  8 ^
			(sm_S[(tt >> 24) & 0xFF] & 0xFF) ^
			(sm_rcon[rconpointer++]  & 0xFF) << 24;
		if(KC != 8)
			for(i=1, j=0; i<KC;)
				tk[i++] ^= tk[j++];
		else
		{
			for(i=1, j=0; i<KC/2; )
				tk[i++] ^= tk[j++];
			tt = tk[KC/2-1];
			tk[KC/2] ^= (sm_S[ tt & 0xFF] & 0xFF) ^
				(sm_S[(tt >>  8) & 0xFF] & 0xFF) <<  8 ^
				(sm_S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^
				(sm_S[(tt >> 24) & 0xFF] & 0xFF) << 24;
			for(j = KC/2, i=j+1; i<KC; )
				tk[i++] ^= tk[j++];
		}
		//Copy values into round key arrays
		for(j=0; (j<KC) && (t<ROUND_KEY_COUNT); j++, t++)
		{
			m_Ke[t/BC][t%BC] = tk[j];
			m_Kd[m_iROUNDS - (t/BC)][t%BC] = tk[j];
		}
	}
	//Inverse MixColumn where needed
	for(int r=1; r<m_iROUNDS; r++)
		for(j=0; j<BC; j++)
		{
			tt = m_Kd[r][j];
			m_Kd[r][j] = sm_U1[(tt >> 24) & 0xFF] ^
				sm_U2[(tt >> 16) & 0xFF] ^
				sm_U3[(tt >>  8) & 0xFF] ^
				sm_U4[tt & 0xFF];
		}
	//Initialization Flag
	m_bInit = true;
}

//Resetting the Initialization Vector
void CRijndael::ResetChain()
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	memcpy(m_chain, m_chain0, m_blockSize);
}

//Compute Signature
void CRijndael::Signature(char* pcSig)
{
	//8+32+2+2+1+1+1
	char acSigData[48] = {0};
	strcat(acSigData, "RIJNDAEL");
	int iLen = strlen(acSigData);
	memcpy(acSigData+iLen, m_acKey, m_keylength);
	sprintf(acSigData+iLen+m_keylength, "%d%d%d%d", m_blockSize, m_keylength, m_iMode, m_iPadding);
	CSHA oSHA;
	oSHA.AddData(acSigData, strlen(acSigData));
	oSHA.FinalDigest(pcSig);
}

//Convenience method to encrypt exactly one block of plaintext, assuming
//Rijndael's default block size (128-bit).
// in         - The plaintext
// result     - The ciphertext generated from a plaintext using the key
void CRijndael::DefEncryptBlock(char const* in, char* result)
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	int* Ker = m_Ke[0];
	int t0 = ((unsigned char)*(in++) << 24);
	t0 |= ((unsigned char)*(in++) << 16);
	t0 |= ((unsigned char)*(in++) << 8);
	(t0 |= (unsigned char)*(in++)) ^= Ker[0];
	int t1 = ((unsigned char)*(in++) << 24);
	t1 |= ((unsigned char)*(in++) << 16);
	t1 |= ((unsigned char)*(in++) << 8);
	(t1 |= (unsigned char)*(in++)) ^= Ker[1];
	int t2 = ((unsigned char)*(in++) << 24);
	t2 |= ((unsigned char)*(in++) << 16);
	t2 |= ((unsigned char)*(in++) << 8);
	(t2 |= (unsigned char)*(in++)) ^= Ker[2];
	int t3 = ((unsigned char)*(in++) << 24);
	t3 |= ((unsigned char)*(in++) << 16);
	t3 |= ((unsigned char)*(in++) << 8);
	(t3 |= (unsigned char)*(in++)) ^= Ker[3];
	int a0, a1, a2, a3;
	//Apply Round Transforms
	for (int r = 1; r < m_iROUNDS; r++)
	{
		Ker = m_Ke[r];
		a0 = (sm_T1[(t0 >> 24) & 0xFF] ^
			sm_T2[(t1 >> 16) & 0xFF] ^
			sm_T3[(t2 >>  8) & 0xFF] ^
			sm_T4[t3 & 0xFF]) ^ Ker[0];
		a1 = (sm_T1[(t1 >> 24) & 0xFF] ^
			sm_T2[(t2 >> 16) & 0xFF] ^
			sm_T3[(t3 >>  8) & 0xFF] ^
			sm_T4[t0 & 0xFF]) ^ Ker[1];
		a2 = (sm_T1[(t2 >> 24) & 0xFF] ^
			sm_T2[(t3 >> 16) & 0xFF] ^
			sm_T3[(t0 >>  8) & 0xFF] ^
			sm_T4[t1 & 0xFF]) ^ Ker[2];
		a3 = (sm_T1[(t3 >> 24) & 0xFF] ^
			sm_T2[(t0 >> 16) & 0xFF] ^
			sm_T3[(t1 >>  8) & 0xFF] ^
			sm_T4[t2 & 0xFF]) ^ Ker[3];
		t0 = a0;
		t1 = a1;
		t2 = a2;
		t3 = a3;
	}
	//Last Round is special
	Ker = m_Ke[m_iROUNDS];
	int tt = Ker[0];
	result[0] = sm_S[(t0 >> 24) & 0xFF] ^ (tt >> 24);
	result[1] = sm_S[(t1 >> 16) & 0xFF] ^ (tt >> 16);
	result[2] = sm_S[(t2 >>  8) & 0xFF] ^ (tt >>  8);
	result[3] = sm_S[t3 & 0xFF] ^ tt;
	tt = Ker[1];
	result[4] = sm_S[(t1 >> 24) & 0xFF] ^ (tt >> 24);
	result[5] = sm_S[(t2 >> 16) & 0xFF] ^ (tt >> 16);
	result[6] = sm_S[(t3 >>  8) & 0xFF] ^ (tt >>  8);
	result[7] = sm_S[t0 & 0xFF] ^ tt;
	tt = Ker[2];
	result[8] = sm_S[(t2 >> 24) & 0xFF] ^ (tt >> 24);
	result[9] = sm_S[(t3 >> 16) & 0xFF] ^ (tt >> 16);
	result[10] = sm_S[(t0 >>  8) & 0xFF] ^ (tt >>  8);
	result[11] = sm_S[t1 & 0xFF] ^ tt;
	tt = Ker[3];
	result[12] = sm_S[(t3 >> 24) & 0xFF] ^ (tt >> 24);
	result[13] = sm_S[(t0 >> 16) & 0xFF] ^ (tt >> 16);
	result[14] = sm_S[(t1 >>  8) & 0xFF] ^ (tt >>  8);
	result[15] = sm_S[t2 & 0xFF] ^ tt;
}

//Convenience method to decrypt exactly one block of plaintext, assuming
//Rijndael's default block size (128-bit).
// in         - The ciphertext.
// result     - The plaintext generated from a ciphertext using the session key.
void CRijndael::DefDecryptBlock(char const* in, char* result)
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	int* Kdr = m_Kd[0];
	int t0 = ((unsigned char)*(in++) << 24);
	t0 = t0 | ((unsigned char)*(in++) << 16);
	t0 |= ((unsigned char)*(in++) << 8);
	(t0 |= (unsigned char)*(in++)) ^= Kdr[0];
	int t1 = ((unsigned char)*(in++) << 24);
	t1 |= ((unsigned char)*(in++) << 16);
	t1 |= ((unsigned char)*(in++) << 8);
	(t1 |= (unsigned char)*(in++)) ^= Kdr[1];
	int t2 = ((unsigned char)*(in++) << 24);
	t2 |= ((unsigned char)*(in++) << 16);
	t2 |= ((unsigned char)*(in++) << 8);
	(t2 |= (unsigned char)*(in++)) ^= Kdr[2];
	int t3 = ((unsigned char)*(in++) << 24);
	t3 |= ((unsigned char)*(in++) << 16);
	t3 |= ((unsigned char)*(in++) << 8);
	(t3 |= (unsigned char)*(in++)) ^= Kdr[3];
	int a0, a1, a2, a3;
	for(int r = 1; r < m_iROUNDS; r++) // apply round transforms
	{
		Kdr = m_Kd[r];
		a0 = (sm_T5[(t0 >> 24) & 0xFF] ^
			sm_T6[(t3 >> 16) & 0xFF] ^
			sm_T7[(t2 >>  8) & 0xFF] ^
			sm_T8[ t1        & 0xFF] ) ^ Kdr[0];
		a1 = (sm_T5[(t1 >> 24) & 0xFF] ^
			sm_T6[(t0 >> 16) & 0xFF] ^
			sm_T7[(t3 >>  8) & 0xFF] ^
			sm_T8[ t2        & 0xFF] ) ^ Kdr[1];
		a2 = (sm_T5[(t2 >> 24) & 0xFF] ^
			sm_T6[(t1 >> 16) & 0xFF] ^
			sm_T7[(t0 >>  8) & 0xFF] ^
			sm_T8[ t3        & 0xFF] ) ^ Kdr[2];
		a3 = (sm_T5[(t3 >> 24) & 0xFF] ^
			sm_T6[(t2 >> 16) & 0xFF] ^
			sm_T7[(t1 >>  8) & 0xFF] ^
			sm_T8[ t0        & 0xFF] ) ^ Kdr[3];
		t0 = a0;
		t1 = a1;
		t2 = a2;
		t3 = a3;
	}
	//Last Round is special
	Kdr = m_Kd[m_iROUNDS];
	int tt = Kdr[0];
	result[ 0] = sm_Si[(t0 >> 24) & 0xFF] ^ (tt >> 24);
	result[ 1] = sm_Si[(t3 >> 16) & 0xFF] ^ (tt >> 16);
	result[ 2] = sm_Si[(t2 >>  8) & 0xFF] ^ (tt >>  8);
	result[ 3] = sm_Si[ t1 & 0xFF] ^ tt;
	tt = Kdr[1];
	result[ 4] = sm_Si[(t1 >> 24) & 0xFF] ^ (tt >> 24);
	result[ 5] = sm_Si[(t0 >> 16) & 0xFF] ^ (tt >> 16);
	result[ 6] = sm_Si[(t3 >>  8) & 0xFF] ^ (tt >>  8);
	result[ 7] = sm_Si[ t2 & 0xFF] ^ tt;
	tt = Kdr[2];
	result[ 8] = sm_Si[(t2 >> 24) & 0xFF] ^ (tt >> 24);
	result[ 9] = sm_Si[(t1 >> 16) & 0xFF] ^ (tt >> 16);
	result[10] = sm_Si[(t0 >>  8) & 0xFF] ^ (tt >>  8);
	result[11] = sm_Si[ t3 & 0xFF] ^ tt;
	tt = Kdr[3];
	result[12] = sm_Si[(t3 >> 24) & 0xFF] ^ (tt >> 24);
	result[13] = sm_Si[(t2 >> 16) & 0xFF] ^ (tt >> 16);
	result[14] = sm_Si[(t1 >>  8) & 0xFF] ^ (tt >>  8);
	result[15] = sm_Si[ t0 & 0xFF] ^ tt;
}

//Encrypt exactly one block of plaintext.
// in           - The plaintext.
// result       - The ciphertext generated from a plaintext using the key.

⌨️ 快捷键说明

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