Libove Blog

Personal Blog about anything - mostly programming, cooking and random thoughts

Sign message for ActivityPub mock:

Based on Mastodon Doc - Security

def sign(method, url, data):
    from urllib.parse import urlparse
    from cryptography.hazmat.primitives.serialization import load_pem_private_key
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import padding

    priv_key = load_pem_private_key(PRIV_KEY_PEM.encode(), None)
    body = json.dumps(data).encode()
    body_hash = hashlib.sha256(body).digest()
    digest = "SHA-256=" + base64.b64encode(body_hash).decode()
    date = datetime.now(tz=timezone.utc).strftime("%a, %d %b %Y %H:%M:%S GMT")
    host = "localhost:3000"
    target = urlparse(url).path
    to_sign = f"""(request-target): {method.lower()} {target}
host: {host}
date: {date}""".encode()
    sig = priv_key.sign(
        to_sign,
        padding.PKCS1v15(),
        hashes.SHA256(),
    )
    sig_str = base64.b64encode(sig).decode()

    request = requests.Request(method, url, data=body)
    request = request.prepare()
    request.headers["Content-Digest"] = digest
    request.headers["Host"] = host
    request.headers["Date"] = date
    request.headers["Signature"] = (
        f'keyId="http://mock_masto/users/h4kor#main-key",headers="(request-target) host date",signature="{sig_str}"'
    )
    return request