Generating the signature (Example)

This page describes by example how you validate the signature of incoming requests

Algorithm

To allow you to validate incoming events, we are signing every request with a signature as part of the header field X-Monta-Signature.

The value has the following format: sha1={signature}

The signature is generated using this algorithm: HMAC-SHA1 with your webhookSecret as key (Bytes) and the request body as input.

Example

Given you have set the following secret for your Webhook config: top-secret

And assuming we are sending this (simplified) payload (Post Body): {"foo": "bar"}

We would generate this signature: sha1=d7f7fb0093470143a57bc39a3d9f0bb61fa67131 and deliver it in the header (X-Monta-Signature).

Generating the signature (Kotlin)

val secret = "top-secret"  
val payload = "{\"foo\": \"bar\"}".toByteArray()  
val signature = SignRequest.generateSignature(secret, payload)  
val expectedSignature = "sha1=d7f7fb0093470143a57bc39a3d9f0bb61fa67131"  
expectThat(signature).describedAs("Signatures should match").isEqualTo(expectedSignature)

// Used Methods with outputs

SIGNATURE_ALGORITHM = "HmacSHA1"  
SIGNATURE_PREFIX = "sha-1"

// key = "top-secret", payload = [123, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 125]  
fun generateSignature(key: String, payload: ByteArray): String {  
    val signingKey = SecretKeySpec(key.toByteArray(), SIGNATURE_ALGORITHM) // key.toByteArray = [116, 111, 112, 45, 115, 101, 99, 114, 101, 116]  
    val hmac = Mac.getInstance(SIGNATURE_ALGORITHM)  
    hmac.init(signingKey)  
    // hmac.doFinal(payload) = [-41, -9, -5, 0, -109, 71, 1, 67, -91, 123, -61, -102, 61, -97, 11, -74, 31, -90, 113, 49]  
    // hmac.doFinal(payload).toHexString() = "d7f7fb0093470143a57bc39a3d9f0bb61fa67131"  
    return SIGNATURE_PREFIX + hmac.doFinal(payload).toHexString() // "sha1=d7f7fb0093470143a57bc39a3d9f0bb61fa67131"  
}

// converts ByteArray to Hex String  
private fun ByteArray.toHexString(): String {  
    val formatter = Formatter()  
    for (b in this) {  
        formatter.format("%02x", b)  
    }  
    return formatter.toString()  
}