MD5 Hash

553 views
Skip to first unread message

Ryan McLaughlin - DTI

unread,
Oct 5, 2009, 3:35:43 PM10/5/09
to InterSystems: Zen Community
I am creating a credit card page that will send data to credit card
processing company. They require a MD5 hash inorder to validate the
connection, but I cannot find anything in Zen or Cache. How can I
create an MD5 hash?

Dawn Wolthuis

unread,
Oct 5, 2009, 3:42:30 PM10/5/09
to intersys...@googlegroups.com
From the class doc, it looks like "%SYSTEM.Encryption"->MD5Hash(text)
should work (translated from mvbasic to cos, class=%SYSTEM.Encryption,
method = MD5Hash, if needed).

--dawn
--
Dawn M. Wolthuis

Take and give some delight today

Ryan McLaughlin - DTI

unread,
Oct 5, 2009, 5:26:09 PM10/5/09
to InterSystems: Zen Community
Dawn,

Thanks for pointing that out.
I am now having a problem with the result of the MD5Hash function

Here is what I am doing:
set orderid = "111111"
set amount = "10.00"
set time = "20091005151910"
set key="776320"
set hash = $system.Encryption.MD5Hash
(orderid_"|"_amount_"|"_time_"|"_key)

If I print out the hash variable I get "4"_$c(150,7,17)_" :«*$"_$c(3)
_"åì"""_$c(27)_"k"_$c(5)

This is not a valid md5 hash and so I am wondering what I am doing
wrong.


On Oct 5, 1:42 pm, Dawn Wolthuis <dw...@tincat-group.com> wrote:
> From the class doc, it looks like "%SYSTEM.Encryption"->MD5Hash(text)
> should work (translated from mvbasic to cos, class=%SYSTEM.Encryption,
> method = MD5Hash, if needed).
>
> --dawn
>
> On Mon, Oct 5, 2009 at 2:35 PM, Ryan McLaughlin - DTI
>

Dawn Wolthuis

unread,
Oct 5, 2009, 5:54:45 PM10/5/09
to intersys...@googlegroups.com
I have not figured out when you use that $system object and when you
use the class, but since this is a classmethod and not an instance
method, you might try calling MD5Hash as a classmethod using that
##class... notation with %SYSTEM.Encryption as the class name then the
dot and then the method. --dawn

Taylor Flagg

unread,
Oct 5, 2009, 5:58:18 PM10/5/09
to intersys...@googlegroups.com
Dawn, you're correct.

$System.Class.Method = ##class(%SYSTEM.Class).Method


Taylor

Ryan McLaughlin - DTI

unread,
Oct 5, 2009, 6:04:06 PM10/5/09
to InterSystems: Zen Community
I chaged the call to
set hash = ##class(%SYSTEM.Encryption).MD5Hash
(orderid_"|"_amount_"|"_time_"|"_key)

but I still get an invalid hash.
4– :«*$ åì" k
> Take and give some delight today- Hide quoted text -
>
> - Show quoted text -

Derek Day

unread,
Oct 5, 2009, 8:23:58 PM10/5/09
to intersys...@googlegroups.com
Hi, Ryan.
http://www.faqs.org/rfcs/rfc1321.html

That looks as though it may be 16 bytes if there is one non-printing character that you didn't copy.

• classmethod MD5Hash(text As %String) as %String

This method generates a 16-byte hash using the MD5 message digest algorithm. (See Internet Engineering Task Force Request for Comments 1321 for more information.)

Input parameter:
text - String to be hashed.

Return value: 16-byte MD5 hash.

Are you by any chance looking for a Base 64 encoded hash?

~Derek
________________________________________
From: intersys...@googlegroups.com [intersys...@googlegroups.com] On Behalf Of Ryan McLaughlin - DTI [ryan.mc...@dtint.com]
Sent: Monday, October 05, 2009 18:04
To: InterSystems: Zen Community
Subject: [InterSystems-Zen] Re: MD5 Hash

Eric

unread,
Oct 5, 2009, 8:31:42 PM10/5/09
to InterSystems: Zen Community
Ryan,

MD5 is a 32 digit hexadecimal number but $SYSTEM.Encryption.MD5Hash is
documented as a 16-byte MD5 hash so I am guessing it is just not in
hex format.

They have a few examples on wikipedia and if I take one:
MD5("The quick brown fox jumps over the lazy dog")
= 9e107d9d372bb6826bd81d3542a419d6

I can hash it like this:
set x= $system.Encryption.MD5Encode("The quick brown fox jumps over
the lazy dog")

and then dump it:

USER>zzdump x

0000: 9E 10 7D 9D 37 2B B6 82 6B D8 1D 35 42 A4 19 D6

and it does look the same now. You can do the same thing with $zhex:

USER>f i=1:1:$l(x) {w $zcvt($zhex($a($e(x,i,i+1))),"l")}
9e107d9d372bb6826bd81d3542a419d6

and this now looks identical to the wikipedia example so I guess you
now need to wrap the $SYSTEM.Encryption.MD5Hash method with your own
to get the correct result.

Hope that helps

Eric


On Oct 5, 6:04 pm, Ryan McLaughlin - DTI <ryan.mclaugh...@dtint.com>

Eric

unread,
Oct 5, 2009, 8:46:00 PM10/5/09
to InterSystems: Zen Community
Hi Derek!

The test suite in the standard (http://tools.ietf.org/html/rfc1321)
uses 32 bit hex hash:

A.5 Test suite

The MD5 test suite (driver option "-x") should print the following
results:

MD5 test suite:
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
=
d174ab98d277d9f5a5611c2c9f419d9f
MD5
("123456789012345678901234567890123456789012345678901234567890123456
78901234567890") = 57edf4a22be3c955ac49da2e2107b67a


and there is a very nice test page here: http://hash-it.net/

Maybe the %SYSTEM.Encryption implementation could eventually offer
both 16 & 32 bytes output?


On Oct 5, 8:23 pm, Derek Day <Derek....@intersystems.com> wrote:
> Hi, Ryan.http://www.faqs.org/rfcs/rfc1321.html
>
> That looks as though it may be 16 bytes if there is one non-printing character that you didn't copy.
>
> • classmethod MD5Hash(text As %String) as %String
>
>     This method generates a 16-byte hash using the MD5 message digest algorithm. (See Internet Engineering Task Force Request for Comments 1321 for more information.)
>
>     Input parameter:
>     text - String to be hashed.
>
>     Return value: 16-byte MD5 hash.
>
> Are you by any chance looking for a Base 64 encoded hash?
>
> ~Derek
> ________________________________________
> From: intersys...@googlegroups.com [intersys...@googlegroups.com] On Behalf Of Ryan McLaughlin - DTI [ryan.mclaugh...@dtint.com]

Derek Day

unread,
Oct 6, 2009, 8:53:19 AM10/6/09
to intersys...@googlegroups.com
Hi, Eric.

There are multiple ways to translate a binary hash or encoding to
printable characters; base 64 encoding and hex dump are two options.

%SYS>r eric
4– :«*$ åì" k
%SYS>zzdump eric
0000: 0034 2013 0020 0020 0020 003A 00AB 002A 4– :«*
0008: 0024 0020 00E5 00EC 0022 0020 006B $ åì" k
%SYS>s eric=$zcvt(eric,"O","RAW") //email had caused the
characters to be widened, high-order bytes are zeroes, so we can strip
them using RAW output translation.
%SYS>zzdump eric
0000: 34 3F 20 20 20 3A AB 2A 24 20 E5 EC 22 20 6B 4? :«*$
åì" k
%SYS>w $System.Encryption.Base64Encode(eric)
ND8gICA6qyokIOXsIiBr
%SYS>w $L($System.Encryption.Base64Encode(eric))
20

The hex dump does match the MD5 test output (corresponding to the -x --
hex option).

%SYS>r test
12345678901234567890123456789012345678901234567890123456789012345678901234567890
%SYS>s ryan2=$System.Encryption.MD5Hash(test)
%SYS>zzdump ryan2

0000: 57 ED F4 A2 2B E3 C9 55 AC 49 DA 2E 21 07 B6 7A
Wíô¢+ãÉU¬IÚ.!.¶z

%SYS>s ryan3="" for i=1:1:$length(ryan2) { s
ryan3=ryan3_$zhex($a($extract(ryan2,i))) }

%SYS>w ryan3
57EDF4A22BE3C955AC49DA2E217B67A
%SYS>



Eric wrote (10/5/09 8:46 PM):
> Hi Derek!
>
> The test suite in the standard (http://tools.ietf.org/html/rfc1321)
> uses 32 bit hex hash:
>
> A.5 Test suite
>
> The MD5 test suite (driver option "-x") should print the following
> results:
>
> MD5 test suite:
> MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
> MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
> MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
> MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
> MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
> MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
> =
> d174ab98d277d9f5a5611c2c9f419d9f
> MD5
> ("123456789012345678901234567890123456789012345678901234567890123456
> 78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
>
>
> and there is a very nice test page here: http://hash-it.net/
>
> Maybe the %SYSTEM.Encryption implementation could eventually offer
> both 16& 32 bytes output?

Eric

unread,
Oct 6, 2009, 9:18:43 AM10/6/09
to InterSystems: Zen Community
Derek,

I agree the result can be encoded correctly multiple ways but I
expected Ryan to want hex encoding because this is how MD5 is usually
encoded. I first thought of base64 but had doubts since this is used
in email where 7bits is more standard so I looked up wikipedia and the
rfc itself and saw both used hex instead of base64.

The MD5Hash method does a good job but adding some more documentation
saying what to do to produce different encodings would be helpful for
the casual developer who expects the output to be immediatly
consummable. This is why I suggested the method could offer different
outputs through a second parameter.


Eric

Derek Day

unread,
Oct 6, 2009, 9:29:11 AM10/6/09
to intersys...@googlegroups.com
Yep, I haven't thought about that much -- there *are* other methods in
context specific locations -- the XML and SOAP classes, since they
provide some automatic use of $System.Encryption functions, also
%CSP.Page (inherited by Zen pages) contains some web page specific
interfaces to the kernel functions.

I am hesitant to agree that the kernel functions should be made more
complex when a COS solution is quite simple to code. In general I'd just
say that if there is an application need for an API modification or for
significant performance improvements for some function such that it
needs to be implemented in c code, then a WRC issue requesting an
enhancement should be logged.

You can see from my examples that I remembered Ryan had started this
thread, and then I noticed that you had posted the last reply instead of
him.... I do think the documentation is probably adequate, since it does
say exactly what output is expected (16 bytes), and references the RFC.
If you do have any specific suggestions for any documentation
improvements, please also submit those to the WRC.

~Derek

Eric wrote (10/6/09 9:18 AM):

Eric

unread,
Oct 6, 2009, 9:45:06 AM10/6/09
to InterSystems: Zen Community


> I am hesitant to agree that the kernel
> functions should be made more complex

I would would have said "easier to use" instead;) but I see your
point.

BTW, connecting to a PIX requires base64 MD5 instead of hex MD5.

Ryan McLaughlin - DTI

unread,
Oct 6, 2009, 10:47:46 AM10/6/09
to InterSystems: Zen Community
Thanks Derek and Eric

I was able to get this to work using Dereks example, but I also agree
that their should add a 32bit MD5 wrapper class that does the
converting automatically. It would also be nice if there was better
documentation. I had no idea that this function even existed (I spent
at least an hour in the DocBook Caché ObjectScript Reference), and
since I am new to security and encryption I didn't know I needed a
32bit MD5 instead of a 16bit MD5 or even that the 16bit one was in
binary and I needed hex.

One other thing I want to mention for others that may need the same
thing. Dereks example strips off the leading 0 which can sometimes
result in a hash that is less that 32bits. Each time the loop is run
you need to check the value and if it is only 1 number then you need
to add the leading 0 back on.

set hash16 = ##class(%SYSTEM.Encryption).MD5Hash(string)
for i=1:1:$l(hash16) {
set temp = $zcvt($zhex($a($e(hash16,i,i+1))),"l")
if ($l(temp)=1) set temp = "0"_temp
set hash32 = hash32_temp
}

Thanks again for all your help.
> > >> 123456789012345678901234567890123456789012345678901234567890123456789012345­67890
> > >>>>> - Show quoted text -- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages