Question
Nael Nasereldeen · Oct 27, 2019

%SYSTEM.Encryption MD5Hash function -return value conversion

Hi,

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:

https://groups.google.com/forum/#!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("f...@baz.com")
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")
1d2fd35d57d574b807a807b507528b19"

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?

 

Regards,

Nael
 

0
0 906
Discussion (8)3
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.

Hi,

What I mean by a simple string, is a value that you can send Via a web service for example.

Thanks.

What value are you expecting?

Base64 is often used to encode hashes:

write ##class(%SYSTEM.Encryption).Base64Encode(##class(%SYSTEM.Encryption).MD5Hash("f...@baz.com"))

I understand.

Thanks, all comments have been helpful!

Regards,

Nael

That looks better than the WRC supplied code when I fist noticed the binary rather than hex values returned.

set text = "message digest"
  set md5hash = $system.Encryption.MD5Hash(text)
  set md5HashHex = ""
  for i=1:1:$Length(md5hash) {
   set md5HashHex = md5HashHex _ $Zhex($Ascii($Extract(md5hash,i)))
  }
  write md5HashHex, !


 

FWIW, you can also replace the call to $extract with two-argument $ascii:

$a(md5hash,i)

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)
25D55AD283AA400AF464C76D713C07AD
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!

Joe!