Skip to content

A library to parse and generate Visible Digital Seals (VDS)

License

Notifications You must be signed in to change notification settings

tsenger/vdstools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VdsTools - lib to decode/verify and encode/sign Visible Digital Seals

License Maven Central Version GitHub Actions Workflow Status

A library to decode/verify and encode/sign Visible Digital Seals (VDS) as specified in

It also supports encoding and decoding Seals defined in the new draft of ICAO Datastructure for Barcode. The IDB encoder/decoders are at early stadium of and still differs from the VDS parser/encoder but they are already useable. You will find them in the package de.tsenger.vdstools.idb.

VDS can be created with the help of this library or, if you want to try it out quickly, via the web Sealgen tool. There is also the Sealva Android app which scans, verifies and displays all VDS profiles defined in the above specifications.

Get it on Google Play

Parse and verify a VDS

Here is a quick overview how to use the VDS parser and verifier. When you have the decoded raw string or raw bytes from your favorite datamatrix decoder, just put them to the VDS Tools Dataparser like this:

import de.tsenger.vdstools.Verifier;
import de.tsenger.vdstools.vds.DigitalSeal;
import de.tsenger.vdstools.vds.Feature;

...
DigitalSeal digitalSeal = DigitalSeal.fromByteArray(rawBytes);
String vdsType = digitalSeal.getVdsType();

// getFeature() returns an Optional<Feature> which can be used as follows
String mrz = digitalSeal.getFeature("MRZ").get().valueStr();
String azr = digitalSeal.getFeature("AZR").get().valueStr();
if(digitalSeal.getFeature("FACE_IMAGE").isPresent() ){
    byte[] imgBytes = digitalSeal.getFeature("FACE_IMAGE").get().valueBytes();
}

// or get all available Features in one List<Feature>
List<Feature> featureList = digitalSeal.getFeatureList();
for (Feature feature: featureList) {
    System.out.println(feature.name() + ", " + feature.coding() + ", " + feature.valueStr());
}

// Get the VDS signer certificate reference
String signerCertRef = digitalSeal.getSignerCertRef();

// Provide for the matching X509 signer certificate
// and use this to verify the VDS signature   
Verifier verifier = new Verifier(digitalSeal, x509SignerCert);
Verifier.Result result = verifier.verify();

Also have a look at DigitalSealTest.java and VerifierTest.java for some more examples.

Build a new VDS

Since version 0.3.0 you can also generate VDS with this library. Here is an example on how to use the DateEncoder and Signer classes:

KeyStore keystore = ...
...

// Here we use a keystore to get the certificate (for the header information)
// and the private key for signing the seals data
X509Certificate cert = (X509Certificate) keystore.getCertificate(keyAlias);
ECPrivateKey ecKey = (ECPrivateKey) keystore.getKey(certAlias, keyStorePassword.toCharArray());

// initialize the Signer
Signer signer = new Signer(ecKey); 
	
// 1. Build a VdsHeader
VdsHeader header = new VdsHeader.Builder("ARRIVAL_ATTESTATION")
		.setIssuingCountry("D<<")
		.setSignerIdentifier("DETS")
		.setCertificateReference("32")
		.setIssuingDate(LocalDate.parse("2024-09-27"))
		.setSigDate(LocalDate.parse("2024-09-27"))
		.build();

// 2. Build a VdsMessage
String mrz = "MED<<MANNSENS<<MANNY<<<<<<<<<<<<<<<<\n6525845096USA7008038M2201018<<<<<<06";
String azr = "ABC123456DEF";
VdsMessage vdsMessage = new VdsMessage.Builder(header.getVdsType())
		.addDocumentFeature("MRZ", mrz)
		.addDocumentFeature("AZR", azr)
		.build();

// 3. Build a signed DigitalSeal
DigitalSeal digitalSeal = new DigitalSeal(header, vdsMessage, signer);

// The encoded bytes can now be used to build a datamatrix (or other) code - which is not part of this library
byte[] encodedBytes = digitalSeal.getEncodedBytes();

There are many other ways to define the content of the VDS. In the example above, a lot of data such as the signature or issuing date is generated automatically. However, it is also possible to set your own values. There are various ways to encode a DigitalSeal by for this purpose. The VdsHeader and VdsMessage classes offer the option of setting the content in a finely granular manner.

Alternatively, it is also possible to generate many values automatically with as little input as possible or to use default values.

Also have a look at DataEncoderTest.java for some examples how to use the different options. In DataMatrixTest.java you will find an example on how to generated a datamatrix image file from the encoded bytes of the DataEncoder.

Documentation

javadoc

Online JavaDoc can be found here: https://javadoc.io/doc/de.tsenger/vdstools

How to include

The vdstools library is available on the Maven Central Repository and can be easly integrated in your projects.

Gradle

To include this library to your Gradle build add this dependency:

dependencies {
    implementation 'de.tsenger:vdstools:0.7.0'
}

Maven

To include this library to your Maven build add this dependency:

<dependency>
    <groupId>de.tsenger</groupId>
    <artifactId>vdstools</artifactId>
    <version>0.7.0</version>
</dependency>