From WikiChip
Editing mirc/identifiers/$hotp

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

This page supports semantic in-text annotations (e.g. "[[Is specified as::World Heritage Site]]") to build structured and queryable content provided by Semantic MediaWiki. For a comprehensive description on how to use annotations or the #ask parser function, please have a look at the getting started, in-text annotation, or inline queries help pages.

Latest revision Your text
Line 5: Line 5:
  
 
== Parameters ==
 
== Parameters ==
* '''key''' - The can be in a base16 format of either 40, 64 or 128 chars; or in a base32 format (not containing the '=' character) of any length that's a multiple of 8 greater than length 8; or plain text. The "Google Authenticator format" is implemented by allowing the base32 and base16 lengths to be upper/lower case-insensitive and optionally contain spaces, where the string length is evaluated before removing spaces, instead of the correct method where the string length is verified after spaces are removed. Also incorrect is allowing the spaces to be present when not following exactly 4 encoding characters. If the 40/64/128 lengths of base16 contain an odd number of non-space hex digits, the decoding method is undiscovered. For even-number count of hex digits, the hex is decoded to binary, with 0x00 bytes discarded. The remaining bytes are individually UTF-8 encoded. The correct method should have been to use these 3 lengths are the hex encoding of binary strings of length 20/32/64 bytes.
+
* '''key''' - The can be in a base16 format of either 40, 64 or 128 chars; or in a base32 format (not containing the '=' character) of any length that's a multiple of 8 greater than length 8; or plain text. The "Google Authenticator format" is implemented by allowing the base32 and base16 lengths to be upper/lower case-insensitive and optionally contain spaces, where the string length is evaluated before removing spaces, instead of the correct method where the string length is verified after spaces are removed. Also incorrect is allowing the spaces to be present when not following exactly 4 encoding characters. If the 40/64/128 lengths of base16 contain an odd number of non-space hex bytes, the decoding method is undiscovered.
 
* '''count''' - required. The 'counter' should never be used more than once with the same key, as it always returns the same number for the same number value. This is a 64-bit number with valid range 0 through 2^64-1. Non-numeric are removed from the end, and "+" removed from the beginning.
 
* '''count''' - required. The 'counter' should never be used more than once with the same key, as it always returns the same number for the same number value. This is a 64-bit number with valid range 0 through 2^64-1. Non-numeric are removed from the end, and "+" removed from the beginning.
 
* '''hash''' - optional, hashing algorithm, default to sha1. Also allowed: sha256, sha512, sha384, md5
 
* '''hash''' - optional, hashing algorithm, default to sha1. Also allowed: sha256, sha512, sha384, md5
Line 17: Line 17:
 
The /help describes 4 formats for the key. Here is the sequence of parsing:.<br />
 
The /help describes 4 formats for the key. Here is the sequence of parsing:.<br />
  
Rule #1. If key is a length 40/64/128 case-insensitive string that's a mix of spaces and/or case-insensitive hex digits, spaces are removed then the remaining pairs of hex digits are translated into a byte value. If the pair of hex digits is value 00, it is not added to the key. Otherwise, the byte values 1-255 are individually UTF-8 encoded and added to the key string. When there are an odd number of space characters causing an odd number of hex digits, the key is created in an un-discovered way where shifting the location of the spaces in the original string doesn't alter the output.<br/>
+
Rule #1. If key is a length 40/64/128 case-insensitive string that's a mix of spaces and/or case-insensitive hex digits, spaces are removed then the remaining pairs of hex digits are translated into a byte value. If the pair of hex digits is value 00, it is not added to the key. Otherwise, the byte values 1-254 are individually UTF-8 encoded and added to the key string. When there are an odd number of space characters causing an odd number of hex digits, the key is created in an un-discovered way where shifting the location of the spaces in the original string doesn't alter the output.<br/>
 
Rule#2. Else: If key length is 16 or greater and a multiple of 8 (except for matching rule #1) containing only A-F 2-7 a-f or spaces, and if removing spaces results in a valid case-insensitive Base32 encoded string, the spaces are stripped from the string, and the key is the binary decoded contents whose length is approximately 5/8ths the length of the remaining Base32 string. The decoded binary bytes are used as the key, with no 0x00's stripped and no UTF-8 encoding as done in #1 for hex-encoded strings.<br />
 
Rule#2. Else: If key length is 16 or greater and a multiple of 8 (except for matching rule #1) containing only A-F 2-7 a-f or spaces, and if removing spaces results in a valid case-insensitive Base32 encoded string, the spaces are stripped from the string, and the key is the binary decoded contents whose length is approximately 5/8ths the length of the remaining Base32 string. The decoded binary bytes are used as the key, with no 0x00's stripped and no UTF-8 encoding as done in #1 for hex-encoded strings.<br />
 
Rule #3. Else: Any remaining strings not matching the 1st 2 patterns are considered literal case-sensitive text keys, and the input is assumed to already be UTF-8 encoded where necessary.<br />
 
Rule #3. Else: Any remaining strings not matching the 1st 2 patterns are considered literal case-sensitive text keys, and the input is assumed to already be UTF-8 encoded where necessary.<br />
  
* Note: The actual Google Authenticator format should be: Case-insensitive base32 string of length 16/26/32 encoding a key of 80/128/160 bits, not the 16/24/32 lengths decribed in /help. Base32 string can optionally have spaces inserted into that 16/26/32 character string only if immediately preceded by exactly 4 base32 characters. The purpose of adding spaces is to improve accuracy when entering the key by hand into a 2nd device while viewing the encoded string on a 1st device. $hotp is not recognizing the 128-bit key because 26 isn't a multiple of 8, unless it's padded with 6 spaces so the key length is 32 and becomes a multiple of 8. $hotp is not supporting the base32 encoded string padded by spaces into being divided into groups of 4 because that space-padded string isn't a multiple of 8, so you must $remove(key,$chr(32)) before $hotp correctly recognizes the 16 and 32 character strings as 80-bit or 160-bit keys. Instead of supporting length 16/26/32 AFTER spaces are removed, $hotp is incorrectly using base32 strings of lengths 16/24/32 BEFORE spaces are removed, then extended that same behavior to strings whose length including spaces is any multiple of 8 greater than 8.
+
* Note: The actual Google Authenticator format should be: Case-insensitive base32 string of length 16/26/32 encoding a key of 80/128/160 bits. Base32 string can optionally have spaces inserted into that 16/26/32 character string only if immediately preceded by exactly 4 base32 characters. The purpose of adding spaces is to improve accuracy when entering the key into a 2nd device while viewing the encoded string on a 1st device. $hotp is not recognizing the 128-bit key because 26 isn't a multiple of 8, unless it's padded with 6 spaces so the key length is 32 and becomes a multiple of 8. $hotp is not supporting the base32 encoded string padded by spaces into being divided into groups of 4 because that space-padded string isn't a multiple of 8, so you must $remove(key,$chr(32)) before $hotp correctly recognizes the 16 and 32 character strings as 80-bit or 160-bit keys. Instead of supporting length 16/26/32 AFTER spaces are removed, $hotp is incorrectly using base32 strings of lengths 16/24/32 BEFORE spaces are removed, then extended that same behavior to strings whose length is any multiple of 8 greater than 8.
  
 
* Note: Because $hotp uses decoded base16 strings after deleting 0x00 bytes and then UTF-8 encoding byte values 128-255 into 2 bytes, keys are replaced by UTF-8 encoded text strings an average of 50% longer, and hex strings with 0x00's in different positions produce matching keys. Because the $hmac format appends 0x00's to a key shorter than 512 bits, all strings which decode into the $null string or a string entirely consisting of 1-128 0x00's or have differing number of trailing 0x00's produce identical outputs.<br />
 
* Note: Because $hotp uses decoded base16 strings after deleting 0x00 bytes and then UTF-8 encoding byte values 128-255 into 2 bytes, keys are replaced by UTF-8 encoded text strings an average of 50% longer, and hex strings with 0x00's in different positions produce matching keys. Because the $hmac format appends 0x00's to a key shorter than 512 bits, all strings which decode into the $null string or a string entirely consisting of 1-128 0x00's or have differing number of trailing 0x00's produce identical outputs.<br />
  
The '''count''' parameter should be in the range 0 to 2^64-1. All values greater than 2^64-1 return the same password as when 2^64-1 is used. For 64-bit negative numbers, negative N returns the same password as when 2^64 is added to the negative number. If using a count value greater than 2^53, $hotp correctly translates it to binary, but $calc() does not perform accurate integer math for all values above 2^53.<br />
+
The '''count''' parameter should be in the range 0 to 2^64-1. All values greater than 2^64-1 return the same password as when 2^64-1 is used. For 64-bit negative numbers, negative N returns the same password as when +2^64 less N is used. If using a count value greater than 2^53, $hotp correctly translates it to binary, but $calc() does not perform accurate math when arriving at values above 2^53.<br />
  
 
The OTP in HOTP stands for One Time Password, which is only 'one time' if the application makes sure that the same 'count' value is never used twice. Either the server and the client keep track of the last count used with each key, or each use the current time for a very short interval as defined for $totp().
 
The OTP in HOTP stands for One Time Password, which is only 'one time' if the application makes sure that the same 'count' value is never used twice. Either the server and the client keep track of the last count used with each key, or each use the current time for a very short interval as defined for $totp().
Line 112: Line 112:
 
These produce a different string than the all-zeroes hex string does, showing that keys of length 40/64/128 containing an odd number of hexadecimal digits do strip the spaces before decoding the remaining string, but they do not append or prepend the 0 digit to handle the not-paired hex digit, so they are processing the string in an unknown manner. Moving the space to a different position shows the spaces are stripped before decoding the string into identical keys. Having an odd-number of zeroes in the 40-byte string always returns the same number that's different than the number returned when there's an even number of zeroes. But so far I have not been able to figure out how mIRC decodes a hex string containing an odd number of hex digits.
 
These produce a different string than the all-zeroes hex string does, showing that keys of length 40/64/128 containing an odd number of hexadecimal digits do strip the spaces before decoding the remaining string, but they do not append or prepend the 0 digit to handle the not-paired hex digit, so they are processing the string in an unknown manner. Moving the space to a different position shows the spaces are stripped before decoding the string into identical keys. Having an odd-number of zeroes in the 40-byte string always returns the same number that's different than the number returned when there's an even number of zeroes. But so far I have not been able to figure out how mIRC decodes a hex string containing an odd number of hex digits.
 
</source>
 
</source>
== Warning ==
 
Through v7.53, $hmac and $hotp and $totp using hash method sha512 or sha384 and a key whose length is 65-128 returned an incorrect value due to replacing the key with its own hash for lengths 65+ instead of only for 129+.
 
<pre>//echo -a $hotp($str(z,65),0,sha512,9) should be 187092660</pre>
 
 
== Compatibility ==
 
== Compatibility ==
 
{{mIRC compatibility|7.42}}
 
{{mIRC compatibility|7.42}}
 +
 
== See Also ==
 
== See Also ==
 
{{collist
 
{{collist

Please note that all contributions to WikiChip may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see WikiChip:Copyrights for details). Do not submit copyrighted work without permission!

Cancel | Editing help (opens in new window)