将C#加密转换为C ++加密

时间:2016-10-01 13:29:31

标签: c++ encryption

我目前正在学习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库

更新

我有点笨拙,没注意到字符串被转换为十六进制,我不是100%确定openssl加密器是否进行了base 64编码。

所以我现在正在尝试将已加密的内容转换为基本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;
}

当我加密字符串Hello时,我希望基本64位编码的字符串为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;

2 个答案:

答案 0 :(得分:1)

简单地说:加密的结果是相同的,它们只是在不同的编码中。 bb5ef912a40cb9f16b91b3a7fccc2bc8hexadecimal编码且u175EqQMufFrkbOn/MwryA==Base64编码。它们的价值相同。

答案 1 :(得分:1)

关于Base64部分:
取代

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;

HelperMethods helperMethods;
string converted = helperMethods.base64Encode(encrypted.data(), encrypted.size());
cout << "Converted: " << converted << endl;