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() |