【问题标题】:Encryption/Decryption from C# to C++从 C# 到 C++ 的加密/解密
【发布时间】:2012-01-09 21:56:03
【问题描述】:

我正在开发一个使用 C# 服务器和 C++ 客户端的应用程序,许可数据在两个应用程序之间传输。出于安全原因,我显然想加密这些许可证,但是我在寻找适合我的 C++ 用途的库时遇到了一些麻烦。也就是说,我已经尝试过 Crypto++ 和 CryptoAPI。 Crypto++ 看起来是一个不错的、易于使用的库,但是 Crypto++ 的加密结果和 C# 的加密结果是不同的。 CryptoAPI 可以完成这项工作,因为它由 Microsoft 维护,但 API 令人困惑且难以理解。此外,奇怪的是,C# 在每次运行时都会生成相同的加密输出,即使我没有触及 IV 的随机生成。 Crypto++ 不这样做(输出随随机 IV 下的每个运行时而变化)。

有没有人有任何建议或指导?我对 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);
    }
}

【问题讨论】:

  • 我们需要代码和输出来查看 IV 部分哪里出错了。
  • 刚刚添加了代码。对此感到抱歉。
  • @jForshee : 你的 Decrypt 函数没有使用它传递的 Key 参数——这是故意的吗?
  • 为什么IV设置为全零?有人可以检查 CryptoPP 中的默认填充是否是 PKCS#5 和/或 PKCS#7?
  • 在密文前添加随机 IV 是解决 IV 传输问题的正常方法(IV 始终与密码块具有相同的大小)。除了不相关的随机数据之外,使用 ECB 模式对于任何其他数据都是不安全的。再说一次,不执行完整性检查的客户端/服务器协议也是如此(例如,由于填充预言) - 您可能还想在密文上创建(H)MAC,并在解密之前验证(最后一个块)数据。

标签: c# c++ encryption cryptography


【解决方案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);
        }

【讨论】:

  • 您能否详细说明如何在 C# 中加密并在 C++ 中解密?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-24
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 2021-02-06
  • 1970-01-01
相关资源
最近更新 更多