Snippets Project Page
Author: maroon
Added: 5y
Updated: Never
mIRC: used 6.35 & 7.52+
Hits: 1,012
Downloads: 6
Review: westor
Size: 8.72KB
2 0
Login to vote.
Binary Keys for $hmac() identifier
v1.0
Enable HMAC identifier prior to v7.42 for md5 and sha1, or also with hashes sha256 or sha512 if also installed my sha2M.dll (see https://mircscripts.net/DPk3u )
Enables the HMAC key parameter to be a binary variable or disk file, or allows either key or message parameter to be the contents of a binary item stored in a hash table.
Download
JSON
▲ Review
▼ Source
; $hmac2([text|&binvar|filename|hashtable item],[key|&binvar|filename|hashtable item],[hash[.R.M]],[dataN[-keyN]]) ; For mIRC prior to v7.42, you can have compatible support for the $hmac identifier by removing the '2' to rename ; this alias as 'hmac', and by installing sha2M.dll to allow $hmac() to use the $sha256 $sha384 $sha512 hashes. ; See https://mircscripts.net/DPk3u ; For v7.42-and-later, this script adds functionality where the key can be a binary variable or a disk file. ; ; Below assumes you already understand mIRC's $hmac() syntax. This alias exends with additional features: ; ; 1. The TypeN parameter can also be 2 hyphen-delimited numbers, where an optional number following the hyphen is ; the type for the key parameter (default = 0 text). This allows the key to be a binary variable or a disk file. ; Note that there's a limit to size of disk file used for Message or Key parameters because this alias must fit ; the entire diskfile into a binary variable, so the alias can append message data to key data. ; 2. If the N string before/after that hyphen contains 'a', it's used only by N=0 to apply the bset -ta switch to ; avoid UTF-8 encoding Unicode codepoints 128-255 when codepoints 256+ not also in that string. This is intended ; for compatibility between newer mIRC versions and v6.35 which does not UTF-8 encode ASCII 128-255. It will be ; difficult for v6 and v7 to share keys containing codepoints 256+ without them being stored as disk files. ; 3. Type N=3 for space-delimited hash table-name and item-name. This is intended for loading binary hashtable items ; into a binvar without your script needing to handle deletion of the temp &binvar used to load the contents. If ; the hashtable item contains normal text you should instead use $hget(table,item) and N=0. ; 4. Additional hash names sha224 sha-224 sha-256 sha-384 sha-512 sha-160 sha-320. These assume you've already created ; aliases which use sha2M.dll to calculate those hashes. The alias names containing a hyphen also support referencing ; the R and M parameters supported by sha2M.dll when tokenized by periods. sha-256.100.2 calls alias sha-256 using ; R=100 and M=2 parameters as $sha-256(&binvar,1,100,2) ; 5. Note for using binary keys: The HMAC design for keys shorter than 'blocksize' calls for those key lengths to be ; padded with 0x00's to make them have length=blocksize. Blocksize is 64 bytes for most hashes, but is 128 bytes for ; sha384/sha512 and sha2M.dll's sha-512 sha-256 and sha-320. This means that all binary keys of length blocksize or ; shorter which end with at least one 0x00's are not changed by shortening those keys to remove the trailing 0x00's ; nor by altering them to add trailing 0x00's. The only way to avoid this is to have your key either already padded ; to length blocksize, or have the key contain a length-byte, or define your key to not possibly end with 0x00. ; This issue doesn't affect longer keys because keys longer than blocksize are hashed before being used. ; ; Example: $hmac(foo bar,&key,sha256,3-1) = uses binary contents of table=foo item=bar as message, binvar &key as the key. ; $hmac2(message,t $+ $chr(233) $+ st,sha512,-0a) = key uses the 4-byte string without utf-8 encoding the accented-e, compatible output with v6.35 ; $hmac2(message,key,sha-256.100.1) = Uses sha2M.dll options to hash using 100 rounds and M=1 parameters. ; ; For compatibility with the built-in $hmac identifier, zero-length or missing 1=binvar 2=filename results in an error, ; but missing or zero length 0=text or 3=hash/item uses $null length key. ; ; https://tools.ietf.org/html/rfc2202 contains $hmac test vectors for md5/sha1, https://tools.ietf.org/html/rfc4231 contains ; vectors for sha224/256/384/512. Most of these use binary keys, so can't be used to verify $hmac identifier, but can be used ; to verify $hmac2() output. The https://www.freeformatter.com/hmac-generator.html allows any text string as message or as key, ; so can verify the $hmac identifier for all test vectors where both message and key are text. ; The "4.7. Test Case 6" from RFC 4231 verifies $hmac2() by returning the correct HMAC string for each valid $3 hashname: ; //bset &key 1 $str($base(aa,16,10) $chr(32),131) | echo -a $hmac2(Test Using Larger Than Block-Size Key - Hash Key First,&key,sha512,0-1) alias hmac2 { var %hash = $gettok($3,1,46) | if (%hash == $null) var %hash = sha1 | if (!$istok(sha1 sha256 sha512 md5 sha384 sha224 sha-256 sha-512 sha-384 sha-224 sha-160 sha-320,%hash,32)) goto syntax var %blocksize = 64 , %keytext.a , %msgtext.a , %syntax , %Rparm , %Mparm , %a = $remove(0 $+ $4,$chr(32)) var %msg.n = $gettok(%a,1,45) | if (a isin %msg.n) { var %msgtext.a = a | var %msg.n = $remove(%msg.n,a) } var %key.n = $gettok(%a,2,45) | if (a isin %key.n) { var %keytext.a = a | var %key.n = $remove(%key.n,a) } if (- isin %hash) { var %a = $remove($3,$chr(32)) , %Rparm = $gettok(%a,2,46) , %Mparm = $gettok(%a,3,46) } if (%hash isin sha512 sha384 sha-512 sha-384 sha-320) var %blocksize = 128 if (%key.n == $null) var %key.n = 0 | if ((%msg.n !isnum 0-3) || (%key.n !isnum 0-3)) goto syntax bunset &maroon.hmac.msg &maroon.hmac.key if (%key.n == 2) { var %s = $file($2).size | if (!%s) { var %syntax = Missing or zero-size $2 key file | goto syntax } if (%s isnum 1- $+ %blocksize) bread $qt($2) 0 %s &maroon.hmac.key else noop $hmac.hash.toolong.key(%hash,$2,2,%Rparm,%Mparm) } elseif (%key.n == 1) { var %s = $bvar($2,0) | if (!%s) { var %syntax = Missing $2 key binvar | goto syntax } if (%s isnum 1- $+ %blocksize) bcopy &maroon.hmac.key 1 $2 1 -1 else noop $hmac.hash.toolong.key(%hash,$2,1,%Rparm,%Mparm) } elseif (%key.n == 0) { var %s = $len($2) | if (%s) bset -t $+ %keytext.a &maroon.hmac.key 1 $2 var %s = $bvar(&maroon.hmac.key,0) | if (%s > %blocksize) noop $hmac.hash.toolong.key(%hash,&maroon.hmac.key,1,%Rparm,%Mparm) } elseif (%key.n == 3) { noop $hget($gettok($2,1,32),$gettok($2,2,32),&maroon.hmac.key) | var %s = $bvar(&maroon.hmac.key,0) if (%s > %blocksize) noop $hmac.hash.toolong.key(%hash,&maroon.hmac.key,1,%Rparm,%Mparm) } bset -c &maroon.hmac.key.inner 1 $str(54 $chr(32),%blocksize) bset -c &maroon.hmac.key.outer 1 $str(92 $chr(32),%blocksize) var %i = $bvar(&maroon.hmac.key,0) , %append = %blocksize + 1 while (%i) { var %a = $bvar(&maroon.hmac.key,%i) bset &maroon.hmac.key.inner %i $xor(%a,54) bset &maroon.hmac.key.outer %i $xor(%a,92) dec %i } if (%msg.n == 2) { var %s = $file($1).size | if (!%s) { var %syntax = Missing or zero-size $2 Message file | goto syntax } bread $qt($1) 0 %s &maroon.hmac.msg bcopy &maroon.hmac.key.inner %append &maroon.hmac.msg 1 -1 } elseif (%msg.n == 1) { var %s = $bvar($1,0) | if (!%s) { var %syntax = Missing $2 Message binvar | goto syntax } bcopy &maroon.hmac.key.inner %append $1 1 -1 } elseif (%msg.n == 0) { var %s = $len($1) | if (%s) bset -t $+ %msgtext.a &maroon.hmac.key.inner %append $1 } elseif (%msg.n == 3) { noop $hget($gettok($1,1,32),$gettok($1,2,32),&maroon.hmac.msg) var %s = $bvar(&maroon.hmac.msg,0) | if (%s) bcopy &maroon.hmac.key.inner %append &maroon.hmac.msg 1 -1 } var %a = $hmac.hash.function(%hash,&maroon.hmac.key.inner,1,%Rparm,%Mparm) bset &maroon.hmac.key.outer %append $regsubex(%a,/(\S\S)/g,$base(\t,16,10) $chr(32)) var %hash = $hmac.hash.function(%hash,&maroon.hmac.key.outer,1,%Rparm,%Mparm) bunset &maroon.hmac.msg &maroon.hmac.key &maroon.hmac.key.inner &maroon.hmac.key.outer return %hash :syntax echo -sc info %syntax * Invalid parameters: $ $+ hmac2([text|&binvar|filename|hashtable item],[key|&binvar|filename|hashtable item],[hash[.R.M]],[dataN[-keyN]]) | halt } ; $1 = sha1/md5/sha256/sha512/sha384 $2=datasource $3=type0-2 $4=%Rparm $5=%Mparm alias hmac.hash.toolong.key { bset -c &maroon.hmac.key 1 $regsubex($hmac.hash.function($1,$2,$3,$4,$5),/(\S\S)/g,$base(\t,16,10) $chr(32)) } ; $1 = sha1/md5/sha256/sha512/sha384 $2=&binvar-name $3=0/1/2 $4=%Rparm $5=%Mparm ; $4 and $5 are ignored as invalid parameter unless $1 contains a hyphen alias hmac.hash.function { if (- !isin $1) return $ [ $+ [ $+($1,$chr(40),$2,$chr(44),$3,$chr(41)) ] ] | return $ [ $+ [ $+($1,$chr(40),$2,$chr(44),$3,$chr(44),$4,$chr(44),$5,$chr(41)) ] ] }
Changelog:
0
0