| Crates.io | obadgen |
| lib.rs | obadgen |
| version | 0.2.3 |
| created_at | 2025-07-14 06:28:02.024762+00 |
| updated_at | 2025-07-14 06:28:02.024762+00 |
| description | Generates (aka "bakes") basic Open Badge annotated images (lib & CLI-tool). |
| homepage | https://github.com/hoijui/obadgen |
| repository | https://github.com/hoijui/obadgen |
| max_upload_size | |
| id | 1751217 |
| size | 303,203 |
obadgen)obadgen is a CLI (Command-line Interface) tool,
which helps in generating "baking"
Open Badge 2.0 (latest release as of Nov. 2023)
annotated images.
To use this tool, you need some prerequisites:
openssl,
which allows you to generate and convert
cryptographic certificates and keys.In Open Badg 2.0, the assertion JSON-LD content can either be:
Also see Full Example further down.
res/ob-ents/badge-assertion-simple.json:
{
"@context": "https://w3id.org/openbadges/v2",
"type": "Assertion",
"id": "https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/badge-assertion-simple.json",
"badge": "https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/badge-definition-simple.json",
"recipient": {
"type": "email",
"identity": "sha256$488842626ec74a0468d90ea17dc4e11c2d0e8e54e45c5075fbd1d2e767f44249",
"hashed": true
},
"verification": {
"type": "HostedBadge"
},
"issuedOn": "2022-06-17T23:59:59Z",
"expires": "2099-06-30T23:59:59Z"
}
res/ob-ents/badge-assertion-with-key.json:
{
"@context": "https://w3id.org/openbadges/v2",
"type": "Assertion",
"id": "https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/badge-assertion-with-key.json",
"badge": "https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/badge-definition-with-key.json",
"recipient": {
"type": "email",
"identity": "sha256$a596420c9e6e6d4a7a552b2073a3b6c28807d808b37c97454ab4e419c9e5e4ad",
"hashed": true,
"salt": "dfvnk0923#%^&87t6iubasr"
},
"verification": {
"type": "SignedBadge",
"creator": "https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/issuer-with-key.json"
},
"issuedOn": "2022-06-17T23:59:59Z",
"expires": "2099-06-30T23:59:59Z"
}
Both the examples below create the file baked-badge.svg.
Example for a hosted badge:
obadgen \
--assertion assertion.json \
--source-image raw-badge.svg \
--baked baked-badge.svg
Example for a signed badge:
obadgen \
--assertion assertion.json \
--signing-algorithm es256 \
--key my_organization.x509_cert.priv_key.der \
--source-image raw-badge.svg \
--baked baked-badge.svg
Here we create a badge assertion, which we then sign and bake into an SVG. This SVG can thereafter be stored and verified anywhere.
PRIV_KEY="res/ob-ents/issuer-key.priv.der"
ALG="es256"
ISSUER_ID="https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/issuer-with-key.json"
BADGE_CLASS_ID="https://raw.githubusercontent.com/hoijui/obadgen/master/res/ob-ents/badge-definition-with-key.json"
ASSERTION_ID="https://some-domain.com/anywhere/does-not-even-have-to-exist/because-signed/badge-assertion-with-key.json"
EMAIL="recipient@email.com"
RECIPIENT_SALT="dfvnk097t6iubasr"
IDENTITY_HASH="sha256\$$(printf '%s%s' "$EMAIL" "$RECIPIENT_SALT" | sha256sum - | sed -e 's/ .*//')"
DATE_NOW="$(date --iso-8601=seconds)"
DATE_FUTURE="$(date --iso-8601=seconds --date="2099-12-30")"
ASSERTION_FILE_PATH="assertion.json"
IMG_EXT="svg"
#IMG_EXT="png"
SOURCE_IMAGE_BASE="res/media/img/test"
# Writing the badge asserion JSON-LD file
cat > "$ASSERTION_FILE_PATH" << EOF
{
"@context": "https://w3id.org/openbadges/v2",
"type": "Assertion",
"id": "$ASSERTION_ID",
"badge": "$BADGE_CLASS_ID",
"recipient": {
"type": "email",
"identity": "$IDENTITY_HASH",
"hashed": true,
"salt": "$RECIPIENT_SALT"
},
"verification": {
"type": "SignedBadge",
"creator": "$ISSUER_ID"
},
"issuedOn": "$DATE_NOW",
"expires": "$DATE_FUTURE"
}
EOF
# Signs and bakes the assertion to baked-badge.svg
obadgen \
--assertion "$ASSERTION_FILE_PATH" \
--signing-algorithm "$ALG" \
--key "$PRIV_KEY" \
--source-image "$SOURCE_IMAGE_BASE.$IMG_EXT" \
--baked "baked-badge.$IMG_EXT"
If you desicde to sign your badge (vs simply hosting it) as your verification method, you will need a private-key.
It could come from a simple public-private key-pair, or prefferably from an x.509 certificate, both of which can be generated with OpenSSL (shown below), if you do not yet have it.
The private-key you supply to this tool must be in DER format. If yours is in any other format (most likely PEM), you can convert it to DER suing OpenSSL (shown below).
Currently supported key-types are:
This list is what the library we use (biscuit)
supports for JSON Web Signature (JWS)),
which is what Open Badge signing requires.
In the following sub-sections, you find how to generate and convert certificates and keys.
For all these examples we use a common base (FILE_BASE)
for the certificates and keys file names,
extended with verbose suffixes.
We also provide the algorithm name (ALG)
as it has to be supplied to this tool later on.
NOTE: In cryptographic practice,
each private-key file also contains its corresponding public-key. \
So in any case, you will either have:
Both of the two exampels below, create these two files:
my_organization.x509_cert.priv_key.der (private file)my_organization.x509_cert.cert.pem (public file)Create a self-signed x.509 certificate in PEM format
using ES256 (ECDSA) key types,
with its private-key in DER format:
FILE_BASE="my_organization"
ALG="es256"
openssl req \
-new \
-x509 \
-subj "/C=DE/ST=Berlin/L=Berlin/O=OSEG/OU=SW-Dev/CN=ose-germany.de/emailAddress=open-badges-123@ose-germany.de" \
-sha256 \
-nodes \
-pkeyopt ec_paramgen_curve:prime256v1 \
-newkey ec \
-keyform DER \
-keyout "$FILE_BASE.x509_cert.priv_key.der" \
-days 730 \
-outform PEM \
-out "$FILE_BASE.x509_cert.cert.pem"
Create a self-signed x.509 certificate in PEM format
using RS256 (RSA) key types,
with its private-key in DER format:
FILE_BASE="my_organization"
ALG="rs256"
openssl req \
-new \
-x509 \
-subj "/C=DE/ST=Berlin/L=Berlin/O=OSEG/OU=SW-Dev/CN=ose-germany.de/emailAddress=open-badges-123@ose-germany.de" \
-sha256 \
-nodes \
-newkey rsa:4096 \
-keyform DER \
-keyout "$FILE_BASE.x509_cert.priv_key.der" \
-days 730 \
-outform PEM \
-out "$FILE_BASE.x509_cert.cert.pem"
Both of the two exampels below, create these two files:
my_organization.priv.der (private file)my_organization.pub.pem (public file)Create an ES256 (ECDSA) key pair,
with the private-key in DER format
and the public-key in PEM format:
FILE_BASE="my_organization"
ALG="es256"
openssl genpkey \
-algorithm RSA \
-pkeyopt rsa_keygen_bits:4096 \
-outform der \
-out "$FILE_BASE.priv.der"
Create an RS256 (RSA) key pair,
with the private-key in DER format
and the public-key in PEM format:
FILE_BASE="my_organization"
ALG="rs256"
# TODO FIXME This is still the certificate, not a key-pair only!
openssl req \
-x509 \
-sha256 \
-nodes \
-newkey rsa:4096 \
-keyform DER \
-keyout "$FILE_BASE.x509_cert.priv_key.der" \
-days 730 \
-outform PEM \
-out "$FILE_BASE.x509_cert.cert.pem"
Converts an RSA private-key in PEM format into the DER format:
FILE_BASE="my_organization"
openssl rsa \
-inform PEM \
-in "$FILE_BASE.pem" \
-outform DER \
-out "$FILE_BASE.der"
Converts an RSA public-key in DER format into the PEM format:
FILE_BASE="my_organization"
openssl rsa \
-RSAPublicKey_in \
-inform PEM \
-in "$FILE_BASE.pem" \
-outform DER \
-RSAPublicKey_out \
-out "$FILE_BASE.der"
Converts an ECDSA private-key in PEM format into the DER format:
FILE_BASE="my_organization"
openssl ec \
-inform PEM \
-in "$FILE_BASE.pem" \
-outform DER \
-out "$FILE_BASE.der"
Converts an ECDSA public-key in DER format into the PEM format:
FILE_BASE="my_organization"
openssl ec \
-pubin \
-inform PEM \
-in "$FILE_BASE.pem" \
-outform DER \
-pubout \
-out "$FILE_BASE.der"
Extracts the public key from an RSA private key-pair file (here one from an x.509 certificate, but can be any other) into a separate file, and reformats that files content to be pasted directly into an Open Badge 2.0 assertion.json file:
FILE_BASE="my_organization"
openssl rsa \
-in "$FILE_BASE.x509_cert.priv_key.der" \
-inform DER \
-RSAPublicKey_out \
-outform PEM \
-out "$FILE_BASE.x509_cert.pub_key.pem"
sed -e 's/\n/\\n/' "$FILE_BASE.x509_cert.pub_key.pem"
Visualizes certificate info for human eyes:
openssl x509 \
-in "$FILE_BASE.x509_cert.cert.pem" \
-inform PEM \
-text