Student card integration
Validation procedure for the QR Code of AppScho's student card
AppScho's student card can, in addition to its visual, display a QR code allowing to scan and validate the card presented by a user and the information it contains.
This QR Code is:
signed cryptographically
time-limited
The QR code must be regenerated regularly in order for it to keep being verified. If an invalid or expired QR is scanned, it will automatically be rejected.
The procedure below describes the algorithm to follow in order to verify the QR code when scanned.
Let's begin on the basis that the QR code has already been scanned and that you are in possession of its content in the format of a string of characters. Also, we will not give any code example, as it is the school's responsability to search for implementation methods for each concept mentioned in this documentation, according to the latter's languages and platforms.
For a subject as sensible as cryptography, we highly recommend to choose an established library, recognised and maintained.
QR code and JWT
Each QR code generated for AppScho's student card contains a JWT token containing all the information necessary to verify the displayed information.
This JWT is signed using the ES256 algorithm (ECDSA with P-256 and SHA-256). This asymetric encryption algorithm, based on elliptical curves, allows us to sign the value with a private key managed by AppScho, while allowing anyone to verify its validity with a public key made available.
The data contained in the JWT resembles the following (the first tab corresponding to the header, the second one to the payload):
Header
{
"alg": "ES256",
"kid": "Wpn+0mxthk+5ZLsyBGRhnw==",
"typ": "JWT"
}
Body
{
"bc": "0197456712",
"c": "demo",
"exp": 1602080318,
"jti": "33f04486-4190-4dfb-86ab-2d47bdf40584",
"n": "Amandine CLÉMENT",
"t": 0,
"u": "01974567A-12"
}
Key ID recovery
The JWT can theorically be signed using different keys throughout time. In order to determine which public key is used for validation, the goal is to decode the JWT header and recover the value of the "kid" attribute (key ID). In the example below, our key ID is Wpn+0mxthk+5ZLsyBGRhnw==.
It is possible to recover all valid public keys at a given time by making requests to the URLs below (according to the environment) :
Beta/Production : https://api.appscho.com/<id>/idcard/pubkeys
The ID to inform will be the one provided by AppScho. If the API returns an error, the scanner of the student card is probably not activated for your school. Please contact AppScho in order to solve this issue.
The API sends back data under this format :
{
"response": [
{
"kid": "Wpn+0mxthk+5ZLsyBGRhnw==",
"x5c": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER2MMLwxo0baYhy8E/gvA+Hz0gz/js54BQRa9e6TacFl
}
],
"state": "ok",
"timestamp": "2020-10-07 14:22:25 +0000"
}
You'll find, in the response attribute, the list of active public keys for your school. By comparing their "kid" with the ones from the scanned JWT, you'll be able to get the public key indicated in the "x5c" attribute.
The public key is given in a headerless PEM format. The goal it so rebuild the public ECDSA key thanks to its reprensetation in the PEM format.
Depending on the languages and libraries used, you might be forced to add adequate PEM headers and footers ( -----BEGIN PUBLIC KEY-----
and -----END PUBLIC KEY-----
).
JWT validation
The library used to validate the JWT should have to verify the cryptographic properties of the token, along with the expiration date (indicated in the "exp" attribute).
On your side, two values must be verified in order to guarantee the process fiability :
The header value "alg" must be equal to the "ES256" string of characters.
The attribute value "c" must be equal to the ID in the URL used to call the API used to recover the public key.
If all these elements are verified, you have validated that, for your school, the scanned QR code has effectively been generated by AppScho, and that it is still valid.
Read the attributes
The token beint signed, you can be certain that the data it contains has not been modified by the user. You can currently recover the following attributes (please note some attributes can be missing if not applicable or missing):
u : user's identifier
bc : user's barcode number
n : user's full name
t : type of user (0 for a student, 1 for a teacher, 2 for a staff member)