About cookies on this site Our websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising. For more information, please review your options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.
Question & Answer
Question
Example of how to use Qc3CalculateHMAC with ILE RPG IV program.
Answer
Note: The following code is provided as-is, IBM accepts no responsibility for it's correctness or use. Assistance modifying the example for your needs would be provided by lab services. |
This sample program hardcodes the data to be hashed and the key:
Data - stringtobehashed
Key - hashkeyhashkeyaahashkeyhashkeyaa
Note: The minimum key length for SHA-256 is 32 bytes per the API document:
https://www.ibm.com/docs/en/i/7.5?topic=ssw_ibm_i_75/apis/qc3calhm.html
Before calculating the HMAC hash, the data is converted to CCSID 1208 with iconv() to replicate results that would be seen if you are comparing the data with a hash received from a Web site that is using Unicode data rather than EBCDIC.
Example ILE RPG IV HMACRPG1:
Type command, press Enter.
===> CALL HMACRPG1
H DFTACTGRP(*NO)
H debug
* Copyright (c) 2006,2011 Scott C. Klement
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
*/
d iconv_t DS qualified
d based(StructureTemplate)
d return_value 10I 0
d cd 10I 0 dim(12)
d QtqCode_T DS qualified
d CCSID 10I 0 inz
d ConvAlt 10I 0 inz
d SubsAlt 10I 0 inz
d ShiftAlt 10I 0 inz
d InpLenOp 10I 0 inz
d ErrorOpt 10I 0 inz
d Reserved 8A inz(*ALLx'00')
d iconv_code_t DS qualified
d owner 8a inz('IBMCCSID')
d CCSID 5a inz('00000')
D ReservedTo
d ConvAlt 3a inz('000')
D overlay(ReservedTo)
d SubsAlt 1a inz('0')
D overlay(ReservedTo:*next)
d ShiftAlt 1a inz('0')
D overlay(ReservedTo:*next)
d InpLenOpt 1a inz('0')
D overlay(ReservedTo:*next)
d ErrorOpt 1a inz('0')
D overlay(ReservedTo:*next)
d ReservedFrom 12A inz(*ALLx'00')
D overlay(ReservedTo:*next)
d QtqIconvOpen PR extproc('QtqIconvOpen')
d like(iconv_t)
d toCode likeds(QtqCode_t) const
d fromCode likeds(QtqCode_t) const
D iconv_open PR extproc('iconv_open')
D like(iconv_t)
D toCode like(iconv_code_t) const
D fromCode like(iconv_code_t) const
d iconv PR 10U 0 extproc('iconv')
d cd like(iconv_t) value
d inbuf *
d inbytesleft 10U 0
d outbuf *
d outbytesleft 10U 0
d QlgTransformUCSData...
d PR 10U 0 extproc('QlgTransformUCSData')
d xformtype 10i 0 value
d inbuf *
d inbytesleft 10U 0
d outbuf *
d outbytesleft 10U 0
d outspacereq 10U 0
D ICONV_FAIL C CONST(4294967295)
D iconv_close PR 10I 0 extproc('iconv_close')
D cd like(iconv_t) value
*----------------------------------------
d from37 s 256a
d from37len s 10u 0
D outputbuf s 256a
D outputlen s 10u 0
d source ds likeds(QtqCode_t)
d inz(*likeds)
d target ds likeds(QtqCode_t)
d inz(*likeds)
d toEBC ds likeds(iconv_t)
D p_input s *
D p_output s *
D inputleft s 10u 0
D outputleft s 10u 0
*-------------hash parms----------------
d binaryHMAC s 32a
d SHA_256 c const(3)
D DataLen s 10u 0
d dataToHash s 256a
d $hex s 64a
d Nullfield s 100a
d MySalt s 64a
D SaltLen s 10u 0
*---------------------------------------------------------------------
* Stand Alone Fields - BOTTOM
*---------------------------------------------------------------------
D ErrorCode DS qualified
D bytesProv 10i 0 inz(0)
D bytesAvail 10i 0 inz(0)
D WsErrorCode DS qualified
D bytesProv 10i 0 inz(0)
D bytesAvail 10i 0 inz(0)
D my_key DS qualified
D Type 10i 0 inz(SHA_256)
D Len 10i 0
D Fmt 1a inz('0')
D 3a
D Value 64a
d cvthc PR ExtProc('cvthc')
d target 65534A options(*varsize)
d src_bits 32767A options(*varsize) const
d tgt_length 10I 0 value
D GetHMAC PR ExtProc('Qc3CalculateHMAC')
D datatohash 256a const options(*varsize)
D pinDataLen 10i 0 const
D pinFormat 8a const
D palgDesc 10i 0 const
D palgDescFmt 8a const
D pkeyDesc 32767a const options(*varsize)
D pkeyDescFmt 8a const
D pcryptoProv 1a const
D pcryptoDev 10a const
D pHMAC 64a options(*varsize)
D pErrorCode 32767a options(*varsize)
/FREE
//data to hash
from37 = 'stringtobehashed';
//data to hash length
from37len = %len(%trimr(from37));
// set conversion from 37 to 1208
// -----------------------------------------------
source.CCSID = 37;
target.CCSID = 1208;
toEBC = QtqIconvOpen( target: source );
if (toEBC.return_value = -1);
// handle error...
endif;
// -----------------------------------------------
// Translate data.
//
// the iconv() API will increment/decrement
// the pointers and lengths, so make sure you
// do not use the original pointers...
// -----------------------------------------------
p_input = %addr(from37);
inputleft = from37len;
p_output = %addr(outputbuf);
outputleft = %size(outputbuf);
iconv( toEBC
: p_input
: inputleft
: p_output
: outputleft );
// -----------------------------------------------
// if needed, you can calculate the length of
// the decoded data by subtracting the amount
// of space left in the buffer from the total
// buffer size.
//
// At this point, 'outputbuf' should contain
// the EBCDIC data.
// -----------------------------------------------
outputlen = %size(outputbuf) - outputleft;
DataToHash = %subst(outputbuf:1:outputlen);
DataLen = outputlen;
//dump;
//encode the hash key per API doc
//The minimum length for an SHA-256 HMAC key is 32 bytes
from37 = 'hashkeyhashkeyaahashkeyhashkeyaa';
//hash key len
from37len = %len(%trimr(from37));
clear outputbuf;
p_input = %addr(from37);
inputleft = from37len;
p_output = %addr(outputbuf);
outputleft = %size(outputbuf);
iconv( toEBC
: p_input
: inputleft
: p_output
: outputleft );
outputlen = %size(outputbuf) - outputleft;
MySalt = %subst(outputbuf:1:outputlen);
SaltLen = outputlen;
//dump;
// -----------------------------------------------
// you can call iconv() many more times if you
// want, using the same 'toEBC' table for
// translation.
// - -
// when you are completely done, call iconv_close()
// to free up memory.
// -----------------------------------------------
iconv_close(toEBC);
//---------------------------------------------------------
// Calculate the SHA-256 HMAC hash
//---------------------------------------------------------
Nullfield = *allx'00';
my_key.value = %TRIMR(MySalt) + Nullfield;
my_key.len = SaltLen;
monitor;
GetHMAC( DataToHash
: DataLen
: 'DATA0100'
: SHA_256
: 'ALGD0500'
: my_key
: 'KEYD0200'
: '0'
: *blanks
: binaryHMAC
: ErrorCode );
on-error;
WsErrorCode = ErrorCode;
Dsply 'Error in Conversion';
endmon;
cvthc( $hex: binaryHMAC: %len(binaryHMAC)*2);
//review the dump spool file to see HMAC in $hex parm
dump;
*inlr = '1';
return;
/end-free
Compile using CRTBNDRPG.
Call program from command line.
Call program from command line.
Type command, press Enter.
===> CALL HMACRPG1
Display the generated spoolfile QPPGMDMP and examine variable $HEX
This is a partial snippet of the QPPGMDMP spoolfile :
Internal Indicators:
LR '0' MR '0' RT '0' 1P '0'
NAME ATTRIBUTES VALUE
$HEX CHAR(64) '39B0B5FE1C9A5EAB64E714BCEBCD938EC49E9C0038AA53D344355F68AE6CDAC8'
VALUE IN HEX 'F3F9C2F0C2F5C6C5F1C3F9C1F5C5C1C2F6F4C5F7F1F4C2C3C5C2C3C4F9F3F8C5C3F4F9C5F9C3F0F0'X
41 'F3F8C1C1F5F3C4F3F4F4F3F5F5C6F6F8C1C5F6C3C4C1C3F8'X
BINARYHMAC CHAR(32) ' ^§Ú ª;¿ÀX ¯ÔòlþDÆæ ¡ëLà ¬ÇÞ%¹H'
VALUE IN HEX '39B0B5FE1C9A5EAB64E714BCEBCD938EC49E9C0038AA53D344355F68AE6CDAC8'X
DATALEN UNS(10) 16 '00000010'X
[{"Type":"MASTER","Line of Business":{"code":"LOB68","label":"Power HW"},"Business Unit":{"code":"BU070","label":"IBM Infrastructure"},"Product":{"code":"SWG60","label":"IBM i"},"ARM Category":[{"code":"a8m3p000000hB4rAAE","label":"API"},{"code":"a8m0z0000000CHtAAM","label":"Programming ILE Languages"}],"ARM Case Number":"","Platform":[{"code":"PF012","label":"IBM i"}],"Version":"All Versions"}]
Was this topic helpful?
Document Information
More support for:
IBM i
Component:
API, Programming ILE Languages
Software version:
All Versions
Operating system(s):
IBM i
Document number:
666847
Modified date:
25 November 2024
UID
nas8N1021175
Manage My Notification Subscriptions