数据加密解密是一个常用的功能,如果你不希望让别人看到文件中的内容,可以通过密钥(也称”密码“)将文件的内容加密。比如文本文件(.txt),加密前的内容是能够读懂的,加密后的内容是”乱码“,都是一些奇怪的字符,根本无法阅读。
数据加密解密的原理也很简单,就是使用异或运算。请先看下面的代码:
#include<stdio.h> #include<stdlib.h> int main() { #pragma warning(suppress : 4996) char plaintext = 'a'; //明文 char secretkey = '!'; //密钥 char ciphertext = plaintext ^ secretkey; //密文 char decodetext = ciphertext ^ secretkey; //解密后的字符 char buffer[9]; printf(" char ASCII\n"); // itoa()用来将数字转换为字符串,可以设定转换时的进制(基数) // 这里将字符对应的ascii码转换为二进制 printf(" plaintext %c %7s\n", plaintext, itoa(plaintext, buffer, 2)); printf(" secretkey %c %7s\n", secretkey, itoa(secretkey, buffer, 2)); printf("ciphertext %c %7s\n", ciphertext, itoa(ciphertext, buffer, 2)); printf("decodetext %c %7s\n", decodetext, itoa(decodetext, buffer, 2)); return 0; }
运行结果:
char ASCII plaintext a 1100001 secretkey ! 100001 ciphertext @ 1000000 decodetext a 1100001
看到了吗,plaintext 与 decodetext相同,也就是说,两次异或运算后还是原来的结果。
这就是加密的关键技术:
1、通过一次异或运算,生成密文,密文没有可读性,与原文风马牛不相及,这就是加密;
2、密文再经过一次异或运算,就会还原成原文,这就是解密的过程;
3、加密和解密需要相同的密钥,如果密钥不对,是无法成功解密的。
上面的加密算法称为对称加密算法,加密和解密使用同一个密钥。
如果加密和解密的密钥不同,则称为非对称加密算法。在非对称算法中,加密的密钥称为公钥,解密的密钥称为私钥,只知道公钥是无法解密的,还必须知道私钥。
注意:程序中的 itoa() 位于 stdlib.h 头文件,它并不是一个标准的C函数,只有Windows下有,
使用异或运算对数据及文件进行加密处理
typedef struct CRYPT_BLOCK { DWORD dwSize; // Data的 DWORD dwKey; // 密钥 循环使用DWORD的每个字节来进行加密 详情见XorEncrypt char chData[1]; // 加密后的数据 } CRYPT_BLOCK, *PCRYPT_BLOCK; typedef boost::shared_ptr<Json::Value> JsonSharedPtr;
一个数异或另一个数两次后,该数保持不变。即:
c = a^b; c = c^b; c == a;
这一规律就是使用异或运算对数据及文件进行加密处理的基本原理。
bool XorEncrypt(const char* pKey, DWORD dwCbKey, const char* pIn, DWORD dwCbSize, char* pOut) { if (pIn == NULL || pOut == NULL || pKey == NULL) { return false; } for (DWORD i = 0; i < dwCbSize; ++i) { pOut[i] = pIn[i] ^ pKey[i % dwCbKey]; } return true; }
pKey为密钥数据指针,dwCbKey为密钥数据长度,pIn为需要加密的数据指针,dwCbSize为需要加密的数据长度,pOut为加密后数据指针
加密函数:
vector<char> Encrypt(const vector<char> &vecPlainData) { vector<char> vecCryptedData; do { if (vecPlainData.empty()) { break; } if (UINT_MAX - vecPlainData.size() < sizeof(CRYPT_BLOCK) - 1) { //溢出 break; } //文件里的加密信息是分成一个一个数据块CRYPT_BLOCK存放的 //只是用异或简单加密一下,具体加密流程见XorEncrypt函数 DWORD dwCryptBlockSize = sizeof(CRYPT_BLOCK) - 1 + vecPlainData.size(); vecCryptedData.resize(dwCryptBlockSize); PCRYPT_BLOCK CryptedBlock = (PCRYPT_BLOCK)&vecCryptedData[0]; CryptedBlock->dwKey = GenerateKey(); CryptedBlock->dwSize = vecPlainData.size(); bool bOk = XorEncrypt((char*)&CryptedBlock->dwKey, sizeof CryptedBlock->dwKey, &vecPlainData[0], vecPlainData.size(), CryptedBlock->chData); if (!bOk) { vecCryptedData.clear(); } } while (false); return vecCryptedData; }
解密函数:
vector<char> Decrypt(const vector<char> &vecCryptedData) { PCRYPT_BLOCK pCryptedBlock = NULL; vector<char> vecPlainData; do { if (vecCryptedData.size() < sizeof *pCryptedBlock) { break; } pCryptedBlock = (PCRYPT_BLOCK)&vecCryptedData[0]; if (UINT_MAX - pCryptedBlock->dwSize < sizeof *pCryptedBlock - 1) { //溢出 break; } //运算符优先级 sizeof > 加减 > 不等 if (pCryptedBlock->dwSize + sizeof *pCryptedBlock - 1 != vecCryptedData.size()) { break; } vecPlainData.resize(pCryptedBlock->dwSize); bool ok = XorEncrypt((char *)&pCryptedBlock->dwKey, sizeof pCryptedBlock->dwKey, pCryptedBlock->chData, pCryptedBlock->dwSize, &vecPlainData[0]); if (!ok) { vecPlainData.clear(); } } while (false); return vecPlainData; }
生成Key:
BYTE CHipsLogQueue::RandomByte() { unsigned int random; rand_s(&random); return BYTE(random); } DWORD CHipsLogQueue::GenerateKey() { DWORD Key = 0; for (int i = 0; i < 4; ++i) { ((BYTE *)(&Key))[i] = RandomByte(); } return Key; }
标签:文件,加密,运算,pCryptedBlock,vecPlainData,char,密钥,BLOCK From: https://www.cnblogs.com/-hz01/p/18077811