By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,965 Members | 1,757 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,965 IT Pros & Developers. It's quick & easy.

C# server side (encode) -> C++ client side (decode) ?

P: n/a
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

Dec 20 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
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

Dec 24 '05 #2

P: n/a
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


Jan 3 '06 #3

P: n/a
<jt*****@eudoramail.com> wrote:
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?


Having had a brief look at the C++ API, I believe you want to call
CryptSetKeyParam, passing in KP_IV as the second parameter.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 3 '06 #4

P: n/a
Yeah, the problem is that I'm unable to generate the same key on both
c# and c++. This is the problem - does anybody have any ideas how to
solve this?

Jon wrote:
<jt*****@eudoramail.com> wrote:
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?


Having had a brief look at the C++ API, I believe you want to call
CryptSetKeyParam, passing in KP_IV as the second parameter.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Jan 6 '06 #5

P: n/a
<jt*****@eudoramail.com> wrote:
Yeah, the problem is that I'm unable to generate the same key on both
c# and c++. This is the problem - does anybody have any ideas how to
solve this?


Hang on - you're unable to generate the same *key*, or the same IV? You
shouldn't be generating the key at all - that should be known
information.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 6 '06 #6

P: n/a
Ok, let say I assign the key (ie. hard code). That's fine; but I'm not
even sure how to do this. I simply cannot pass the same key to the c#
anc c++ encryption functions; therefore the output is not the same.

Do you have any ideas as to how to accomplish this? Let's say I want
to start (in c#) with the key:

byte[] testKey = {32, 44, 185, 98, 172, 89, 7, 91, 150, 75, 7, 21, 45,
35, 75, 112};

I have tried this and it works fine (it encrypts the original text).
But my problem is that now I cannot pass this same key to the
encryption process in c++.

How can I turn the above key into HCRYPTKEY and get the same results?

Thank you,

Jon wrote:
<jt*****@eudoramail.com> wrote:
Yeah, the problem is that I'm unable to generate the same key on both
c# and c++. This is the problem - does anybody have any ideas how to
solve this?


Hang on - you're unable to generate the same *key*, or the same IV? You
shouldn't be generating the key at all - that should be known
information.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Jan 6 '06 #7

P: n/a
<jt*****@eudoramail.com> wrote:
Ok, let say I assign the key (ie. hard code). That's fine; but I'm not
even sure how to do this. I simply cannot pass the same key to the c#
anc c++ encryption functions; therefore the output is not the same.

Do you have any ideas as to how to accomplish this? Let's say I want
to start (in c#) with the key:

byte[] testKey = {32, 44, 185, 98, 172, 89, 7, 91, 150, 75, 7, 21, 45,
35, 75, 112};

I have tried this and it works fine (it encrypts the original text).
But my problem is that now I cannot pass this same key to the
encryption process in c++.

How can I turn the above key into HCRYPTKEY and get the same results?


I'm afraid I don't know - I think you'd be best off asking that in a
Win32-specific group (or a Windows Security/Cryptography group).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 6 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.