7.7. Verify the chain yourself
To verify the message yourself, you will need 3 set of files. First, you need the secure chain chunk containing the message, then you need the corresponding timestamp and finally the manual signature of the chunk. Contact support@babelway.com to receive theses files.
The following java code, using bouncycastle and CSVReader, can be used to validate the chain.
package com.babelway.tools; import java.io.IOException; import java.io.StringReader; import java.nio.file.Files; import java.nio.file.Paths; import java.security.Security; import java.util.Base64; import java.util.Collection; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSProcessableByteArray; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.CMSSignerDigestMismatchException; import org.bouncycastle.cms.CMSVerifierCertificateNotValidException; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jcajce.provider.digest.SHA3; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import au.com.bytecode.opencsv.CSVReader; public class SecureChainValidator { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); // # 1. Validate that the part of the secure chain (i.e. the chunk) that you want to verify is self-consistant // The CSV file that contains a part of the secure chain that you want to verify. byte[] chunk = Files.readAllBytes(Paths.get("/tmp/chunk.csv")); assertChunkFileIsSelfConsistent(chunk); System.out.println("The chunk is self consistant!"); // # 2. Validate the related timestamp // The timestamp byte[] timestamp = Files.readAllBytes(Paths.get("/tmp/timestamp.txt")); assertTimestampIsValid(timestamp); System.out.println("The timstamp is valid!"); // 2. Validate the related manual signature // The text file (in JSON format) that contains all the information about all the chunks that // were manually signed together, including the target chunk byte[] signatureContent = Files.readAllBytes(Paths.get("/tmp/signatureContent.txt")); // The signature itself byte[] signature = Files.readAllBytes(Paths.get("/tmp/signature.txt")); assertSignatureIsValid(signature, signatureContent); System.out.println("The signature is valid!"); System.out.println("Verification finished successfully"); } public static void assertChunkFileIsSelfConsistent(byte[] chunk) { try (CSVReader reader = new CSVReader(new StringReader(new String(chunk)), ';', '"', '\\')) { String[] row = reader.readNext(); if (row == null) { throw new IllegalArgumentException("Empty chunk file"); } //chaining = chainId;creationMoment;hubId;messageKey;step;hash;previousChainHash String chainHash = row[6]; StringBuilder sb; while ((row = reader.readNext()) != null) { sb = new StringBuilder(); for (int j = 0; j