C#加密代码和c++加密代码不匹配

问题描述

我正在用 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 (将#修改为@)