Search code examples
pythonpython-3.xsha256hmacgogs

Secret from Gogs hook (failing to get on python3)


I'm configuring a gogs hook, I have an API that receives this POST from push e.g.

secret: myS3cr3t

it's supposed that " Secret will be sent as SHA256 HMAC hex digest of payload via X-Gogs-Signature header."

then in python3 I got it like this:

message is the payload (json body) from the request and the key i set it on env var

import hashlib
import hmac

def get_secret_signature(message, secret):
   signature = hmac.new(bytes(key, 'utf-8'), bytes(message, 'utf-8'), hashlib.sha256).hexdigest()
   return signature 

but when checking the hook is failing cause the signature sent in X-Gogs-Signature never match with the signature generated on python

even comparing the logic with jenkins gogs plugin:

public static String encode(String data, String key) throws Exception {
        final Charset asciiCs = Charset.forName("UTF-8");
        final Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        final SecretKeySpec secret_key = new javax.crypto.spec.SecretKeySpec(asciiCs.encode(key).array(), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        return Hex.encodeHexString(sha256_HMAC.doFinal(data.getBytes("UTF-8")));
}

I think it's the same logic in python, obviously shorter in python ;)


Solution

  • It seems that the variable that had the payload was not escaping some characters, since I'm using the python framework Bottle this is the right way to get the payload:

    payload = request._get_body_string()
    gogs_signature = request.get_header('X-Gogs-Signature')
    
    signature = get_secret_signature(payload, secret)
    .
    .
    .
    if gogs_signature != signature:
       print("Signature error")
    
    def get_secret_signature(message, secret):
       signature = hmac.new(bytes(key, 'utf-8'), message, hashlib.sha256).hexdigest()
       return signature