Hi,
As I had a need to create a SHA256 hash I'd figure why not try and use MS crypto for that by using the cryptographer class.
The problem with that is that it will not work without making changes to the class.
The following will get it to generate a SHA, I've not yet verified the outcome to see if it makes sense. FWIW I get a different hash on OSX.
Code:
echo "abc" | shasum -a 256
edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb -
Here's the code:
Code:
Object oCrypt is a cCryptographer
Set piHash To CALG_SHA_256
Set piProvider To PROV_RSA_AES // default=PROV_RSA_FULL
// Set psProvider To MS_ENH_RSA_AES_PROV //MS_ENH_RSA_AES_PROV // default=
//***
//*** Function: HashValue
//*** Purpose : Retrieves a hash value
//***
Function HashValue Handle lhHash Returns String
Pointer lpSize
Pointer lpHash
String lsSize
String lsHash
Integer liResult
Move (Repeat(Character(0),4)) To lsSize
GetAddress Of lsSize To lpSize
Move (CryptGetHashParam(lhHash,HP_HASHVAL,0,lpSize,0)) To liResult
If (liResult = 0) Function_Return ""
Move (Repeat(Character(0),BytesTodWord(lsSize,1))) To lsHash
GetAddress Of lsHash To lpHash
Move (CryptGetHashParam(lhHash,HP_HASHVAL,lpHash,lpSize,0)) To liResult
If (liResult = 0) Function_Return ""
Function_Return lsHash
End_Function // HashValue
Function CharToHex Integer iChar Returns String
String sHex
Move (Uppercase(iChar)) to iChar
Move (Mid("0123456789abcdef",1,Integer(iChar/16+1))) to sHex
Move (sHex-Mid("0123456789abcdef",1,Mod(iChar,16)+1)) to sHex
Function_Return sHex
End_Function // CharToHex
Function StrToHex String sString Returns String
Integer iCounter
String sHex sChar
For iCounter from 1 to (Length(sString))
Get CharToHex (Ascii(Mid(sString,1,iCounter))) to sChar
Move (sHex+sChar) to sHex
Loop // For iCounter From 1 To (Length(sString))
Function_Return sHex
End_Function // StrToHex
Function StringToSHA256Hash String sData Returns String
Handle hHash hProv
Integer iResult
String sHash sHashHex
Get AcquireContext to hProv
Get CreateHash hProv CALG_SHA_256 to hHash
If hHash Begin
Get HashData hHash sData to iResult
If iResult Begin
Get HashValue hHash to sHash
Get StrToHex sHash to sHashHex
End
Get DestroyHash hHash to iResult
End
Function_Return sHashHex
End_Function
End_Object
If you run this, it will fail on AquireContext in the function StringToSHA256Hash, the reason there is that the psProvider is given to the AquireContext function. I've changed it as follows and THEN it does work.
Code:
// Function : AcquireContext
// Purpose : Acquire key container handle
Function AcquireContext Returns Handle
Integer iProvider
String sProvider
Handle hProv
Boolean bOk
Move 0 to hProv
Get psProvider to sProvider
Get piProvider to iProvider
// Move (CryptAcquireContext(AddressOf(hProv),0,AddressOf(sProvider),iProvider,0)) to bOk
Move (CryptAcquireContext(AddressOf(hProv),0,0,iProvider,CRYPT_VERIFYCONTEXT)) to bOk
If (not(bOk)) Begin
Move (CryptAcquireContext(AddressOf(hProv),0,AddressOf(sProvider),iProvider,CRYPT_NEWKEYSET)) to bOk
End
Set Private_phProv to hProv
Function_Return hProv
End_Function
The main program is:
Code:
Procedure TestSHA
string sHash
Get StringToSHA256Hash Of oCrypt "abc" To sHash
showln "abc = length(" (length(sHash)) ")"
showln "encryped = " sHash
End_Procedure
Send TestSHA
The output of this is:
Code:
abc = length(64)
encryped = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
Which certainly looks like an sha 256 hash, but somehow the letters "abc" are different in the OSX world
Next step is figuring out why it is different and then doing this for unicode, but figured I'd share these findings.
enjoy!
--
Wil