Page 1 of 1

Crypto API problem

Posted: Fri Aug 07, 2009 12:16 pm
by ConvertFromOldNGs
by johnmunro >> Tue, 3 Dec 2002 11:33:55 GMT

I was very happy yesterday to have finally got Crypto API to work in Jade. I had been developing it separately in a single user dev environment to keep from messing up our main dev system. When it seemed to be working, I copied it from the single user to the multi-user (thin client) development environment, and guess what - it no longer works. I wondered whether anyone here has implemented Crypto API and whether there are any peculiarities to making it work thin client. If possible I would like it to all run on the App Server because the Microsoft Strong Crypto Provider (which allows us to have 128bit encryption) comes with win2k and not previous versions of windows (and the server will be running 2k whereas the clients may not).

The external functions I am using are:

cryptAcquireContext(
phProv : Integer io;
pszContainer : String;
pszProvider : String;
dwProvType : Integer;
dwFlags : Integer
) : Integer is CryptAcquireContextA in advapi32;

cryptCreateHash(
hProv : Integer;
algid : Integer;
hKey : Integer;
dwFlags : Integer;
phHash : Integer io
) : Integer is CryptCreateHash in advapi32;

cryptDecryptBinary(
hKey : Integer;
hHash : Integer;
final : Integer;
dwFlags : Integer;
pbData : Binary;
pdwDataLen : Integer io
) : Integer is CryptDecrypt in advapi32;

cryptDeriveKey(
hProv : Integer;
algid : Integer;
hBaseData : Integer;
dwFlags : Integer;
phKey : Integer io
) : Integer is CryptDeriveKey in advapi32;

cryptDestroyHash(
hHash : Integer
) : Integer is CryptDestroyHash in advapi32;

cryptDestroyKey(
hKey : Integer
) : Integer is CryptDestroyKey in advapi32;

cryptEncryptBinary(
hKey : Integer;
hHash : Integer;
final : Integer;
dwFlags : Integer;
pbData : Binary;
pdwDataLen : Integer io;
dwBufLen : Integer
) : Integer is CryptEncrypt in advapi32;

cryptHashData(
hHash : Integer;
pbData : String;
dwDataLen : Integer;
dwFlags : Integer
) : Integer is CryptHashData in advapi32;

cryptReleaseContext(
hProv : Integer;
dwFlags : Integer
) : Integer is CryptReleaseContext in advapi32;

and the encrypt method is on the primitive type Binary:

encryptAPI() : Binary;

constants
Password : String = "I am not a number!";
Container : String = "TestContainer";

MS_DEF_PROV : String = "Microsoft Base Cryptographic Provider v1.0";
MS_ENHANCED_PROV : String = "Microsoft Enhanced Cryptographic Provider"; MS_STRONG_PROV : String = "Microsoft Strong Cryptographic Provider";
PROV_RSA_FULL : Integer = 1;
CRYPT_NEWKEYSET : Integer = 8;

ALG_CLASS_DATA_ENCRYPT : Integer = 24576;
ALG_CLASS_HASH : Integer = 32768;
ALG_TYPE_ANY : Integer = 0;
ALG_TYPE_STREAM : Integer = 2048;
ALG_SID_RC4 : Integer = 1;
ALG_SID_MD5 : Integer = 3;

CALG_MD5 : Integer = 32771; //ALG_CLASS_HASH.bitOr(ALG_TYPE_ANY).bitOr(ALG_SID_MD5)
CALG_RC4 : Integer = 26625; //ALG_CLASS_DATA_ENCRYPT.bitOr(ALG_TYPE_STREAM).bitOr(ALG_SID_RC4);

ENCRYPT_ALGORITHM : Integer = CALG_RC4;

Key_Length : Integer = 8388608; // 128bit - 0x00800000

vars
hProv : Integer;
hHash : Integer;
hKey : Integer;

tmpBinary : Binary;
tmpLength : Integer;
begin

// connect to CSP
if call cryptAcquireContext(hProv, Container, MS_STRONG_PROV, PROV_RSA_FULL, 0) = 0 then // try to connect to an existing container with this name
if call cryptAcquireContext(hProv, Container, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) = 0 then // try to create a container with this name
app.assert(false, "Error during CryptAcquireContext for a new key container.");
endif;
endif;

// create a hash object
if call cryptCreateHash(hProv, CALG_MD5, 0, 0, hHash) = 0 then
app.assert(false, "Error during CryptCreateHash");
endif;

// hash the password
if call cryptHashData(hHash, Password, Password.length, 0) = 0 then
app.assert(false, "Error during CryptHashData");
endif;

// derive a session key from the hash object
if call cryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, Key_Length, hKey) = 0 then
app.assert(false, "Error during CryptDeriveKey");
endif;

// encrypt yourself and return the result
tmpBinary := self;
tmpLength := tmpBinary.length;
if call cryptEncryptBinary(hKey, 0, 1, 0, tmpBinary, tmpLength, tmpLength) = 0 then
app.assert(false, "Error during CryptEncrypt");
endif;

return tmpBinary[1 : tmpLength];

epilog
// destroy session key
if hKey <> 0 then
call cryptDestroyKey(hKey);
endif;

// destroy hash object
if hHash <> 0 then
call cryptDestroyHash(hHash);
endif;

// disconnect from CSP
if hProv <> 0 then
call cryptReleaseContext(hProv, 0);
endif;

end;

If I call this method on a Binary (for example "Hello".Binary or a Binary local variable) it just returns the original Binary. None of the error traps are triggered, so as far as the API is concerned, it has successfully encrypted...

John Munro

---
Synergist Limited - Home of FileVision
The Bioscience Innovation Centre
Cowley Road, Cambridge, UK
CB4 0DS

Telephone: +44 (0) 1223 478200
Fax: +44 (0) 1223 477969
Email: john.munro@filevision.com
Web: http://www.filevision.com

The contents of this communication are confidential and are only intended to be read by the addressee. We apologize if you receive this communication in error and ask that you contact Synergist Limited immediately to arrange for its return. The use of any information contained in this communication by an unauthorized person is strictly prohibited. Synergist Limited cannot accept responsibility for the accuracy or completeness of this communication as it is being transmitted over a public network. If you suspect this message may have been intercepted or amended, please inform Synergist Limited.

Re: Crypto API problem

Posted: Fri Aug 07, 2009 12:16 pm
by ConvertFromOldNGs
by cdshearer >> Tue, 3 Dec 2002 18:57:46 GMT

Hi John

We implemented encryption using the API quite some time ago, and ran into a problem with it too, when running in Thin Client mode. I can't remember the exact details, but, just as a guess, you should check where the actual methods are being executed. You want them to execute on the AppServer and not on the client machine - you need to modify the external function signatures to reflect this. This is done with the applicationServerExecution tag. For example:

cryptAcquireContext(phProv : Integer io;
pszContainer : String;
pszProvider : String;
dwProvType : Integer;
dwFlags : Integer) : Integer is CryptAcquireContextA in advapi32 applicationServerExecution;


Best of luck

Craig

Re: Crypto API problem

Posted: Fri Aug 07, 2009 12:17 pm
by ConvertFromOldNGs
by johnmunro >> Wed, 4 Dec 2002 14:38:30 GMT

Hooray! That fixed it, thanks! I'd forgotten you can specify where external functions run

Re: Crypto API problem

Posted: Fri Feb 08, 2013 11:01 pm
by M45HY
Hi guys,

Just had a quick question, you know how johnmunro wrote:
constants
ALG_CLASS_DATA_ENCRYPT : Integer = 24576;
ALG_CLASS_HASH : Integer = 32768;
ALG_TYPE_ANY : Integer = 0;
ALG_TYPE_STREAM : Integer = 2048;
ALG_SID_RC4 : Integer = 1;
ALG_SID_MD5 : Integer = 3;
I just wanted to ask whether you knew how to refer to CALG_SHA_256 by any chance (i.e. CALG_SHA_256 : Integer = #800c)?

Omash