Signing a request is one of the simplest ways to keep your APIs secure. In this short guide, I’ll show you how easy it is to set this up using HMAC and SHA256, in both Java and Python.
The key ideas
Before we jump into code, here are the pieces you’ll be working with:
Secret Key — a secret value shared between the server and the client.
It can be anything you like, but it has to be the exact same value on both sides when you sign.
Content/Message — the value you want to sign.
Signing/Hashing — the step on the client side where you turn your content into hashed data. Both the Secret Key and the Content go into this.
Verification — the step on the server side, which does almost the same thing as the client. The server calculates the hash using the same Secret Key and compares it with the one the client sent.
Doing it in Java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public static String hmacSha256(String key, String message) throws Exception {
Mac sha256Hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
sha256Hmac.init(secretKey);
byte[] hmacData = sha256Hmac.doFinal(message.getBytes("UTF-8"));
return bytesToHex(hmacData);
}
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
public static void main(String[] args) throws Exception {
String secretKey = "YOUR_SECRET_KEY";
String content = "YOUR_CONTENT";
String hashed = hmacSha256(secretKey, content);
}
Doing it in Python
Python makes this even shorter:
import hmac
import hashlib
def hmac_sha256(key, message):
return hmac.new(
key.encode("utf-8"),
message.encode("utf-8"),
hashlib.sha256
).hexdigest()
def main():
secret_key = "YOUR_SECRET_KEY"
content = "YOUR_CONTENT"
hashed = hmac_sha256(secret_key, content)
A real example — a secured API
Here’s how the whole thing plays out between a client and a server:
-
Client — calculates a hashed value from the HTTP request body and the Secret Key.
-
Client — attaches that hashed value to an HTTP request header. For example
Authorization: {{hashed}} -
Client — sends the API request.
-
Server — receives the request.
-
Server — reads the HTTP request body and calculates the hashed value using the same Secret Key.
-
Server — compares the received hash with the one it just computed. If they match, verification passes and the API continues with its business logic. If not, it rejects the request, for example with an HTTP 401 Unauthorized.
That’s it.
Happy coding !