├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | e.g. for webhook hashes 2 | 3 | --- 4 | 5 | Example inputs: 6 | 7 | | Variable | Value | 8 | | --- | --- | 9 | | key | `the shared secret key here` | 10 | | message | `the message to hash here ` | 11 | 12 | Reference outputs for example inputs above: 13 | 14 | | Type | Hash | 15 | | --- | --- | 16 | | as hexit | `4643978965ffcec6e6d73b36a39ae43ceb15f7ef8131b8307862ebc560e7f988` | 17 | | as base64 | `RkOXiWX/zsbm1zs2o5rkPOsV9++BMbgweGLrxWDn+Yg=` | 18 | 19 | --- 20 | 21 | ## PHP 22 | 23 | ```php 24 | [[1]](https://caniuse.com/#feat=cryptography)_ 56 | 57 | ```js 58 | const key = 'the shared secret key here'; 59 | const message = 'the message to hash here'; 60 | 61 | const getUtf8Bytes = str => 62 | new Uint8Array( 63 | [...unescape(encodeURIComponent(str))].map(c => c.charCodeAt(0)) 64 | ); 65 | 66 | const keyBytes = getUtf8Bytes(key); 67 | const messageBytes = getUtf8Bytes(message); 68 | 69 | const cryptoKey = await crypto.subtle.importKey( 70 | 'raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, 71 | true, ['sign'] 72 | ); 73 | const sig = await crypto.subtle.sign('HMAC', cryptoKey, messageBytes); 74 | 75 | // to lowercase hexits 76 | [...new Uint8Array(sig)].map(b => b.toString(16).padStart(2, '0')).join(''); 77 | 78 | // to base64 79 | btoa(String.fromCharCode(...new Uint8Array(sig))); 80 | ``` 81 | 82 | ## Ruby 83 | 84 | ```rb 85 | require 'openssl' 86 | require 'base64' 87 | 88 | key = 'the shared secret key here' 89 | message = 'the message to hash here' 90 | 91 | # to lowercase hexits 92 | OpenSSL::HMAC.hexdigest('sha256', key, message) 93 | 94 | # to base64 95 | Base64.encode64(OpenSSL::HMAC.digest('sha256', key, message)) 96 | ``` 97 | 98 | ## Elixir 99 | 100 | ```elixir 101 | key = 'the shared secret key here' 102 | message = 'the message to hash here' 103 | 104 | signature = :crypto.mac(:hmac, :sha256, key, message) 105 | 106 | # to lowercase hexits 107 | Base.encode16(signature, case: :lower) 108 | 109 | # to base64 110 | Base.encode64(signature) 111 | ``` 112 | 113 | ## Go 114 | 115 | ```go 116 | package main 117 | 118 | import ( 119 | "crypto/hmac" 120 | "crypto/sha256" 121 | "encoding/base64" 122 | "encoding/hex" 123 | ) 124 | 125 | func main() { 126 | secret := []byte("the shared secret key here") 127 | message := []byte("the message to hash here") 128 | 129 | hash := hmac.New(sha256.New, secret) 130 | hash.Write(message) 131 | 132 | // to lowercase hexits 133 | hex.EncodeToString(hash.Sum(nil)) 134 | 135 | // to base64 136 | base64.StdEncoding.EncodeToString(hash.Sum(nil)) 137 | } 138 | ``` 139 | 140 | ## Python 2 141 | 142 | ```py 143 | import hashlib 144 | import hmac 145 | import base64 146 | 147 | message = bytes('the message to hash here').encode('utf-8') 148 | secret = bytes('the shared secret key here').encode('utf-8') 149 | 150 | hash = hmac.new(secret, message, hashlib.sha256) 151 | 152 | # to lowercase hexits 153 | hash.hexdigest() 154 | 155 | # to base64 156 | base64.b64encode(hash.digest()) 157 | ``` 158 | 159 | ## Python 3 160 | 161 | ```py 162 | import hashlib 163 | import hmac 164 | import base64 165 | 166 | message = bytes('the message to hash here', 'utf-8') 167 | secret = bytes('the shared secret key here', 'utf-8') 168 | 169 | hash = hmac.new(secret, message, hashlib.sha256) 170 | 171 | # to lowercase hexits 172 | hash.hexdigest() 173 | 174 | # to base64 175 | base64.b64encode(hash.digest()) 176 | ``` 177 | 178 | ## C# 179 | 180 | ```cs 181 | using System; 182 | using System.Security.Cryptography; 183 | using System.Text; 184 | 185 | class MainClass { 186 | public static void Main (string[] args) { 187 | string key = "the shared secret key here"; 188 | string message = "the message to hash here"; 189 | 190 | byte[] keyByte = new ASCIIEncoding().GetBytes(key); 191 | byte[] messageBytes = new ASCIIEncoding().GetBytes(message); 192 | 193 | byte[] hashmessage = new HMACSHA256(keyByte).ComputeHash(messageBytes); 194 | 195 | // to lowercase hexits 196 | String.Concat(Array.ConvertAll(hashmessage, x => x.ToString("x2"))); 197 | 198 | // to base64 199 | Convert.ToBase64String(hashmessage); 200 | } 201 | } 202 | ``` 203 | 204 | ## Java 205 | 206 | ```java 207 | import javax.crypto.Mac; 208 | import javax.crypto.spec.SecretKeySpec; 209 | import java.security.NoSuchAlgorithmException; 210 | import java.security.InvalidKeyException; 211 | import javax.xml.bind.DatatypeConverter; 212 | 213 | class Main { 214 | public static void main(String[] args) { 215 | try { 216 | String key = "the shared secret key here"; 217 | String message = "the message to hash here"; 218 | 219 | Mac hasher = Mac.getInstance("HmacSHA256"); 220 | hasher.init(new SecretKeySpec(key.getBytes(), "HmacSHA256")); 221 | 222 | byte[] hash = hasher.doFinal(message.getBytes()); 223 | 224 | // to lowercase hexits 225 | DatatypeConverter.printHexBinary(hash); 226 | 227 | // to base64 228 | DatatypeConverter.printBase64Binary(hash); 229 | } 230 | catch (NoSuchAlgorithmException e) {} 231 | catch (InvalidKeyException e) {} 232 | } 233 | } 234 | ``` 235 | 236 | ## Rust 237 | 238 | ```rust 239 | extern crate hmac; 240 | extern crate sha2; 241 | extern crate base64; 242 | extern crate hex; 243 | 244 | use sha2::Sha256; 245 | use hmac::{Hmac, Mac}; 246 | 247 | fn main() { 248 | type HmacSha256 = Hmac; 249 | 250 | let secret = "the shared secret key here"; 251 | let message = "the message to hash here"; 252 | 253 | let mut mac = HmacSha256::new_varkey(secret.as_bytes()).unwrap(); 254 | 255 | mac.input(message.as_bytes()); 256 | 257 | let hash_message = mac.result().code(); 258 | 259 | // to lowercase hexits 260 | hex::encode(&hash_message); 261 | 262 | // to base64 263 | base64::encode(&hash_message); 264 | } 265 | ``` 266 | 267 | --- 268 | 269 | * https://stackoverflow.com/questions/13109588/base64-encoding-in-java 270 | * http://www.jokecamp.com/blog/examples-of-creating-base64-hashes-using-hmac-sha256-in-different-languages/ 271 | --------------------------------------------------------------------------------