- Saved searches
- Use saved searches to filter your results more quickly
- Blah2014/Examples-of-creating-base64-hashes-using-HMAC-SHA256-in-different-languages
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- lesstif / HMacTest.java
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Blah2014/Examples-of-creating-base64-hashes-using-HMAC-SHA256-in-different-languages
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Examples of creating base64 hashes using HMAC-SHA256 in different languages
I recently went through the processing of creating SDKs for an in house API. The API required signing every REST request with HMAC SHA256 signatures. Those signatures then needed to be converted to base64. Amazon S3 uses base64 strings for their hashes. There are some good reasons to use base64 encoding. See the stackOverflow question What is the use of base 64 encoding?
Below are some simplified HMAC SHA 256 solutions. They should all output qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc= given the values of secret and Message . Take notice of the capital M. The hashed message is case sensitive.
Jump to an implementation:
Run the code online with this jsfiddle. Dependent upon an open source js library called http://code.google.com/p/crypto-js/.
script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/rollups/hmac-sha256.js">/script> script src="http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/enc-base64-min.js">/script> script> var hash = CryptoJS.HmacSHA256("Message", "secret"); var hashInBase64 = CryptoJS.enc.Base64.stringify(hash); document.write(hashInBase64); /script>
PHP has built in methods for hash_hmac (PHP 5) and base64_encode (PHP 4, PHP 5) resulting in no outside dependencies. Say what you want about PHP but they have the cleanest code for this example.
$s = hash_hmac('sha256', 'Message', 'secret', true); echo base64_encode($s);
Dependent on Apache Commons Codec to encode in base64.
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class ApiSecurityExample < public static void main(String[] args) < try < String secret = "secret"; String message = "Message"; Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); String hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes())); System.out.println(hash); > catch (Exception e)< System.out.println("Error"); > > >
It is mostly java code but there are some slight differences. Adapted from Dev Takeout — Groovy HMAC/SHA256 representation.
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; def hmac_sha256(String secretKey, String data) < try < Mac mac = Mac.getInstance("HmacSHA256") SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256") mac.init(secretKeySpec) byte[] digest = mac.doFinal(data.getBytes()) return digest > catch (InvalidKeyException e) < throw new RuntimeException("Invalid key exception while converting to HMac SHA256") > > def hash = hmac_sha256("secret", "Message") encodedData = hash.encodeBase64().toString() log.info(encodedData)
using System.Security.Cryptography; namespace Test public class MyHmac private string CreateToken(string message, string secret) secret = secret ?? ""; var encoding = new System.Text.ASCIIEncoding(); byte[] keyByte = encoding.GetBytes(secret); byte[] messageBytes = encoding.GetBytes(message); using (var hmacsha256 = new HMACSHA256(keyByte)) byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); return Convert.ToBase64String(hashmessage); > > > >
Objective C and Cocoa HMAC SHA256
Most of the code required was for converting to bae64 and working the NSString and NSData data types.
#import "AppDelegate.h" #import CommonCrypto/CommonHMAC.h> @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification < NSString* key = @"secret"; NSString* data = @"Message"; const char *cKey = Java hmac sha256 example; const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding]; unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC); NSData *hash = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)]; NSLog(@"%@", hash); NSString* s = [AppDelegate base64forData:hash]; NSLog(s); > + (NSString*)base64forData:(NSData*)theData < const uint8_t* input = (const uint8_t*)[theData bytes]; NSInteger length = [theData length]; static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; uint8_t* output = (uint8_t*)data.mutableBytes; NSInteger i; for (i=0; i < length; i += 3) < NSInteger value = 0; NSInteger j; for (j = i; j < (i + 3); j++) < value 8; if (j < length) < value |= (0xFF & input[j]); > > NSInteger theIndex = (i / 3) * 4; output[theIndex + 0] = table[(value >> 18) & 0x3F]; output[theIndex + 1] = table[(value >> 12) & 0x3F]; output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '='; output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '='; > return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; > @end
Go programming language — Golang HMAC SHA256
package main import ( "crypto/hmac" "crypto/sha256" "encoding/base64" "fmt" ) func ComputeHmac256(message string, secret string) string < key := []byte(secret) h := hmac.New(sha256.New, key) h.Write([]byte(message)) return base64.StdEncoding.EncodeToString(h.Sum(nil)) > func main() < fmt.Println(ComputeHmac256("Message", "secret")) >
require 'openssl' require "base64" hash = OpenSSL::HMAC.digest('sha256', "secret", "Message") puts Base64.encode64(hash)
import hashlib import hmac import base64 message = bytes("Message").encode('utf-8') secret = bytes("secret").encode('utf-8') signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest()) print(signature)
Tested with Python 2.7.6. Also, be sure not to name your python demo script the same as one of the imported libraries.
See Digest::SHA documentation. By convention, the Digest modules do not pad their Base64 output. To fix this you can test the length of the hash and append equal signs » highlight highlight-source-perl notranslate position-relative overflow-auto» dir=»auto» data-snippet-clipboard-copy-content=»use Digest::SHA qw(hmac_sha256_base64); $digest = hmac_sha256_base64(«Message», «secret»); # digest is currently: qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc # Fix padding of Base64 digests while (length($digest) % 4) < $digest .= '='; >print $digest; # digest is now: qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc pl-k»>use Digest::SHA qw( hmac_sha256_base64 ) ; $digest = hmac_sha256_base64( » Message » , » secret » ); # digest is currently: qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc # Fix padding of Base64 digests while ( length ( $digest ) % 4) < $digest .= ' = ' ; >print $digest ; # digest is now: qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc=
import 'dart:html'; import 'dart:convert'; import 'package:crypto/crypto.dart'; void main() < String secret = 'secret'; String message = 'Message'; Listint> secretBytes = UTF8.encode('secret'); Listint> messageBytes = UTF8.encode('Message'); var hmac = new HMAC(new SHA256(), secretBytes); hmac.add(messageBytes); var digest = hmac.close(); var hash = CryptoUtils.bytesToBase64(digest); // output to html page querySelector('#hash').text = hash; // hash => qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc= >
I have not verified but see this stackOverflow post
Take a look at the alco/rust-digest repository for Rust (lang) guidance. I have not verified yet.
Powershell (Windows) HMAC SHA256
Mostly wrapping of .NET libraries but useful to see it in powershell’s befuddling syntax. See code as gist
$message = 'Message' $secret = 'secret' $hmacsha = New-Object System.Security.Cryptography.HMACSHA256 $hmacsha.key = [Text.Encoding]::ASCII.GetBytes($secret) $signature = $hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($message)) $signature = [Convert]::ToBase64String($signature) echo $signature # Do we get the expected signature? echo ($signature -eq 'qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc=')
lesstif / HMacTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
import javax . crypto . Mac ; |
import javax . crypto . spec . SecretKeySpec ; |
public class HMacTest |
public static final String ALGORITHM = «HmacSHA256» ; |
public static String calculateHMac ( String key , String data ) throws Exception |
Mac sha256_HMAC = Mac . getInstance ( ALGORITHM ); |
SecretKeySpec secret_key = new SecretKeySpec ( key . getBytes ( «UTF-8» ), ALGORITHM ); |
sha256_HMAC . init ( secret_key ); |
return byteArrayToHex ( sha256_HMAC . doFinal ( data . getBytes ( «UTF-8» ))); |
> |
public static String byteArrayToHex ( byte [] a ) |
StringBuilder sb = new StringBuilder ( a . length * 2 ); |
for ( byte b : a ) |
sb . append ( String . format ( «%02x» , b )); |
return sb . toString (); |
> |
public static void main ( String [] args ) throws Exception |
// see https://en.wikipedia.org/wiki/HMAC#Examples |
// expected output: |
// HMAC_SHA256(«key», «The quick brown fox jumps over the lazy dog») = f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8 |
System . out . println ( calculateHMac ( «key» , «The quick brown fox jumps over the lazy dog» )); |
> |
> |