APIs by Example: The Calculate Hash Value Command

Back in time the _CIPHER MI instruction was the only immediately available function to produce an MD5 (Message Digest) or SHA-1 (Secure Hash Algorithm) hash value. Now that the SHA-1 algorithm has been deprecated, it appears that the _CIPHER MI instruction does not support the SHA-256 hash algorithm.

IBM probably decided to focus their effort on the more recent Calculate Hash (Qc3CalculateHash) API.

As documented, the Qc3CalculateHash API supports the MD5 as well as SHA-1 to SHA-512 hash algorithms, and will probably continue to be enhanced, if and when new algorithms are implemented. I have written a very simple Calculate Hash Value (CLCHASHVAL) command for the purpose of demonstrating how to call he Qc3CalculateHash API. The command processing program could easily be adapted to more specific requirements, given the need.

The Calculate Hash Value command is based on the following source members:

CBX277    RPGLE    Calculate Hash Value - CPP              
CBX277S   RPGLE    Encrypt and Decrypt Data - services     
CBX277B   SRVSRC   Encrypt and Decrypt Data - services     
CBX277H   PNLGRP   Calculate Hash Value - Help             
CBX277X   CMD      Calculate Hash Value
CBX277M   CLP      Calculate Hash Value - Build command

Compiling and running the CL-program CBX277M will create the utility for you, once you’ve copied the other source members to their respective default source files. The source members are located in the zip file ClcHashVal.zip available here:

Download the save file containing the source code.

Postscript: I have added the Calculate File Hash Value (CLCFILHASH) command to the download zip-file. The CLCFILHASH command is similar to the CLCHASHVAL command, but will produce the hash value based on the content of a specified input stream file name. You’ll find compilation instructions in each of the respective source file headers:

CBX2772   RPGLE    Calculate File Hash Value - CPP   
CBX2772H  PNLGRP   Calculate File Hash Value - Help  
CBX2772X  CMD      Calculate File Hash Value            

14 thoughts on “APIs by Example: The Calculate Hash Value Command

  1. Hi Carten
    sorry for disturbing you .. i have downloaded the zip ClcHashVal.zip, but running the command CLCHASHVAL, i find the result different from some online hash calculator;
    example if i run CLCHASHVAL CALCDATA(ABC) HASHALG(*SHA256)
    Input . . . : ABC
    Hash value . :
    5202BF40821662BF1AD7D9C9B558056775D9D6BF8AA1C00492BCA8556B02772F
    but if go to for example to https://www.xorbin.com/tools/sha256-hash-calculator
    the result is
    b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78
    where am i wrong ?
    Thanks in advance

    Like

    1. Hi Angiolo,

      Thanks for your e-mail! The difference in the results you’re seeing, is due to two different character sets being involved. Cryptographic processing is always based on the binary value of an input string – even if you see it as characters.

      The CLCHASHVAL command running on a System i, is therefore acting on an EBCDIC character set when you specify the input value ‘ABC’ – which is equal to the hexadecimal value x’C1C2C3’.
      https://en.wikipedia.org/wiki/EBCDIC

      And this site https://www.xorbin.com/tools/sha256-hash-calculator being a web-page, is seeing the UTF-8 representation for the same letters – so here ‘ABC’ amounts to x’414243’.
      https://en.wikipedia.org/wiki/UTF-8

      This topic is explained in more detail here:
      https://www.di-mgt.com.au/cryptoInternational2.html

      If you run the following command you should see the result you’d expect:
      CLCHASHVAL CALCDATA(X’414243′) HASHALG(*SHA256)

      – Because now the CLCHASHVAL is processing the same binary value as the http://www.xorbin.com site does.

      Let me know if you have any questions, or need me to elaborate further.

      Like

  2. Hello,

    I am trying to build the tool and when doing crtsrvpgm it tells me Definition not found for symbol ‘CLCHASHVAL’.
    Definition not found for symbol ‘CVTCHRHEX’.
    Any idea to make it working ?

    thanks in advance
    take care
    jp

    Like

    1. It seems to me that you’re trying to compile the CPP source CBX277, rather than service program CBX277S. Are you using the CBX277M CL-program to create all the objects involved in the CLCHASHVAL command?

      Like

  3. YES I am using the cbx277M cl pour build the tool and when the clp is doing
    CRTSRVPGM with EXPORT(*SRCFILE)
    Definition not found for symbol ‘CVTCHRHEX’.
    Definition not found for symbol ‘RMVALGCTX’.

    I ‘ve got error

    CPF5D05

    Like

  4. also, when compiling I’ve got this problem now

    * * * * * E N D O F E X T E R N A L R E F E R E N C E S * * * * *
    5770WDS V7R2M0 140418 RN IBM ILE RPG JPD/CBX277
    M e s s a g e S u m m a r y
    Msg id Sv Number Message text
    *RNF8044 20 1 Source records exist but no array or table definition found
    *RNF7023 40 1 The Compiler cannot determine how the program can end.

    Like

  5. Hello Carsten –

    I am using your example with calculate hash, but I didn’t know if you had an example of Qc3CalculateSignature using a private key? I am having to create an OAUTH header in an HTTP api. Thanks.

    Like

    1. Hello Joshua,

      I can send you an example using a private key with the Qc3CalculateSignature API and the associated public key with the Qc3VerifySignature API to demonstrate the usage of the two APIs – would that be useful?

      Like

  6. Hello Carsten – I came across your fantastic article. I got your CLCHASHVAL program working first time and it’s something I’ve been looking for, so thank you for this. I do have one question about you command. Is there a particular reason why the hash value is all in upper case? My understanding is that the hash value is case-sensitive. Can you provide some insights?

    Thank you for the great work!

    Like

    1. Hello Eddie,
      Thanks for your note. The hash value is actual a binary value – every byte can be in the value range of x’00’ to x’FF’, many of which are neither possible to display or print. In order to display and enter those values I therefore convert the hash value to hex nibbles (4 bit values) ‘0’ to ‘F’. An 8 byte hash value is consequently shown as an 16 byte nibble string. Let me know if you have any further questions.

      Like

Leave a reply to jpdlxhotmailfr Cancel reply