Porting .NET Encryption to Win32 or ATL

  • Thread starter Thread starter Sygnosys
  • Start date Start date
S

Sygnosys

Hi,


I have a piece of code in .NET that encrypts a string.
The .NET code is quite simple and through the last couple of days I've
been trying to build it's equivalent in ATL playing arround with CCrypt
classes and I just haven't been able to get it right.
So if anyone can help me porting this to ATL or Win32 I would be
grateful.


..NET Code:


String* Encrypt(String* PlainText)
{
System::Byte IV[] = { 1, 9, 1, 7, 1, 4, 6, 4 };
System::Byte key[] = Convert::FromBase64String("password");


TripleDES *algorithm = TripleDESCryptoServiceProvider::Create();
MemoryStream *memStream = new MemoryStream();
CryptoStream *cryptoStream = new CryptoStream( memStream,
algorithm->CreateEncryptor( key, IV ),CryptoStreamMode::Write );


StreamWriter* myWriter = new StreamWriter(cryptoStream);
myWriter->Write(PlainText);
myWriter->Flush();
cryptoStream->FlushFinalBlock();
memStream->Flush();


String *strResult =
Convert::ToBase64String(memStream->GetBuffer(),0,(int)memStream->get_Length­());



return strResult;
}
 
Hi!
I have a piece of code in .NET that encrypts a string.
The .NET code is quite simple and through the last couple of days I've
been trying to build it's equivalent in ATL playing arround with CCrypt
classes and I just haven't been able to get it right.
So if anyone can help me porting this to ATL or Win32 I would be
grateful.

It's not acutally too hard. It's just that the documentation isn't
exactly great. Always look in the docs for the raw Win32 APIs.

First you need to initialize the Crypto API and select
the appropriate CSP.

CCryptProv prov;
CheckHresult( prov.Initialize() );
String* Encrypt(String* PlainText)
{
System::Byte IV[] = { 1, 9, 1, 7, 1, 4, 6, 4 };
System::Byte key[] = Convert::FromBase64String("password");


TripleDES *algorithm = TripleDESCryptoServiceProvider::Create();
MemoryStream *memStream = new MemoryStream();
CryptoStream *cryptoStream = new CryptoStream( memStream,
algorithm->CreateEncryptor( key, IV ),CryptoStreamMode::Write );

I'm not sure that is really what you want. Typically, you would derive
the key from a hash of the password not from the raw password.

This would probably look like
System::Byte key[] = new PasswordDeriveBytes(
Convert::FromBase64String("password"), salt )
->CryptDeriveKey("TripleDES", "SHA1", 192, IV );

Not exactly certain (looks like the documentation is pretty poor here)
I guess - quite contrary to the docs --, salt isn't used at all here and IV
receives the initialization vector. Haven't tried it, though.

If you want it that way, you should use CCryptDerivedKey. Otherwise
(the key is a raw password) you need to use CCryptImportKey.

To construct the CCryptDerivedKey you need a hash of the
key. You get that from the corresponding CCryptXXXHash class.

E.g.:
CCryptSHA1Hash hash;
CheckHresult( hash.Initialize(prov), password );
CCryptDerivedKey key;
CheckHresult( key.Initialize(prov, hash, CALG_3DES ) );

key.Encrypt( ... );

Base64 encoding is also supported by the ATL Server libs.
Look for Base64(En/De)code.

-hg
 
Thanks for your reply Holger.

I must agree that the .NET algorithm is somewhat "strange" to be kind,
but I do have to suport it in my app. So I want to create a compatible
version in ATL or Win32.
So thanks for your sugestion I will try it and post back my findings
here!

Thanks
Cláudio Albuquerque
 
Hi,
In the hope that this will help someone in the future.
There goes the details

The ATL classes CCryptImportKey do not work.

So the anwser relies in the microsoft knowlege base article "How to
export and import plain text session keys by using CryptoAPI".

Kind Regards
Cláudio Albuquerque
 
Back
Top