Tink HMAC Key Derivation function (HKDF)HMAC Key Derivation function (HKDF) is used to derive an encryption key from a pass phrase [RFC 2104]. Initially HKDF creates a pseudorandom key (PRK) using a pass phrase and a salt value (and any other random functions which are relavent), in order to produce an HMAC hash function (such as HMAC-SHA256), along with a salt value. Next the PRK output is used to produce a key of the required length. If we generate a 16-byte output (32 hex characters), we have a 128-bit key, and a 32-byte output (64 hex characters) will generate a 256-bit key. HKDF uses a defined hash function. For a MAC function we take a key and a message. In secure method is just to take a hash of the key appended to the message. HKDF overcomes this weakness and uses HASH(K XOR opad, HASH(K XOR ipad, M)), and where K is the key, M is the message, opad is "0x36" repeated the number of times of the block size (B) and ipad is "0x5C" and again repeated for the size of the block [Tink Symmetric key][Tink MAC][Tink ECDSA/Ed25519]][Tink Hybrid encryption][Tink Envelope encryption][HKDF][Deterministic Authenticated Encryption]: |
Outline
The code is:
package com.helloworld; import java.util.Base64; import com.google.crypto.tink.aead.AeadConfig; import com.google.crypto.tink.subtle.Hex; import com.google.crypto.tink.subtle.Hkdf; public final class HelloWorld { public static void main(String[] args) throws Exception { AeadConfig.register(); String plaintext="hello"; int t=1; String method="HMACSHA1"; int bytes=8; String salthex="8e94ef805b93e683ff18"; if (args.length>0) plaintext=args[0]; if (args.length>1) bytes=Integer.valueOf(args[1]); if (args.length>2) t=Integer.valueOf(args[2]); if (args.length>3) salthex=args[3]; if (t==2) { method="HMACSHA256"; System.out.println("Method: HMACSHA256"); } else if (t==3) { method="HMACSHA384"; System.out.println("Method: HMACSHA384"); } else if (t==3) { method="HMACSHA512"; System.out.println("Method: HMACSHA512"); } else {System.out.println("Method: HMACSHA1");} byte[]salt =Hex.decode(salthex); byte[] encoded = Hkdf.computeHkdf(method,plaintext.getBytes(), salt, null, bytes); byte[] b64 = Base64.getEncoder().encode(encoded); String hex =Hex.encode(encoded); System.out.println("\nText:\t"+plaintext); System.out.println("Salt:\t"+salthex); System.out.println("\nHKDF:\t"+new String(b64)); System.out.println("HKDF:\t"+hex);
A sample run is:
Method: HMACSHA1 Text: hello Salt: 3e94ef805b93e683ff18 HKDF: iDyIsfG3IOND06caqFlDnA== HKDF: 883c88b1f1b720e343d3a71aa859439c
With Google Tink we finally get a code based which has now been hacked together over the years (such as with OpenSSL) and which is consistent in its usage and focused on API integration. It is a code based for a modern world.
Presentation
The following is a presentation related to Google Tink [slides]: