Question
· Sep 28, 2017

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

Hello,

 

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:

 

https://en.wikipedia.org/wiki/Crypt_(C)
http://php.net/manual/en/function.crypt.php
http://www.gnu.org/software/libc/manual/html_node/crypt.html

 

 

Does Cache have something like that built in?

Has somebody here seen it implemented somewhere?

 

Thanks.

 

 

Added:

I have found description of the underlying algorithm here: https://www.vidarholen.net/contents/blog/?p=32

Discussion (7)0
Log in or sign up to continue

I am trying to generate same output as http://php.net/manual/en/function.crypt.php crypt function (CRYPT_MD5 flavor).

So for example

$salt=crypt("2Ggaobjb","$1$1a2b3c4d$");

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.

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

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/libcna.so") ; Creates object of CNA.CNA class.
    do cna.LoadLibrary("/lib/x86_64-linux-gnu/libcrypt-2.23.so")      ; 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()
>$1$1a2b3c4d$Y5tt50CQ12xW2saeYnI43.

do ##class(CNA.Crypt).Crypt("ABC", "$1$12345678$") 
>$1$12345678$0QgUhxfT5h1pvtkhF5pzx/