问题描述
我正在用 c++/c# 实现加密/解密代码 我提到了 this post 并提到了 answers.z`
但是没有匹配到c++/c#加密的代码。
这是我的代码。
C++
// base64 encode part
static const std::string base64_chars =
"ABCDEFGHIJKLMnopQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(BYTE c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(BYTE const* buf,unsigned int bufLen) {
std::string ret;
int i = 0;
int j = 0;
BYTE char_array_3[3];
BYTE char_array_4[4];
while (bufLen--) {
char_array_3[i++] = *(buf++);
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;
}
//start encrypt
std::string key = "01286567891233460123456789a12345";
std::string iv = "0123456789123456";
std::string encrypt(const std::string& str_in)
{
std::string str_out;
std::string str_out2;
byte* keybyte = (byte*)key.c_str();
CryptoPP::AES::Encryption aesEncryption((byte*)key.c_str(),CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption,(byte*)iv.c_str());
StreamTransformationFilter stfEncryptor(cbcEncryption,new CryptoPP::StringSink(str_out));
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(str_in.c_str()),str_in.length() + 1);
stfEncryptor.MessageEnd();
str_out2 = base64_encode(reinterpret_cast<const unsigned char*>(str_out.c_str()),strlen(str_out.c_str()));
return str_out2;
}
std::string decrypt(const std::string& cipher_text)
{
std::string str_out;
//need to insert code of decrypt base64
CryptoPP::AES::Decryption aesDecryption((byte*)key.c_str(),CryptoPP::AES::MAX_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption,(byte*)iv.c_str());
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption,new CryptoPP::StringSink(str_out));
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(cipher_text.c_str()),cipher_text.size());
stfDecryptor.MessageEnd();
return str_out;
}
c#
public string Encrypt(string testCode)
{
string clearText = testCode;
byte[] clearBytes = Encoding.Default.GetBytes(clearText);
using (Aes encryptor = Aes.Create("AES"))
{
//encryptor.BlockSize = 128;
encryptor.Padding = PaddingMode.Zeros;
encryptor.KeySize = 128;
encryptor.Mode = CipherMode.CBC;
encryptor.Key = Encoding.Default.GetBytes("01286567891233460123456789a12345");
encryptor.IV = Encoding.Default.GetBytes("0123456789123456");
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms,encryptor.CreateEncryptor(),CryptoStreamMode.Write))
{
cs.Write(clearBytes,clearBytes.Length);
cs.Close();
}
byte[] bt = ms.ToArray();
clearText = Convert.ToBase64String(bt); //clearText = Encoding.Default.GetString(bt);
}
}
return clearText; //Return the encrypted command
}
public string Decrypt(string cipherText)
{
byte[] clearBytes = Convert.FromBase64String(cipherText);
using (Aes decryptor = Aes.Create("AES"))
{
// decryptor.BlockSize = 128;
decryptor.Padding = PaddingMode.Zeros;
decryptor.KeySize = 128;
decryptor.Mode = CipherMode.CBC;
decryptor.Key = Encoding.Default.GetBytes("01286567891233460123456789a12345");
decryptor.IV = Encoding.Default.GetBytes("0123456789123456");
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms,decryptor.CreateDecryptor(),clearBytes.Length);
cs.Close();
}
byte[] bt = ms.ToArray();
cipherText = Encoding.Default.GetString(bt);
}
}
return cipherText; //Return the decrypted text
}
c++ 结果
encrypted code : ks8zzu20w6zURkuZMgbx8g==
decrypted code : test
c# 结果
encrypted code : nsWRYBylyjVaJ5Yckk+SRw==
decrypted code : test
我用 test 两个 C++/C# 单词进行了测试,但是加密代码不匹配。
另外,我在删除base64编码后进行了测试,但也没有匹配纯加密代码。
有人可以分享您的知识吗?
编辑 1
我尝试用 c++ 复制加密代码并粘贴到 c# 解密代码,如下所示
string testcode = "ks8zzu20w6zURkuZMgbx8g=="
Decrypt(testcode)
//result - test↗↗↗↗↗
如您所见,结果看起来非常相似,但有些奇怪。 ↗ 这个符号加在test这个词之后。 我不知道为什么会出现这样的结果。有什么我错过的吗?
已解决
std::string encrypt(const std::string& str_in)
{
std::string str_out;
std::string str_out2;
byte* keybyte = (byte*)key.c_str();
CryptoPP::AES::Encryption aesEncryption((byte*)key.c_str(),new CryptoPP::StringSink(str_out));
// 'str_in.length() + 1' in the line below makes the encryption code different from c# code.
/*stfEncryptor.Put(reinterpret_cast<const unsigned char*>(str_in.c_str()),str_in.length() + 1);*/
stfEncryptor.Put(reinterpret_cast<const unsigned char*>(str_in.c_str()),str_in.length());
stfEncryptor.MessageEnd();
str_out2 = cryptobase64_encode(str_out);
return str_out2;
}
正如我所评论的,str_in.length() + 1 使加密代码不同于 C# 代码。
并且我将 C# 填充选项从 Zeros 更改为 PKCS7 以匹配 C++ 加密代码。 但我不知道为什么我需要设置这个选项。我想我需要研究这个。 无论如何,它运作良好。特别感谢@jdweng。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)