by Bozho | Dec 17, 2017 | Aggregated, bouncycastle, Developer tips, security, timestamping
Trusted timestamping is the process of having a trusted third party (“Time stamping authority”, TSA) certify the time of a given event in electronic form. The EU regulation eIDAS gives these timestamps legal strength – i.e. nobody can dispute the time or the content of the event if it was timestamped. It is applicable to multiple scenarios, including timestamping audit logs. (Note: timestamping is not sufficient for a good audit trail as it does not prevent a malicious actor from deleting the event altogether) There are a number of standards for trusted timestamping, the core one being RFC 3161. As most RFCs it is hard to read. Fortunately for Java users, BouncyCastle implements the standard. Unfortunately, as with most security APIs, working with it is hard, even abysmal. I had to implement it, so I’ll share the code needed to timestamp data. The whole gist can be found here, but I’ll try to explain the main flow. Obviously, there is a lot of code that’s there to simply follow the standard. The BouncyCastle classes are a maze that’s hard to navigate. The main method is obviously timestamp(hash, tsaURL, username, password): public TimestampResponseDto timestamp(byte[] hash, String tsaUrl, String tsaUsername, String tsaPassword) throws IOException { MessageImprint imprint = new MessageImprint(sha512oid, hash); TimeStampReq request = new TimeStampReq(imprint, null, new ASN1Integer(random.nextLong()), ASN1Boolean.TRUE, null); byte[] body = request.getEncoded(); try { byte[] responseBytes = getTSAResponse(body, tsaUrl, tsaUsername, tsaPassword); ASN1StreamParser asn1Sp = new ASN1StreamParser(responseBytes); TimeStampResp tspResp = TimeStampResp.getInstance(asn1Sp.readObject()); TimeStampResponse tsr = new TimeStampResponse(tspResp); checkForErrors(tsaUrl, tsr); // validate communication level attributes (RFC 3161 PKIStatus) tsr.validate(new TimeStampRequest(request)); TimeStampToken token = tsr.getTimeStampToken(); TimestampResponseDto response = new TimestampResponseDto(); response.setTime(getSigningTime(token.getSignedAttributes())); response.setEncodedToken(Base64.getEncoder().encodeToString(token.getEncoded()));...
Recent Comments