2016-10-01 91 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;