2012-01-09 147 views
1

我正在研究利用C#服务器和C++客户端的应用程序,并在两个应用程序之间传输许可数据。为了安全起见,我显然希望对这些许可证进行加密,但是我在查找符合C++目标的库时遇到了一些问题。也就是说,我已经尝试了Crypto ++和CryptoAPI。 Crypto ++似乎是一个不错的易用库,但Crypto ++的加密和C#加密的结果是不同的。 CryptoAPI可以完成这项工作,因为它由微软维护,但是API很混乱,难以理解。另外,奇怪的是,C#在每个运行时都会生成相同的加密输出,即使我没有触及IV的随机生成。 Crypto ++不会这样做(输出随随机IV下的每个运行时间而变化)。从C#到C++的加密/解密

有没有人有任何建议或指引?我为Crypto ++和C#使用CBC模式,所以我不认为这是一个问题。我目前正在使用TripleDES让程序首先运行。我应该使用不同的算法(我肯定会一旦完成)?

代码,如要求(我们对此深感抱歉):

public static string Encrypt(string ToEncrypt, string Key) 
{ 
    byte[] keyArray = UTF8Encoding.UTF8.GetBytes(Key); 
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(ToEncrypt); 
    TripleDESCryptoServiceProvider tDes = new TripleDESCryptoServiceProvider(); 

    tDes.Key = keyArray; 
    tDes.Mode = CipherMode.CBC; 
    tDes.Padding = PaddingMode.PKCS7; 
    ICryptoTransform cTransform = tDes.CreateEncryptor(); 
    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 
    tDes.Clear(); 
    return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
} 

和解密(C++):

std::string Decrypt(std::string ToDecrypt, string Key) 
{ 
    const byte *byteKey = (byte*) Key.c_str(); 
    CryptoPP::SecByteBlock key(CryptoPP::DES_EDE2::DEFAULT_KEYLENGTH); 
    key.Assign(byteKey, Key.length()); 
    byte iv[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; 

    try { 
     std::string recovered, cipher; 
     CryptoPP::CBC_Mode<CryptoPP::DES_EDE2>::Decryption d; 
     d.SetKeyWithIV(key, key.size(), iv); 

     CryptoPP::StringSource(ToDecrypt, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(cipher))); 
     CryptoPP::StringSource(cipher, true, new CryptoPP::StreamTransformationFilter(d, new CryptoPP::StringSink(recovered))); 

     std::cout << "Recovered: " << recovered << std::endl; 
     return recovered; 
    } catch (const CryptoPP::Exception &e) { 
     std::cout << e.what() << std::endl; 
     exit(1); 
    } 
} 
+2

我们需要代码和输出来查看IV部分出错的位置。 – 2012-01-09 22:00:16

+0

只需添加代码。对于那个很抱歉。 – jForshee 2012-01-09 22:42:55

+0

@jForshee:你的'Decrypt'函数不使用它传递的'Key'参数 - 这是故意的吗? – ildjarn 2012-01-09 23:14:27

回答

1

//Decryption Dll

extern "C" 

{ 
__declspec(dllexport) char* Parse(LPSTR Data) 
{ 
    CString decryptString; //ccrpyt is a c++ encryption and decryption library 
    CCrypt crypt; 
    char* sUser = new char[200]; 
    char* sURL = new char[200]; 
     strcpy(sUser, Data); 
    CString sEncryptedUser= crypt.DecryptStrFromHex(sUser); 
    strcpy(sURL, sEncryptedUser.GetBuffer()); 
    return sURL ; 
} 
} 


{ 
    __declspec(dllexport) char* Parse(LPSTR Data) 
{ 
    CString decryptString; //ccrpyt is a c++ encryption and decryption library 
    CCrypt crypt; 
    char* sUser = new char[200]; 
    char* sURL = new char[200]; 
     strcpy(sUser, Data); 
    CString sEncryptedUser= crypt.DecryptStrFromHex(sUser); 
    strcpy(sURL, sEncryptedUser.GetBuffer()); 
    return sURL ; 
} 
} 

我把它称为C#为.. 。

public static extern IntPtr Parse([MarshalAs(UnmanagedType.LPStr)] string s1); 
      string s = Request.QueryString.Get("U"); 
      IntPtr i; 
      { 
       i = Parse(s); 
      } 
      string jj =Marshal.PtrToStringAnsi(i); 
      Response.Write(jj); 
     } 
+0

您能否详细说明如何在C#中进行加密并在C++中对其进行解密? – 2016-02-11 05:25:42