Signer
Ce contenu n’est pas encore disponible dans votre langue.
Status: Draft
Introduction
The signer is a component of the EVC software suite that enables the signing and generation of the EVC in a portable format.
This software is developed using the Ruby language and the following libraries:
- base45
- openssl
- cbor
- falcon
- rqrcode
- jwt
- rack
Each of these libraries is used to perform specific tasks, such as encoding and decoding data, signing data, and generating QR codes.
The signer exposes an API that allows for signing the EVC and generating QR codes. It is designed as a toolbox accessible through a JSON-RPC server that provides access to several procedures:
- sign
- generate QR code (SVG, PNG)
- zip data
- encode data in base45
- verify the signature
- etc.
These procedures allow anyone to use the signer to sign and generate a portable version of the EVC in any language with a default implementation. This approach allows you to use the default implementation or to customize certain parts. For example, you can use the signer to sign the EVC, return it as a base45 string, and generate the QR code on your side.
APIs
The signer exposes two APIs:
- A JSON-RPC API
- A standard API to retrieve the public key
JSON-RPC API
All procedures are exposed through the same endpoint: POST
on /jsonrpc
. The body of the request must be a JSON-RPC request.
Here is a list of the available procedures:
to_base_45
: Encode data in base45to_cwt
: Generate an HCERT CWTto_jwt
: Generate an HCERT JWTto_zip
: Zip datato_hcert
: Generate an HCERT (compressed CWT in base45)to_hcert_qr_code
: Compressed CWT in base45 as a QR codeto_jwt_qr_code
: Compressed JWT in base45 as a QR codepipeline
: A procedure that allows chaining several proceduresfrom_hcert
: Decode an HCERT and verify the signature
Public Key API
The public key is exposed at the /.well-known/jwks.json
endpoint.
It uses the JWKS format to expose the public key.
Running the Signer
The simplest way to run the signer is to use the Docker image.
docker build -t signer . docker run -p 3000:3000 signer
By default, the signer will listen on port 3000.
It boots using the config.ru
file and uses an example key pair to sign the EVC.
Generating your own Docker image
In order to deploy the signer in your own environment, you have to build your own Docker image from this one.
The signer uses a basic interface for key pair storage that allows you to implement your own key store.
The config.ru
file must be overwritten with a version containing your own key pair.
config.ru
to adapt:
# frozen_string_literal: true
require 'jwt'require 'rack/cors'require 'rack/deflater'
require_relative './initializers'
nuva = ''Initializers.init_all(nuva:) => { app:, jwks_server:, pub_key_store:, priv_key_store: }
use Rack::CommonLoggeruse Rack::Deflater
use Rack::Cors do allow do origins '*' resource '*', headers: :any, methods: %i[get post] endend
full_app = Rack::Builder.app do map '/jsonrpc' do run app end map '/.well-known/jwks.json' do run jwks_server end map '/healthz' do run ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['OK']] } end end
# A.2.3. Elliptic Curve Digital Signature Algorithm (ECDSA) P-256 256-Bit# https://datatracker.ietf.org/doc/html/rfc8392#appendix-A.2.3pub_key_store.add( JWT::JWK.new( { kty: 'EC', crv: 'P-256', x: 'FDMpzOeGjkFpJ1mc9lo0884v/aVafspp7YkZo5TULw8', y: 'YPfxp4DYp4O/t6LdayeW6BKNu87509Fo25Uplxo257k', kid: 'AsymmetricECDSA256' } ))
priv_key_store.add( JWT::JWK.new( { kty: 'EC', crv: 'P-256', alg: 'ES256', # required for JWT.encode x: 'FDMpzOeGjkFpJ1mc9lo0884v/aVafspp7YkZo5TULw8', y: 'YPfxp4DYp4O/t6LdayeW6BKNu87509Fo25Uplxo257k', d: 'bBOCdlrsU1jxF3M9KBwce9w5iE0EpFoebGfIWLwgbBk', kid: 'AsymmetricECDSA256' } ))
# RubyVM::YJIT.enable
run full_app
Dockerfile
used to build the Docker image:
FROM syadem/signer
WORKDIR /app
COPY config.ru config.ru
Then you can push the generated Docker image to the registry of your choice and deploy it within your infrastructure.
Usage Examples
All examples are based on the JSON-RPC API. To reproduce these examples, you’ll need the curl
and jq
command-line tools.
Sign and Generate a QR Code (PNG)
In this example, we call the to_hcert_qr_code
procedure.
First, create a file named to_hcert_qr_code_png.json
with the following content:
{ "jsonrpc": "2.0", "id": "1234", "method": "to_hcert_qr_code", "params": { "file_format": "png", "hcert_data": { "ver": "1.0.0", "nam": { "fnt": "Jean", "gnt": "Michel" }, "dob": "1978-01-01", "v": [] } }}
Then, run the following command:
curl -X POST localhost:3000/jsonrpc -d @./to_hcert_qr_code_png.json | jq -r .result | base64 -D > test.png
You should now have a test.png
file in your current directory.
Some explanations:
- All procedures are called with a POST request to the
/jsonrpc
endpoint. - The procedure name is specified in the
method
field of the request body. - The parameters are provided in the
params
field of the request body. - The result is in the
result
field of the response (jq -r .result
). - All binary results are base64 encoded, so we use
base64 -D
to decode them.