How to use HMAC SHA256? - sha256

As per the various docs that I have read for using HMAC SHA256, I have understood that:
H (K XOR opad, H (K XOR ipad, text)) where H in my case is SHA256.
But, SHA256 input has only one parameter i.e a Message.
Whereas H(K,text) has two inputs.
So how to calculate H(k,text)?
Should I first encode text with k and then use H(encoded_text), where encoded_text will be used as a message?
Thank You

H() is your cryptographic hash function, in this case SHA256() but
could also be MD5 or whatever;
K is your predifined key
Text is the message to be authenticated
opad be the outer padding (0x5c5c5c…5c5c, one-block-long hexadecimal
constant)
ipad be the inner padding (0x363636…3636, one-block-long hexadecimal
constant)
Then HMAC(K,m) is mathematically defined by
HMAC(K,m) = H((K ⊕ opad) ∥ H((K ⊕ ipad) ∥ m)).
blocksized is determined by your hash function (MD5 would be 64
bytes)
o_key_pad = [opad * blocksize] ⊕ key
i_key_pad = [ipad * blocksize] ⊕ key
Your result would be:
H(o_key_pad || H(i_key_pad || TEXT))
You can find a good read here:
http://timdinh.nl/index.php/hmac/
With also the following pseudocode which almost looks like mine :
function hmac (key, message)
opad = [0x5c * blocksize] // Where blocksize is that of the underlying hash function
ipad = [0x36 * blocksize]
if (length(key) > blocksize) then
key = hash(key) // Where 'hash' is the underlying hash function
end if
for i from 0 to length(key) - 1 step 1
ipad[i] = ipad[i] XOR key[i]
opad[i] = opad[i] XOR key[i]
end for
return hash(opad || hash(ipad || message)) // Where || is concatenation
end function

Related

decoding base64 encoded text with POSIX awk

In a bash script that I'm writing for Linux/Solaris I need to decode more than a hundred thousand base64-encoded text strings, and, because I don't wanna massively fork a non-portable base64 binary from awk, I wrote a function that does the decoding.
Here's the code of my base64_decode function:
function base64_decode(str, out,i,n,v) {
out = ""
if ( ! ("A" in _BASE64_DECODE_c2i) )
for (i = 1; i <= 64; i++)
_BASE64_DECODE_c2i[substr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i,1)] = i-1
i = 0
n = length(str)
while (i <= n) {
v = _BASE64_DECODE_c2i[substr(str,++i,1)] * 262144 + \
_BASE64_DECODE_c2i[substr(str,++i,1)] * 4096 + \
_BASE64_DECODE_c2i[substr(str,++i,1)] * 64 + \
_BASE64_DECODE_c2i[substr(str,++i,1)]
out = out sprintf("%c%c%c", int(v/65536), int(v/256), v)
}
return out
}
Which works fine:
printf '%s\n' SmFuZQ== amRvZQ== |
LANG=C command -p awk '
{ print base64_decode($0) }
function base64_decode(...) {...}
'
Jane
jdoe
SIMPLIFIED REAL-LIFE EXAMPLE THAT DOESN'T WORK AS EXPECTED
I want to get the givenName of the users that are members of GroupCode = 025496 from the output of ldapsearch -LLL -o ldif-wrap=no ... '(|(uid=*)(GroupCode=*))' uid givenName sn GroupCode memberUid:
dn: uid=jsmith,ou=users,dc=example,dc=com
givenName: John
sn: SMITH
uid: jsmith
dn: uid=jdoe,ou=users,dc=example,dc=com
uid: jdoe
givenName:: SmFuZQ==
sn:: RE9F
dn: cn=group1,ou=groups,dc=example,dc=com
GroupCode: 025496
memberUid:: amRvZQ==
memberUid: jsmith
Here would be an awk for doing so:
LANG=C command -p awk -F '\n' -v RS='' -v GroupCode=025496 '
{
delete attrs
for (i = 2; i <= NF; i++) {
match($i,/::? /)
key = substr($i,1,RSTART-1)
val = substr($i,RSTART+RLENGTH)
if (RLENGTH == 3)
val = base64_decode(val)
attrs[key] = ((key in attrs) ? attrs[key] SUBSEP val : val)
}
if ( /\nuid:/ )
givenName[ attrs["uid"] ] = attrs["givenName"]
else
memberUid[ attrs["GroupCode"] ] = attrs["memberUid"]
}
END {
n = split(memberUid[GroupCode],uid,SUBSEP)
for ( i = 1; i <= n; i++ )
print givenName[ uid[i] ]
}
function base64_decode(...) { ... }
'
On BSD and Solaris the result is:
Jane
John
While on Linux it is:
John
I don't know where the issue might be; is there something wrong with the base64_decode function and/or the code that uses it?
Your function generates NUL bytes when its argument (encoded string) ends with padding characters (=s). Below is a corrected version of your while loop:
while (i < n) {
v = _BASE64_DECODE_c2i[substr(str,1+i,1)] * 262144 + \
_BASE64_DECODE_c2i[substr(str,2+i,1)] * 4096 + \
_BASE64_DECODE_c2i[substr(str,3+i,1)] * 64 + \
_BASE64_DECODE_c2i[substr(str,4+i,1)]
i += 4
if (v%256 != 0)
out = out sprintf("%c%c%c", int(v/65536), int(v/256), v)
else if (int(v/256)%256 != 0)
out = out sprintf("%c%c", int(v/65536), int(v/256))
else
out = out sprintf("%c", int(v/65536))
}
Note that if the decoded bytes contains an embedded NUL then this approach may not work properly.
Problem is within base64_decode function that outputs some junk characters on gnu-awk.
You can use this awk code that uses system provided base64 utility as an alternative:
{
delete attrs
for (i = 2; i <= NF; i++) {
match($i,/::? /)
key = substr($i,1,RSTART-1)
val = substr($i,RSTART+RLENGTH)
if (RLENGTH == 3) {
cmd = "echo " val " | base64 -di"
cmd | getline val # should also check exit code here
}
attrs[key] = ((key in attrs) ? attrs[key] SUBSEP val : val)
}
if ( /\nuid:/ )
givenName[ attrs["uid"] ] = attrs["givenName"]
else
memberUid[ attrs["GroupCode"] ] = attrs["memberUid"]
}
END {
n = split(memberUid[GroupCode],uid,SUBSEP)
for ( i = 1; i <= n; i++ )
print givenName[ uid[i] ]
}
I have tested this on gnu and BSD awk versions and I am getting expected output in all the cases.
If you cannot use external base64 utility then I suggest you take a look here for awk version of base64 decode.
This answer is for reference
Here's a working base64_decode function (thanks #MNejatAydin for pointing out the issue(s) in the original one):
function base64_decode(str, out,bits,n,i,c1,c2,c3,c4) {
out = ""
# One-time initialization during the first execution
if ( ! ("A" in _BASE64) )
for (i = 1; i <= 64; i++)
# The "_BASE64" array associates a character to its base64 index
_BASE64[substr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i,1)] = i-1
# Decoding the input string
n = length(str)
i = 0
while ( i < n ) {
c1 = substr(str, ++i, 1)
c2 = substr(str, ++i, 1)
c3 = substr(str, ++i, 1)
c4 = substr(str, ++i, 1)
bits = _BASE64[c1] * 262144 + _BASE64[c2] * 4096 + _BASE64[c3] * 64 + _BASE64[c4]
if ( c4 != "=" )
out = out sprintf("%c%c%c", bits/65536, bits/256, bits)
else if ( c3 != "=" )
out = out sprintf("%c%c", bits/65536, bits/256)
else
out = out sprintf("%c", bits/65536)
}
return out
}
WARNING: the function requires LANG=C
It also doesn't check that the input is a valid base64 string; for that you can add a simple condition like:
match( str, "^([a-zA-Z/-9+]{4})*([a-zA-Z/-9+]{2}[a-zA-Z/-9+=]{2})?$" )
Interestingly, the code is 2x faster than base64decode.awk, but it's only 3x faster than forking the base64 binary from inside awk.
notes:
In a base64 encoded string, 4 bytes represent 3 bytes of data; the input have to be processed by groups of 4 characters.
Multiplying and dividing an integer by a power of two is equivalent to do bitwise left and right shifts operations.
262144 is 2^18, so N * 262144 is equivalent to N << 18
4096 is 2^12, so N * 4096 is equivalent to N << 12
64 id 2^6, so N * 4096 is equivalent to N << 6
65536 is 2^16, so N / 65536 (integer division) is equivalent to N >> 16
256 is 2^8, so N / 256 (integer division) is equivalent to N >> 8
What happens in printf "%c", N:
N is first converted to an integer (if need be) and then, WITH LANG=C, the 8 least significant bits are taken in for the %c formatting.
How the possible padding of one or two trailing = characters at the end of the encoded string is handled:
If the 4th char isn't = (i.e. there's no padding) then the result should be 3 bytes of data.
If the 4th char is = and the 3rd char isn't = then there's 2 bytes of of data to decode.
If the fourth char is = and the third char is = then there's only one byte of data.

How does the RarePackFour smartcontract generate a new "unique" number from a given random number?

I'm trying to understand the RarePackFour smart contract from the game gods unchained. I noticed that they use a random number to generate other "random" (in parenthesis because i dont think the newly generated numbers are random).
This the code im trying to understand. Could you help me understand what is happening here ?
function extract(uint random, uint length, uint start) internal pure returns (uint) {
return (((1 << (length * 8)) - 1) & (random >> ((start * 8) - 1)));
}
Bitwise operators are not realy a strong point for me so it would really help if you can help understand what is happening in the code.
Let's go with example:
length = 1
start = 1
random = 3250 # Binary: 0b110010110010
1. ((1 << (length * 8)) - 1) = 2^8 - 1 = 255 = 0B11111111 # Binary
2. (random >> ((start * 8) - 1))) = 0b110010110010 >> 7 = 0B11001 # Decimal 25
0B11111111 & 0B11001 = 0B11001 = 25
Usually if length * 8 > ((start * 8) - 1), the function returns random / (start * 8 - 1). Notice that it's only integer calculation in Solidity.

WEP shared-key authentication response generation

While I was capturing packets with Wireshark using my phone I tried connect to my access point which has WEP shared-key authentication (only for testing purposes) and I got the authentication packets which contained the IV, challenge text, etc. Then I tired to represent the ciphertext what my phone sent. So I already know the password and I took the IV, after that concatenated these two and put in the RC4 algorithm what gave me a keystream. I xored the keystream and the challenge text but this always gives me different chipertext than my phone sent.
Maybe I concatenate the IV and password in the wrong way or I'm using wrong algorithm and why is the response in the provided image is 147 bytes long?
Image of wireshark captured packets
Code what I'm using
def KSA(key):
keylength = len(key)
S = range(256)
j = 0
for i in range(256):
j = (j + S[i] + key[i % keylength]) % 256
S[i], S[j] = S[j], S[i] # swap
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # swap
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key):
S = KSA(key)
return PRGA(S)

How does this message splitting work?

I have been trying to reverse engineer various encryption algorithms in compiled code recently, and I came upon this code. It is a part of a RSA algorithm. I've noted that the key size is too small to encrypt/decrypt the data it's supposed to (in this case an int), so the code splits the message into two pieces, and encrypt/decrypt each, then sum them together. I've pulled the segments of code that splits and joins the message, and experimented with it. It appears that the numerical values that it uses is dependent on the n modulus. So, what exactly is this scheme, and how does it work?
uint n = 32437;
uint origVal = 12345;
uint newVal = 0;
for (int i = 0; i < 2; ++i)
{
ulong num = (ulong)origVal * 43827549;
//uint num2 = ((origVal - (uint)(num >> 32)) / 2 + (uint)(num >> 32)) >> 14;
uint num2 = (origVal + (uint)(num >> 32)) / 32768;
origVal -= num2 * n;
// RSA encrypt/decrypt here
newVal *= n;
newVal += origVal;
origVal = num2;
}
// Put newVal into origVal, to reverse
origVal = newVal;
newVal = 0;
for (int i = 0; i < 2; ++i)
{
ulong num = (ulong)origVal * 43827549;
//uint num2 = ((origVal - (uint)(num >> 32)) / 2 + (uint)(num >> 32)) >> 14;
uint num2 = (origVal + (uint)(num >> 32)) / 32768;
origVal -= num2 * n;
// RSA encrypt/decrypt here
newVal *= n;
newVal += origVal;
origVal = num2;
}
Note: it seems the operations applied are symmetric.
After using various values for origVal, I've found out that the first three lines after the for loop is just a division, with the line immediately after that a modulo operation. The lines
ulong num = (ulong)origVal * 43827549;
//uint num2 = ((origVal - (uint)(num >> 32)) / 2 + (uint)(num >> 32)) >> 14;
uint num2 = (origVal + (uint)(num >> 32)) / 32768;
translates into
uint valDivN = origVal / n;
and
origVal -= num2 * n;
into
origVal = origVal % n;
So the final code inside the for loop looks like this:
uint valDivN = origVal / n;
origVal = origVal % n;
// RSA encrypt/decrypt here
newVal*= n;
newVal+= origVal;
origVal = valDivN;
Analysis
This code splits values by taking the modulo of the original value, transforming it, then multiplying it by n, and tacking the transformation of the previous quotient onto the result. The lines uint valDivN = origVal / n; and newVal*= n; form inverse operations. You can think of the input message as having two "boxes". After the loop has run through, you get the transformed value put in opposite "boxes". When the message is decrypted, the two values in the "boxes" are reverse transformed, and put in their original spots in the "boxes". The reason the divisor is n is to keep the value being encrypted/decrypted under n, as the maximum value you can encrypt with RSA is no larger than n. There is no possibility of the wrong value being decrypted, as the code processes the packed message and extracts the part that should be decrypted prior to decrypting. The loop only runs twice because there is no chance for the quotient to exceed the size of an int (since the input is an int).

Websocket (draft 76) handshake difficulties!

I'm using the following keys to calculate the correct handshake response string:
Key1: 18x 6]8vM;54 *(5: { U1]8 z [ 8
Key2: 1_ tx7X d < nw 334J702) 7]o}` 0
Key3: 54:6d:5b:4b:20:54:32:75
I've calculated Key1 and Key2's values:
Key1: 0947fa63 (hex)
Key2: 0a5510d3
However I'm not sure on what to do next, from what I can gather, you concatenate them and MD5 it, but that doesn't seem to work out i.e.
MD5 hashing: 0947fa630a5510d3546d5b4b20543275
Help!
This is the python code for creating the response hash:
from hashlib import md5
import struct
....
hashed = md5(struct.pack('>II8s', num1, num2, key3)).digest()
In the example num1 and num2 are the numeric values of key1 and key2. key3 is the actual textual string (raw bytes) received.
The struct.pack() call is using big endian mode (for the numeric values) and packing them 4 bytes for each number followed by the 8 byte key3 string (bytes).
See the Documentation for the python struct module.
The C version would look more like this:
/* Pack it big-endian */
buf[0] = (num1 & 0xff000000) >> 24;
buf[1] = (num1 & 0xff0000) >> 16;
buf[2] = (num1 & 0xff00) >> 8;
buf[3] = num1 & 0xff;
buf[4] = (num2 & 0xff000000) >> 24;
buf[5] = (num2 & 0xff0000) >> 16;
buf[6] = (num2 & 0xff00) >> 8;
buf[7] = num2 & 0xff;
strncpy(buf+8, headers->key3, 8);
buf[16] = '\0';
md5_buffer(buf, 16, target);
target[16] = '\0';
md5_buffer is in glibc.
For further reference you can look at working implementations (where the above code came from) of websockify (disclaimer: I wrote websockify).
Here's my version:
https://github.com/boothead/stargate/blob/master/stargate/handshake.py#L104
If you use stargate then all of that nasty stuff is done for you :-)