· Oct 27, 2019

%SYSTEM.Encryption MD5Hash function -return value conversion


We wanted to use the MD5Hash function,

And had trouble understanding it's return value , as documented:

"Return value: 16-byte MD5 hash."

The value we wanted should have been a simple string, and we did not know how to convert the output to string.

Searching for a solution we found this article:!msg/intersystems-public-cache/FdkHIgS9PkQ/P7s-92kN70UJ

That had this solution that works:

"If you know what this gibberish stuff is about, it can be very simple ;)

USER> s h = ##class(%SYSTEM.Encryption).MD5Hash("")
USER> s h0x = ""
USER> f i=1:1:$l(h) {s chr = $zhex($ascii($e(h,i))) s h0x = h0x _
$s($l(chr) = 1: "0"_chr, 1:chr)}
USER> w $zcvt(h0x,"l")

And also a simpler solution:

"  s pwd="12345678"
  s md5=$system.Encryption.MD5Hash(pwd)
  s md5hex=##class(%xsd.hexBinary).LogicalToXSD(md5)
  w md5hex,! "


Is this issue addressed in Cache documentation? and is there a more standard way to get the string result?




Discussion (8)2
Log in or sign up to continue

The value we wanted should have been a simple string, and we did not
 know how to convert the output to string
##class(%SYSTEM.Encryption).MD5Hash() does return a string, what do you mean by 'simple'? If you mean 'displayable' that will depend on what you're trying to display on.
Take a look at ##class(%SYSTEM.Encryption).Base64Encode() that will return a string with only non-control ASCII characters.

Whereas the digest methods in the %SYSTEM .Encryption class return binary strings, which are documented in terms of their byte length, it is indeed conventional to display them using hexadecimal. Instead of $select, I more usually see $translate and $justify:

s h0x=h0x_$tr($j(chr,2)," ",0)

If %xsd.hexBinary is covenient, though, I'd say use that.

For a sanity check, you can compare whatever implementation you choose with the zzdump command:

USER>s digest=$system.Encryption.MD5Hash("12345678")

USER>w ##class(%xsd.hexBinary).LogicalToXSD(digest)
USER>zzdump digest

0000: 25 D5 5A D2 83 AA 40 0A F4 64 C7 6D 71 3C 07 AD

To encrypt to MD5 (as javascript, unix and others) I writed this classmethod, using information found here, and works very well.

ClassMethod Encripta(pass) As %String
set intermedio = ##class(%SYSTEM.Encryption).MD5Hash(pass)
set md5HashHex = ""
for i=1:1:$Length(intermedio) {
set hexaIntermedio = $Zhex($Ascii($Extract(intermedio,i)))
if $Length(hexaIntermedio)=1 {
set hexaIntermedio = "0" _ hexaIntermedio
set md5HashHex = md5HashHex _ hexaIntermedio
return $ZConvert(md5HashHex,"L")

Just need to use " d Encripta("word")"

I hope could be useful!