2016-10-01 62 views
-1

我目前在学习C++并正在研究如何将它用于项目,但我需要能够加密和解密字符串。我有转换代码在各种语言,如C#,Java和PHP,他们可以一起工作,例如,C#和/或/ Java和/或PHP可以编写一个加密的字符串数据库和任何这些语言可以读取数据库中的值并解密。将C#加密转换为C++加密

下面是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而如果我在任何其他语言我有我得到u175EqQMufFrkbOn/MwryA==

我有联系的项目OpenSSL库

感谢您的帮助,您可以的加密Hello提供。

UPDATE

我是有点numpty的,没有注意到该字符串被转换为十六进制,我是不是100%确定OpenSSL的加密器是否确实基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我expectin底座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; 

感谢

+0

什么加密算法并不'SymmetricAlgorithm.Create();'实例? –

+0

@RichardCritten Rijndael https://msdn.microsoft.com/en-us/library/z851sbdb%28v=vs.110%29.aspx – deviantfan

+1

@OP:你在C++中得到的不是Base64。 – deviantfan

回答

1

如下简单:加密的结果是一样的,他们只是在不同的编码。 bb5ef912a40cb9f16b91b3a7fccc2bc8是编码的hexadecimal和编码的u175EqQMufFrkbOn/MwryA==Base64。他们是相同的价值。

+0

谢谢,我已经更新了我的问题,我有一个与base64编码的概率。 – Boardy

+1

啊,我怀疑它,我做了sizeof(string)而不是string.length() – Boardy

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;