Adam Skurek · Sep 28, 2017

Crypt-compatible COS function/implementation - has anyone seen this code?



I am looking for ObjectScript implementation of crypt-compatible function, that generates md5 salted hashes (output is in the form of $1$salt$hash). From what I understand it uses its own spin on md5 algorithm:



Does Cache have something like that built in?

Has somebody here seen it implemented somewhere?






I have found description of the underlying algorithm here:


0 7 334 2


Take a look at class %SYSTEM.Encryption, it's all there.

I am trying to generate same output as crypt function (CRYPT_MD5 flavor).

So for example


returns $1$1a2b3c4d$Y5tt50CQ12xW2saeYnI43, which is not same as pure MD5 hash (like $SYSTEM.Encryption.MD5Hash).

From documentation it seems that crypt creates derived hash based on MD5, but it is not the same.


Thanks, but unfortunately I am unable to find suitable DLL for Win64 with crypt function. I have found 32bit version (GnuWin32/crypt), but it does not work on 64bit environment.

Your options are:

  • Try to compile crypt only under win x64 (libc as a whole can't be compiled under windows, but maybe you can compile crypt module)
  • PHP doc you referenced states that PHP has it's own fallback implementation when OS does not provide crypt implementation. Check where does PHP search for crypt implementation on windows - it's probably some C lib and call it too
  • Write the algorithm yourself, here's  a good guide on that
  • Use another more secure hashing algorithm, for example SHA-512

Thank you. We are now using Java gateway and we want to replace this with something more native.  So it seems that writing own implementation in COS is the only option left. I was hoping that someone has already done that ;)

There is also CNA project - it provides an interface for using native C-compatible shared libraries without anything but Caché ObjectScript code. CNA is a wrapper for libffi. CNA consists of native library (libcna) and Caché class (CNA.CNA). It is a wrapper around $zf functions (you can use them directly too).

Here's the code to call crypt using CNA:

Class CNA.Crypt

/// do ##class(CNA.Crypt).Crypt()
ClassMethod Crypt(key = "2Ggaobjb", salt = "$1$1a2b3c4d$")
    set cna = ##class(CNA.CNA).%New("/InterSystems/forCLM/") ; Creates object of CNA.CNA class.
    do cna.LoadLibrary("/lib/x86_64-linux-gnu/")      ; Loads C standard library (crypto) in CNA

    set keyPointer = cna.ConvertStringToPointer(key) ; Converts the string into char array, and saves pointer to the first element

    set saltPointer = cna.ConvertStringToPointer(salt)

    set argTypes = $lb(cna.#POINTER, cna.#POINTER)   ; function argument types
    set result = cna.CallFunction("crypt",          ; Passes the name of the function,
                                cna.#POINTER,       ; type of return value,
                                argTypes,         ; list of argument types,
                                keyPointer, saltPointer)           ; and comma-separated arguments */    
    write cna.ConvertPointerToString(result), !      
    do cna.FreeLibrary()


Sample output:

do ##class(CNA.Crypt).Crypt()

do ##class(CNA.Crypt).Crypt("ABC", "$1$12345678$")