This script demonstrates badge signing.
-
Create a environment to run the script:
$ python -m venv venv $ . ./venv/bin/activate
-
Install the required dependencies
$ pip install pycryptodome dag-cbor
-
Run the script:
$ python ./sign_badge.py
base64 encoded sec1 public key: BOt78Ld2Ig0GWGn/RAGCt6/kFw9ulw/bU3SNLcjCx/XXO8PAHrzvHypp0q33AUwFmHRDMszRRZ6be6/dNpvt6wk= | |
signed award: { | |
"$type": "blue.badge.award", | |
"did": "at://did:plc:ylqu73sqary2qtjv6srcuwco", | |
"badge": { | |
"uri": "at://did:plc:qzp5wrhiapix4p4ombfkjtmp/blue.badge.definition/first-post", | |
"cid": "123", | |
"name": "First Post" | |
}, | |
"issued": "2024-08-24T18:00:00.000Z", | |
"proof": { | |
"$type": "blue.badge.proof", | |
"k": "https://your.handle/.well-known/jwks.json#BOt78Ld2", | |
"s": "IcKsYhRE3f4D5b8VGQEu0nPc0sVLRoE8v_fMPGKBKwPbIsiAPM0FaZ0QyRVOr1ceJxFDOfg35IeO8xR7_mJE6w==" | |
} | |
} |
import sys | |
import dag_cbor | |
from Crypto.Hash import SHA256 | |
from Crypto.PublicKey import ECC | |
from Crypto.Signature import DSS | |
from base64 import urlsafe_b64encode, standard_b64encode, standard_b64decode | |
from json import dumps | |
# Generated with the following command: | |
# openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve | openssl pkcs8 -topk8 -nocrypt -outform der | base64 | |
private_key = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg88RMOjMoNhVpSVG1ber6OJAW3FWGo7vRMafhl2G+XSWhRANCAATre/C3diINBlhp/0QBgrev5BcPbpcP21N0jS3Iwsf11zvDwB687x8qadKt9wFMBZh0QzLM0UWem3uv3Tab7esJ" | |
def main() -> None: | |
badge = { | |
"$type": "blue.badge.award", | |
"did": "at://did:plc:ylqu73sqary2qtjv6srcuwco", | |
"badge": { | |
"uri": "at://did:plc:qzp5wrhiapix4p4ombfkjtmp/blue.badge.definition/first-post", | |
"cid": "123", | |
"name": "First Post", | |
}, | |
"issued": "2024-08-24T18:00:00.000Z", | |
} | |
bare_badge = dag_cbor.encode(badge) | |
key_data = standard_b64decode(private_key) | |
key = ECC.import_key(key_data) | |
public_key_export = standard_b64encode( | |
key.public_key().export_key(format="SEC1") | |
).decode("utf-8") | |
print(f"base64 encoded sec1 public key: {public_key_export}") | |
kid = public_key_export[:8] | |
bare_badge_sha256 = SHA256.new(bare_badge) | |
signer = DSS.new(key, "fips-186-3") | |
signature = signer.sign(bare_badge_sha256) | |
signature_base64 = urlsafe_b64encode(signature).decode("utf-8") | |
badge["proof"] = { | |
"$type": "blue.badge.proof", | |
"k": f"https://your.handle/.well-known/jwks.json#{kid}", | |
"s": signature_base64, | |
} | |
signed_badge = dumps(badge, indent=4) | |
print(f"signed award: {signed_badge}") | |
if __name__ == "__main__": | |
main() |