How do you hash a string to SHA512 in Swift?

Java function for HMAC-MD5 hash.

  • I need a small program/function to generate a HMAC-MD5 hash signature value in Java. I have a secret private key value that I need to use to hash several fields represented as one long string concatenated together with ^ Given a key similar to "HyP8N54REmgEX33V" (I made this up, but its of that length) I need to generate a hash of a string similar to "loginid^55^UTCtimeinsecondssince1970^9.50^" The ^ are to divide the fields and are part of the hash. The function should return a String representation of the hashed value. An example in PHP is: function InsertFP ($loginid, $txnkey, $amount, $sequence, $currency = "") { $tstamp = time (); $fingerprint = hmac ($txnkey, $loginid . "^" . $sequence . "^" . $tstamp . "^" . $amount . "^" . $currency); The function skeleton could be: public static String getKey(String loginID, String sequence,String time,String amount){ } Thanks -Brad

  • Answer:

    Hi Brad, The HMAC-MD5 has been provided by Michael Lecuyer as freely available source at: http://www.theorem.com/java/Free.htm#HMAC-MD5 The full source code from the above resource has been reproduced here for your convenience, but you can alternatively just download the java source file available at the above URL. /* BEGIN SOURCE CODE */ package com.theorem.misc; import com.theorem.misc.MD5; /** * JAVA translation of the hmac_md5() function from RFC 2104. * <P> * HMAC: Keyed-Hashing for Message Authentication. * <P> * Copyright (C) Michael Lecuyer (1999). All Rights Reserved. * <P> * This source code and extensions of it may be used freely as long as the * copyright notice above and this paragraph are included in all copies and * derivative works. * <P> * A notice about the original C code: * Copyright (C) The Internet Society (1999). All Rights Reserved. * <P> * This document and translations of it may be copied and furnished to * others, and derivative works that comment on or otherwise explain it * or assist in its implementation may be prepared, copied, published * and distributed, in whole or in part, without restriction of any * kind, provided that the above copyright notice and this paragraph are * included on all such copies and derivative works. However, this * document itself may not be modified in any way, such as by removing * the copyright notice or references to the Internet Society or other * Internet organizations, except as needed for the purpose of * developing Internet standards in which case the procedures for * copyrights defined in the Internet Standards process must be * followed, or as required to translate it into languages other than * English. The limited permissions granted above are perpetual and will * not be revoked by the Internet Society or its successors or assigns. * This document and the information contained herein is provided on an * "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING * TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE." * <P> * * @author Michael Lecuyer <[email protected]>. * @version 1.0 December 26, 1999 */ public class HMAC_MD5 { /** * Run standard tests from the RFC: */ public static void main(String arg[]) { String expectedHash; byte digest[]; HMAC_MD5 hm; System.out.println("Test Vectors from RFC 2104 - HMAC: Keyed-Hashing for Message Authentication"); System.out.println("This test uses HMAC-MD5."); System.out.println(); System.out.println("Test #1:"); // Test #1: byte key1[] = { (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b, (byte)0x0b }; String text1 = "Hi There"; expectedHash = "0X9294727A3638BB1C13F48EF8158BFC9D"; hm = new HMAC_MD5(key1); hm.addData(text1.getBytes()); digest = hm.sign(); System.out.println("Calculated hash 0X" + hm); System.out.println(" Expected hash " + expectedHash); // Test #2 System.out.println(); System.out.println("Test #2:"); byte key2[] = "Jefe".getBytes(); String text2 = "what do ya want for nothing?"; expectedHash = "0X750C783E6AB0B503EAA86E310A5DB738"; hm = new HMAC_MD5(key2); hm.addData(text2.getBytes()); digest = hm.sign(); System.out.println("Calculated hash 0X" + hm); System.out.println(" Expected hash " + expectedHash); // Test #3 System.out.println(); System.out.println("Test #3:"); byte key3[] = { (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa }; byte text3[] = { (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd, (byte)0xdd }; expectedHash = "0X56BE34521D144C88DBB8C733F0E8B3F6"; byte eh[] = { (byte)0x56, (byte)0xBE, (byte)0x34, (byte)0x52, (byte)0x1D, (byte)0x14, (byte)0x4C, (byte)0x88, (byte)0xDB, (byte)0xB8, (byte)0xC7, (byte)0x33, (byte)0xF0, (byte)0xE8, (byte)0xB3, (byte)0xF6 }; hm = new HMAC_MD5(key3); hm.addData(text3); digest = hm.sign(); System.out.println("Calculated hash 0X" + hm); System.out.println(" Expected hash " + expectedHash); System.out.println("Signature Verification: " + hm.verify(eh)); } /** * Digest to be returned upon completion of the HMAC_MD5. */ private byte digest[]; /** * Inner Padding. */ private byte kIpad[]; /** * Outer Padding. */ private byte kOpad[]; /** * Inner MD5 object. */ private MD5 innerMD5; /** * Constructor */ HMAC_MD5(byte key[]) { int kLen = key.length; // if key is longer than 64 bytes reset it to key=MD5(key) if (kLen > 64) { MD5 md5 = new MD5(); md5.update(key); key = md5.digest(); } kIpad = new byte[64]; // inner padding - key XORd with ipad kOpad = new byte[64]; // outer padding - key XORd with opad // start out by storing key in pads System.arraycopy(key, 0, kIpad, 0, kLen); System.arraycopy(key, 0, kOpad, 0, kLen); // XOR key with ipad and opad values for (int i = 0; i < 64; i++) { kIpad[i] ^= 0x36; kOpad[i] ^= 0x5c; } clear(); // Initialize the first digest. } /** * Clear the HMAC_MD5 object. */ public void clear() { innerMD5 = new MD5(); innerMD5.update(kIpad); // Intialize the inner pad. digest = null; // mark the digest as incomplete. } /** * HMAC_MD5 function. * * @param text Text to process * * @param key Key to use for HMAC hash. * * @return hash */ public void addData(byte text[]) { addData(text, 0, text.length); } /** * HMAC_MD5 function. * * @param text Text to process * * @param textStart Start position of text in text buffer. * @param textLen Length of text to use from text buffer. * @param key Key to use for HMAC hash. * * @return hash */ public void addData(byte text[], int textStart, int textLen) { innerMD5.update(text, textStart, textLen); // then text of datagram. } public byte [] sign() { MD5 md5; /* * the HMAC_MD5 transform looks like: * * MD5(K XOR opad, MD5(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ // Perform inner MD5 digest = innerMD5.digest(); // finish up 1st pass. // Perform outer MD5 md5 = new MD5(); // Init md5 for 2nd pass. md5.update(kOpad); // Use outer pad. md5.update(digest); // Use results of first pass. digest = md5.digest(); // Final result. return digest; } /** * Validate a signature against the current digest. * Compares the hash against the signature. * * @param signature * * @return True if the signature matches the calculated hash. */ public boolean verify(byte signature[]) { // The digest may not have been calculated. If it's null, force a calculation. if (digest == null) sign(); int sigLen = signature.length; int digLen = digest.length; if (sigLen != digLen) return false; // Different lengths, not a good sign. for (int i = 0; i < sigLen; i++) if (signature[i] != digest[i]) return false; // Mismatch. Misfortune. return true; // Signatures matched. Perseverance furthers. } /** * Return the digest as a HEX string. * * @return a hex representation of the MD5 digest. */ public String toString() { // If not already calculated, do so. if (digest == null) sign(); StringBuffer r = new StringBuffer(); final String hex = "0123456789ABCDEF"; byte b[] = digest; for (int i = 0; i < 16; i++) { int c = ((b[i]) >>> 4) & 0xf; r.append(hex.charAt(c)); c = ((int)b[i] & 0xf); r.append(hex.charAt(c)); } return r.toString(); } } /* END SOURCE CODE */ The class listing above goes beyond your initial request in that it is able to generate an encrypted key as well as convert it back to the fields initially input into the function. I believe you will require this as well in order to decrypt your data at a later point. The main() program gives you an idea of how to use the enclosed methods to encrypt/decrypt your information. Hope that serves your purpose....if you require any clarification, please do not hesitate to ask :) ------------------------------------ Search Terms (Google): "HMAC-MD5" hash function algorithm ------------------------------------ Cheers! answerguru-ga

three57-ga at Google Answers Visit the source

Was this solution helpful to you?

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.