代码之家  ›  专栏  ›  技术社区  ›  Boardy

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

  •  -1
  • Boardy  · 技术社区  · 10 年前

    我目前正在学习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;
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   zaph    10 年前

    简单地说:加密的结果是相同的,它们只是采用了不同的编码。 bb5ef912a40cb9f16b91b3a7fccc2bc8 是 hexadecimal 编码和 u175EqQMufFrkbOn/MwryA== 是 Base64

        2
  •  1
  •   deviantfan    10 年前


    代替

    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;