Generating SHA-1 hash keys

Introduction
I wanted to generate SHA-1 (Secure Hash Algorithm 1) hash keys from Caché 5.0, but unfortunately this was only added to the  class in Caché 5.1 and onwards. Looking on the Caché newsgroup I did find a discussion about this, where it was mentioned you could use external utilities, but unfortunately there were no suggested alternatives. In this article I will demonstrate how this can be achieved on Caché 5.0, running on a Windows platform.

OpenSSL Tool
To generate SHA-1 keys you can use a tool called 'OpenSSL' and a Windows version is available by visiting the Shining Light Productions web site and downloading the Win32OpenSSL_Light-0_9_8g.exe file. For other operating systems look at the openssl.org web site.

The installation is very simple and I opted to locate the files in the  sub-directory. I also created  as a working directory.

Utilities.Crypto Class
To generate a SSH-1 hash key from within Caché I created a 'Crypto' class, see below.

Class Utilities.Crypto [ Abstract, ProcedureBlock ] {

/// SHA-1 (Secure Hash Algorithm) is a cryptographic hash function with a 160 bit output ClassMethod SHA1Hash(keyvalue As %String) As %String {	// generate SHA-1 hash (message digest) Set path="c:\data\openssl\temp\" Set filein=path_"input.txt" Set fileout=path_"output.txt" //	// open input file and write key value Set file=##class(%File).%New(filein) Do file.Open("WSN") Do file.Write(keyvalue) Kill file //	// convert the key value to a hash Set cmd="c:\apps\openssl\sha1hash "_filein_" "_fileout Set sc=$zf(-1,cmd) If sc'=0 ZTrap "E"_sc //	// open output file and read key hash Set stream=##class(%FileBinaryStream).%New Set stream.Filename=fileout Set y=stream.ReadLine If 'stream.AtEnd ZTrap "ERR" Kill stream //	// delete the files Do ##class(%File).Delete(filein) Do ##class(%File).Delete(fileout) //	// convert the binary value to hex Set z="" For i=1:1:$Length(y) { Set c=$Select(i=4:"-",i=8:"-",i=12:"-",i=16:"-",1:"") Set x=$ZHex($ASCII($Extract(y,i))) Set z=z_$Select($Length(x)=1:"0"_x,1:x)_c }	//	// return the sha-1 hash Quit $ZConvert(z,"L") }

}

Command File
To allow Caché to call out to the OpenSSL executable a Windows batch file called  was created, see contents below. This was placed in the  sub-directory.

@echo off

rem sha1hash.bat rem --- rem start SHA-1 hash conversion in binary rem - created on 11 Jan 2008 rem rem %1 = input file rem %2 = output file rem rem do not enter any more commands as we need rem the return code from the conversion process

if not exist c:\apps\openssl\bin\openssl.exe goto end c:\apps\openssl\bin\openssl dgst -sha1 -binary -out %2 %1


 * end

SHA-1 Digest Examples
USER>Write ##class(Utilities.Crypto).SHA1Hash("The quick brown fox jumps over the lazy dog") 2fd4e1c6-7a2d28fc-ed849ee1-bb76e739-1b93eb12

USER>Write ##class(Utilities.Crypto).SHA1Hash("The quick brown fox jumps over the lazy cog") de9f2c7f-d25e1b3a-fad3e85a-0bd17d9b-100db4b3

USER>Write ##class(Utilities.Crypto).SHA1Hash("") da39a3ee-5e6b4b0d-3255bfef-95601890-afd80709

If you have Caché 5.1 onwards you can call the following routine.

%SYS>do ^CryptoTest 1) NIST 200-38A AES-CBC tests 2) FIPS 180-2 SHA-1 tests 3) FIPS 198 HMAC-SHA-1 tests 4) RFC 1321 MD5 tests 5) RFC 2104 HMAC-MD5 tests 6) RFC 3211 PBKDF2 tests 7) RFC 3548 Base64 tests Select tests: