1

I am working on an application that utilizes a C# server and a C++ client, with licensing data being transferred between the two applications. I obviously want to encrypt these licenses for security reasons, but I am having some trouble finding a library that will fit my purposes for C++. Namely, I have tried both Crypto++ and CryptoAPI. Crypto++ seems like a nice, easy to use library, but the results of Crypto++'s encryption and C#'s encryption are different. CryptoAPI could do the job since it's maintained by Microsoft, but the API is confusing and difficult to understand. Also, strangely, C# is generating the same encrypted output with each runtime, even though I don't touch the random generation of the IV. Crypto++ doesn't do this (the output changes with each runtime under random IVs).

Does anyone have any suggestions or guidelines? I am using CBC modes for both Crypto++ and C#, so I don't think that is an issue. I'm currently using TripleDES to get the program working first. Should I use a different algorithm (I most certainly will once I'm done)?

Code, as requested (sorry about that):

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);
}

And decryption (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);
    }
}
10
  • 2
    We need code and output to see where the IV part goes wrong. Commented Jan 9, 2012 at 22:00
  • Just added the code. Sorry about that. Commented Jan 9, 2012 at 22:42
  • @jForshee : Your Decrypt function does not use the Key argument it's passed -- is this intentional? Commented Jan 9, 2012 at 23:14
  • And why is the IV set to all zero's? And can somebody check if the default padding is PKCS#5 and/or PKCS#7 in CryptoPP? Commented Jan 10, 2012 at 0:05
  • 1
    Prepending the ciphertext with a random IV is the normal way to get around the IV transport problem (the IV is always has the same size as the cipher blocks). Using ECB mode is unsafe for any other data than non-related, randomized data. Then again, so is a client/server protocol that does not perform integrity checks (e.g. because of padding oracles) - you migth want to create a (H)MAC over your ciphertext as well, and verify that before decrypting (the last block of the) data. Commented Jan 10, 2012 at 19:59

1 Answer 1

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 ;
}
}

I call it in C # as...

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);
        }
Sign up to request clarification or add additional context in comments.

1 Comment

Can you elaborate how can I encrypt in C# and decrypt it in C++?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.