Ok, So my code is listed below. I'm not sure where to put the iv value
for the C++ portion:
I'm trying to encrypt a piece of information (a string of text from an
..INI file) on the server side (C# .net) and pass that information to
the client side app which has to decrypt it. I'm trying to use (in c#)
the System.Security.Cryptography and in c++ the wincrypt.h file. I'm
not sure if this is possible (although I believe it is); so I was
wondering if anybody had any ideas?
The C# Server Code:
// -----------------------------------------------------------
// ENCRYPT (C# SERVER SIDE)
// -----------------------------------------------------------
using System.Security.Cryptography;
private string Encrypt_Try2(string strKey, string strText)
{
PasswordDeriveBytes cdk = new PasswordDeriveBytes(strKey, null);
// generate an RC2 key
byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
byte[] key = cdk.CryptDeriveKey("RC2", "MD5", 128, iv);
Console.WriteLine(key.Length * 8);
// setup an RC2 object to encrypt with the derived key
RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
rc2.Key = key;
rc2.IV = new byte[] { 21, 22, 23, 24, 25, 26, 27, 28};
// now encrypt with it
byte[] plaintext = Encoding.UTF8.GetBytes(strText);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, rc2.CreateEncryptor(),
CryptoStreamMode.Write);
cs.Write(plaintext, 0, plaintext.Length);
cs.Close();
byte[] encrypted = ms.ToArray();
// Convert to Base64
string txtOut = Convert.ToBase64String(encrypted);
// THIS IS THE ENCRYPTED TEXT
return txtOut;
}
// -----------------------------------------------------------
// DECRYPT (FOR VERIFICATION - (C# SERVER SIDE))
// -----------------------------------------------------------
private string Decrypt_Try2(string strKey, string strText)
{
PasswordDeriveBytes cdk = new PasswordDeriveBytes(strKey, null);
// generate an RC2 key
byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
byte[] key = cdk.CryptDeriveKey("RC2", "MD5", 128, iv);
Console.WriteLine(key.Length * 8);
// setup an RC2 object to encrypt with the derived key
RC2CryptoServiceProvider rc2 = new RC2CryptoServiceProvider();
rc2.Key = key;
rc2.IV = new byte[] { 21, 22, 23, 24, 25, 26, 27, 28};
// now encrypt with it
//byte[] plaintext = Encoding.UTF8.GetBytes(strText);
byte[] plaintext = Convert.FromBase64String(strText);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, rc2.CreateDecryptor(),
CryptoStreamMode.Write);
cs.Write(plaintext, 0, plaintext.Length);
cs.Close();
byte[] encrypted = ms.ToArray();
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
// THIS IS THE DECRYPTED TEXT
return encoding.GetString(encrypted);
//this.txtOut.Text = txtOut;
}
// -----------------------------------------------------------
// DECRYPT (C++ CLIENT SIDE)
// -----------------------------------------------------------
CString CJCrypt::Decrypt(char *key, char *txtOut)
{
char *szPassword = key;
CBase64Utils bu;
int iTxtOutLen = strlen(txtOut);
char *result = bu.Decode(txtOut, &iTxtOutLen);
DWORD dwBufLen = 1+strlen(result);
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHashKey;
DWORD sts=0;
DWORD errc = 0;
sts = CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV,
PROV_RSA_FULL, 0);
if(sts == 0) errc=GetLastError();
sts = CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHashKey);
if(sts == 0) errc=GetLastError();
sts = CryptHashData(hHashKey, (BYTE *)szPassword,
strlen(szPassword), 0);
if(sts == 0) errc=GetLastError();
//sts = CryptDeriveKey(hCryptProv, CALG_DES, hHashKey, (56)<<16,
&hKey);
sts = CryptDeriveKey(hCryptProv, CALG_RC2, hHashKey, 128, &hKey);
//sts = CryptDeriveKey(hCryptProv, CALG_3DES, hHashKey, (168)<<16,
&hKey);
//sts = CryptDeriveKey(hCryptProv, CALG_RC4, hHashKey, (56)<<16,
&hKey);
if(sts == 0) errc=GetLastError();
DWORD dwCryptBuffLen = dwBufLen;
sts = CryptEncrypt(hKey,0,TRUE,0,NULL,&dwCryptBuffLen,0) ;
BYTE *bCryptoBuffer = new BYTE[dwCryptBuffLen];
memset(bCryptoBuffer,0,dwCryptBuffLen);
memcpy(bCryptoBuffer,result,dwBufLen + 3);
sts = CryptDecrypt(hKey, 0, TRUE,0,(BYTE *)result,
&dwCryptBuffLen);
if(sts == 0) errc=GetLastError();
// else do something with the dwBufLen bytes of encrypted data in
bCryptoBuffer
sts = CryptDestroyKey(hKey);
sts = CryptDestroyHash(hHashKey);
sts = CryptReleaseContext(hCryptProv, 0);
CString strOut;
strOut.Format("%s", result);
return strOut;
}
// -----------------------------------------------------------
// ENCRYPT (FOR VERFICATION - (C++ CLIENT SIDE))
// -----------------------------------------------------------
CString CJCrypt::Encrypt(char *key, char *txtIn)
{
char *szPassword = key;
DWORD dwBufLen = 1+strlen(txtIn);
HCRYPTPROV hCryptProv;
HCRYPTKEY hKey;
HCRYPTHASH hHashKey;
DWORD sts=0;
DWORD errc = 0;
sts = CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV,
PROV_RSA_FULL, 0);
if(sts == 0) errc=GetLastError();
sts = CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHashKey);
if(sts == 0) errc=GetLastError();
sts = CryptHashData(hHashKey, (BYTE *)szPassword,
strlen(szPassword), 0);
if(sts == 0) errc=GetLastError();
//sts = CryptDeriveKey(hCryptProv, CALG_DES, hHashKey, (56)<<16,
&hKey);
sts = CryptDeriveKey(hCryptProv, CALG_RC2, hHashKey, 128, &hKey);
//sts = CryptDeriveKey(hCryptProv, CALG_3DES, hHashKey, (168)<<16,
&hKey);
//sts = CryptDeriveKey(hCryptProv, CALG_RC4, hHashKey, (56)<<16,
&hKey);
if(sts == 0) errc=GetLastError();
DWORD dwCryptBuffLen = dwBufLen;
sts = CryptEncrypt(hKey,0,TRUE,0,NULL,&dwCryptBuffLen,0) ;
BYTE *bCryptoBuffer = new BYTE[dwCryptBuffLen];
memset(bCryptoBuffer,0,dwCryptBuffLen);
memcpy(bCryptoBuffer,txtIn,dwBufLen);
sts = CryptEncrypt(hKey, 0, TRUE, 0, bCryptoBuffer, &dwBufLen,
dwCryptBuffLen);
// Convert To Base64
CBase64Utils bu;
char *result = bu.Encode((char *)bCryptoBuffer, dwBufLen + 1);
if(sts == 0) errc=GetLastError();
// else do something with the dwBufLen bytes of encrypted data in
bCryptoBuffer
sts = CryptDestroyKey(hKey);
sts = CryptDestroyHash(hHashKey);
sts = CryptReleaseContext(hCryptProv, 0);
CString strOut;
strOut.Format("%s", result);
return strOut;
}
Both the c# and c++ encrypt/decrypt work with them selves (i.e. I can
encrypt and decrypt things using only the c++ OR the C#, but I cannot
encrypt with C# and decrypt with C++). I'm not sure this is possible
and I just don't have the parameters set up correctly; or if they use
completely separate algorythms and will not work.
Does anybody have any idea?
Thank you very much
Nicholas Paldino [.NET/C# MVP] wrote:
J,
Sure you can. The classes in the System.Security.Cryptography namespace
use well established algorithms to encrypt/decrypt information. You just
have to use the same algorithms in your C++ code (which are supported, by
the way), along with the same key and iv values for encryption/decryption.
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
<jt*****@eudoramail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...I need to encode some information on the server side using ASP.NET with
C#; sending via HTTP to a client side application, that needs to be
decoded in an MFC C++ application.
I'm not sure if I can encode something using:
C#: System.Security.Cryptography (to encode)
and
C++: wincrypt.h (to decode)
Does anybody have any idea about this? Thank you in advance; it is
greatly appreciated.
J