我目前正在学习C++并打算将其用于一个项目,但我需要能够加密和解密字符串。
我有各种语言的转换代码,例如C#、Java和PHP,它们可以一起工作,例如,C#和/或/Java和/或PHP可以将加密字符串写入数据库,任何这些语言都可以从数据库读取值并解密。
以下是C#代码示例:
public static string encrypt(string encryptionString)
{
byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString);
SymmetricAlgorithm rijn = SymmetricAlgorithm.Create();
MemoryStream ms = new MemoryStream();
byte[] rgbIV = Encoding.ASCII.GetBytes("ryojvlzmdalyglrj");
byte[] key = Encoding.ASCII.GetBytes("hcxilkqbbhczfeultgbskdmaunivmfuo");
CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write);
cs.Write(clearTextBytes, 0, clearTextBytes.Length);
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
我用C语言尝试了以下内容++
void Encryption::encryptString(string stringToEncrypt)
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
//string key = "hcxilkqbbhczfeultgbskdmaunivmfuo";
//string iv = "ryojvlzmdalyglrj";
unsigned char key[33] = "hcxilkqbbhczfeultgbskdmaunivmfuo";
unsigned char iv[17] = "ryojvlzmdalyglrj";
vector<unsigned char> encrypted;
size_t max_output_len = stringToEncrypt.length() + 16 - (stringToEncrypt.length() % 16);
//size_t max_output_len = 16 - (stringToEncrypt.length() % 16);
encrypted.resize(max_output_len);
EVP_CipherInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv, 1);
// EVP_CipherUpdate can encrypt all your data at once, or you can do
// small chunks at a time.
int actual_size = 0;
EVP_CipherUpdate(&ctx,
&encrypted[0], &actual_size,
reinterpret_cast<unsigned char *>(&stringToEncrypt[0]), stringToEncrypt.size());
// EVP_CipherFinal_ex is what applies the padding. If your data is
// a multiple of the block size, you'll get an extra AES block filled
// with nothing but padding.
int final_size;
EVP_CipherFinal_ex(&ctx, &encrypted[actual_size], &final_size);
actual_size += final_size;
encrypted.resize(actual_size);
for (size_t index = 0; index < encrypted.size(); ++index)
{
std::cout << std::hex << std::setw(2) << std::setfill('0') <<
static_cast<unsigned int>(encrypted[index]);
}
std::cout << "\n";
EVP_CIPHER_CTX_cleanup(&ctx);
}
例如,在C++中,我得到
bb5ef912a40cb9f16b91b3a7fccc2bc8
而如果我加密
Hello
用我掌握的任何其他语言
u175EqQMufFrkbOn/MwryA==
我已将项目链接到openssl库
使现代化
我有点无聊,没有注意到字符串被转换为十六进制,我也不能百分之百确定openssl加密程序是否采用了base64编码。
因此,我现在尝试将加密的内容转换为一个base 64字符串。
下面是进行编码的C++编码代码:
string HelperMethods::base64Encode(const char* buffer, int in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(buffer++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
当我加密字符串时
你好
我预计base64编码的字符串
u175EqQMufFrkbOn/MwryA==
但当我在C++代码中运行它时,我得到了以下结果:
u175EqQMufFrkbOn/MwryADNzc3Nzc3Nzc3Nzc3Nzc39/f39NjQAAA==
正如你所看到的,我在那里要少得多,只是因为某些原因,它比我预期的要大得多,
NZc3
似乎出于某种原因不断重复。
我从加密函数调用编码器,如下所示
char * buff_str = (char*)malloc(encrypted.size() * 2 + 1);
char * buff_ptr = buff_str;
for (size_t index = 0; index < encrypted.size(); ++index)
{
buff_ptr += sprintf(buff_ptr, "%c", encrypted[index]);
}
string encryptedString = buff_str;
HelperMethods helperMethods;
string converted = helperMethods.base64Encode(encryptedString.c_str(), sizeof(encryptedString));
cout << "Converted: " << converted << endl;