Issue a QR code locally

This tutorial explains how to issue QR codes on your own computer with your keyfile using only the command line. However, if you are going to be issuing many QR codes, we encourage you to write a script in your language of choice to automate the process.

For Windows: This tutorial assumes you have installed Windows Subsystem for Linux (WSL) so that you can install and use qrencode.

You need some basic command line tools to generate QR codes on your own computer.

  • Mac: brew install gnupg python3 qrencode
  • Debian/Ubuntu/WSL: sudo apt-get install gnupg python3 qrencode

You'll be using gpg to create issuer signatures for your QR codes, so you need to import your keyfile into your local gpg keychain.
(You can skip this step if you've already imported your keyfile)

gpg --import /path/to/your/keyfile.asc

Should print something like:

gpg: key 836...: public key "" imported
gpg: key 836...: secret key imported
gpg: Total number processed: 2
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

Once you have imported your keypair, find the fingerprint for it by listing your secret keys.
(You can skip this step if you already know your fingerprint)

gpg --list-secret-keys

Will print something like:

/path/to/pubring.kbx
--------------------------------------
sec   ed25519 2021-04-12 [SC]
      68632A32FFDB8EB9ED589CDEF246AA78FD1EFDB1    <--- this is your fingerprint
uid           [ultimate] Test Issuer              <--- make sure this matches your issuer name

You're now ready to create the various parts of the QR code and build the full QR code raw string (which is just a url to the scan page).

# create the url prefix (replace INTERNAL_ONLY with your issuer ID if you have already registered)
echo -n "https://vax.codes/scan#v1/INTERNAL_ONLY/" > v1_prefix.txt

# create the QR code contents (replace CONTENTS_HERE with whatever you want to display when the QR code is scanned)
echo -n "CONTENTS_HERE" > v1_contents.txt

# percent-encode the contents for the url
cat v1_contents.txt | python3 -c "import urllib.parse, sys; print(urllib.parse.quote(sys.stdin.read()), end='')" > v1_contents_percent.txt

# sign the contents with your issuer keypair (replace FINGERPRINT_HERE with your fingerprint from Step 3)
cat v1_contents.txt | gpg --detach-sig --sign --user FINGERPRINT_HERE --output - > v1_signature.sig

# base64 encode the signature
cat v1_signature.sig | python3 -c "import base64, sys; print(base64.urlsafe_b64encode(sys.stdin.buffer.read()).decode().replace('=', ''), end='') > v1_signature.txt

# merge everything into the final qr code raw url
python3 -c "print('{}{}/{}'.format(open('v1_prefix.txt').read(), open('v1_signature.txt').read(), open('v1_contents_percent.txt').read()), end='')" > v1_qr_code.txt

# view the url to make sure it looks good
cat v1_qr_code.txt

Now that you have qr code raw string (v1_qr_code.txt), you can convert that into QR code png image.

cat v1_qr_code.txt | qrencode -o - > v1_qr_code.png

Congratulations! You can created v1_qr_code.png. Open the image in any image editor (or your browser) and try scanning it.


Want to use our online interface for issuing QR codes instead of the command line? Click here

Have questions? Email support@vax.codes for assistance.