Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Benutzerdefinierte Implementierungen der CloudTrail Integritätsprüfung von Protokolldateien
Da branchenübliche, offen verfügbare kryptografische Algorithmen und Hashfunktionen CloudTrail verwendet werden, können Sie Ihre eigenen Tools erstellen, um die Integrität von CloudTrail Protokolldateien zu überprüfen. Wenn die Integritätsprüfung der Protokolldatei aktiviert ist, werden CloudTrail Digest-Dateien an Ihren Amazon S3 S3-Bucket gesendet. Sie können diese Dateien zum Implementieren einer eigenen Validierungslösung verwenden. Weitere Informationen über Digest-Dateien finden Sie unter CloudTrail Struktur der Digest-Datei.
In diesem Thema wird das Signieren von Digest-Dateien beschrieben. Zudem werden detailliert die Schritte dargelegt, die zur Implementierung einer Lösung für die Validierung von Digest-Dateien sowie den referenzierten Protokolldateien ausgeführt werden müssen.
Verstehen, wie CloudTrail Digest-Dateien signiert werden
CloudTrail Digest-Dateien werden mit RSA digitalen Signaturen signiert. CloudTrailFührt für jede Digest-Datei Folgendes aus:
-
Für die Datensignatur wird eine Zeichenfolge erstellt, die auf bestimmten Digest-Dateifeldern basiert (siehe nächster Abschnitt).
-
Ein privater Schlüssel, der für die Region eindeutig ist, wird abgerufen.
-
Übergibt den SHA -256-Hash der Zeichenfolge und den privaten Schlüssel an den RSA Signaturalgorithmus, der eine digitale Signatur erzeugt.
-
Der Byte-Signaturcode wird im Hexadezimalformat verschlüsselt.
-
Die digitale Signatur wird in der Metadateneigenschaft
x-amz-meta-signature
des Digest-Dateiobjekts von Amazon S3 bereitgestellt.
Inhalt der Datensignatur-Zeichenfolge
Die folgenden CloudTrail Objekte sind in der Zeichenfolge für die Datensignierung enthalten:
-
Der Endzeitstempel der Digest-Datei im UTC erweiterten Format (z. B.)
2015-05-08T07:19:37Z
-
S3-Pfad der aktuellen Digest-Datei
-
Der hexadezimalkodierte SHA -256-Hash der aktuellen Digest-Datei
-
Im Hexadezimalformat verschlüsselte Signatur der vorherigen Digest-Datei
Das Format für die Zeichenfolgenberechnung und eine Beispielzeichenfolge finden Sie weiter unten in diesem Dokument.
Schritte der benutzerdefinierten Validierungsimplementierung
Bei der Implementierung einer benutzerdefinierten Validierungslösung müssen Sie zunächst die Digest-Datei und anschließend die referenzierten Protokolldateien validieren.
Validieren der Digest-Datei
Zur Validierung einer Digest-Datei benötigen Sie die Signatur, den öffentlichen Schlüssel, dessen privater Schlüssel zum Signieren verwendet wurde, und eine berechnete Datensignatur-Zeichenfolge.
-
Rufen Sie die Digest-Datei ab.
-
Überprüfen Sie, ob die Digest-Datei vom ursprünglichen Speicherort abgerufen wurde.
-
Rufen Sie die im Hexadezimalformat verschlüsselte Signatur der Digest-Datei ab.
-
Rufen Sie den im Hexadezimalformat verschlüsselten Fingerabdruck des öffentlichen Schlüssels ab, dessen privater Schlüssel zum Signieren der Digest-Datei verwendet wurde.
-
Rufen Sie die öffentlichen Schlüssel für den entsprechenden Zeitraum der Digest-Datei ab.
-
Wählen Sie aus den abgerufenen öffentlichen Schlüsseln denjenigen aus, dessen Fingerabdruck mit dem in der Digest-Datei übereinstimmt.
-
Verwenden Sie den Digest-Dateihash und weitere Digest-Dateifelder, um die Datensignatur-Zeichenfolge, anhand der die Digest-Dateisignatur überprüft wird, neu zu erstellen.
-
Überprüfen Sie die Signatur, indem Sie den SHA -256-Hash der Zeichenfolge, den öffentlichen Schlüssel und die Signatur als Parameter an den Signaturüberprüfungsalgorithmus übergeben. RSA Wenn das Ergebnis „True“ lautet, ist die Digest-Datei gültig.
Validieren der Protokolldateien
Wenn die Digest-Datei gültig ist, validieren Sie alle von der Digest-Datei referenzierten Protokolldateien.
-
Um die Integrität einer Protokolldatei zu überprüfen, berechnen Sie ihren Hashwert SHA -256 für ihren unkomprimierten Inhalt und vergleichen Sie die Ergebnisse mit dem Hash für die Protokolldatei, der im Digest hexadezimal aufgezeichnet wurde. Stimmen die Hashwerte überein, ist die Protokolldatei gültig.
-
Validieren Sie nun anhand der Informationen über die vorherige Digest-Datei, die in der aktuellen Digest-Datei enthalten sind, die vorherige Digest-Datei und dann die entsprechenden Protokolldateien.
In den folgenden Abschnitten werden diese Schritte ausführlich beschrieben.
A. Abrufen der Digest-Datei
Die ersten Schritte bestehen darin, die neueste Digest-Datei herunterzuladen und sicherzustellen, dass diese vom ursprünglichen Speicherort stammt, die digitale Signatur zu überprüfen und den Fingerabdruck des öffentlichen Schlüssels abzurufen.
-
Rufen Sie mithilfe von S3
GetObject
oder der Klasse AmazonS3Client (z. B.) die neueste Digest-Datei aus Ihrem Amazon S3 S3-Bucket für den Zeitraum ab, den Sie validieren möchten. -
Stellen Sie sicher, dass der S3-Bucket und das S3-Objekt für den Dateiabruf mit den Speicherorten des S3-Buckets und des S3-Objekts übereinstimmen, die in der Digest-Datei erfasst wurden.
-
Rufen Sie anschließend die digitale Signatur der Digest-Datei aus der Metadateneigenschaft
x-amz-meta-signature
des Digest-Dateiobjekts in Amazon S3 ab. -
Rufen Sie in der Digest-Datei den Fingerabdruck des öffentlichen Schlüssels, dessen privater Schlüssel zum Signieren der Digest-Datei verwendet wurde, aus dem Feld
digestPublicKeyFingerprint
ab.
B. Abrufen des öffentlichen Schlüssels zur Validierung der Digest-Datei
Um den öffentlichen Schlüssel zur Validierung der Digest-Datei zu erhalten, können Sie entweder die oder die verwenden. AWS CLI CloudTrail API In beiden Fällen geben Sie einen Zeitraum (Start- und Endzeitpunkt) für die zu validierenden Digest-Dateien an. Für den angegebenen Zeitraum können ein oder mehrere öffentliche Schlüssel zurückgegeben werden. Möglicherweise überschneiden sich die Gültigkeitszeiträume der zurückgegebenen Schlüssel.
Anmerkung
Da pro Region unterschiedliche private/öffentliche Schlüsselpaare CloudTrail verwendet werden, ist jede Digest-Datei mit einem privaten Schlüssel signiert, der für ihre Region einzigartig ist. Wenn Sie also die Digest-Datei einer bestimmten Region validieren, müssen Sie den öffentlichen Schlüssel dieser Region abrufen.
Verwenden Sie die, um öffentliche Schlüssel abzurufen AWS CLI
Verwenden Sie den cloudtrail list-public-keys
Befehl, um öffentliche Schlüssel für Digest-Dateien mithilfe von abzurufen. AWS CLI Der Befehl hat das folgende Format:
aws cloudtrail list-public-keys [--start-time <start-time>] [--end-time <end-time>]
Die Parameter Startzeit und Endzeit sind UTC Zeitstempel und optional. Wenn diese Parameter nicht angegeben werden, wird die aktuelle Uhrzeit verwendet und der aktuell aktive öffentliche Schlüssel (oder mehrere) wird zurückgegeben.
Beispielantwort
Die Antwort wird eine Liste von JSON Objekten sein, die den zurückgegebenen Schlüssel (oder die Schlüssel) darstellen:
{ "publicKeyList": [ { "ValidityStartTime": "1436317441.0", "ValidityEndTime": "1438909441.0", "Value": "MIIBCgKCAQEAn11L2YZ9h7onug2ILi1MWyHiMRsTQjfWE+pHVRLk1QjfWhirG+lpOa8NrwQ/r7Ah5bNL6HepznOU9XTDSfmmnP97mqyc7z/upfZdS/AHhYcGaz7n6Wc/RRBU6VmiPCrAUojuSk6/GjvA8iOPFsYDuBtviXarvuLPlrT9kAd4Lb+rFfR5peEgBEkhlzc5HuWO7S0y+KunqxX6jQBnXGMtxmPBPP0FylgWGNdFtks/4YSKcgqwH0YDcawP9GGGDAeCIqPWIXDLG1jOjRRzWfCmD0iJUkz8vTsn4hq/5ZxRFE7UBAUiVcGbdnDdvVfhF9C3dQiDq3k7adQIziLT0cShgQIDAQAB", "Fingerprint": "8eba5db5bea9b640d1c96a77256fe7f2" }, { "ValidityStartTime": "1434589460.0", "ValidityEndTime": "1437181460.0", "Value": "MIIBCgKCAQEApfYL2FiZhpN74LNWVUzhR+VheYhwhYm8w0n5Gf6i95ylW5kBAWKVEmnAQG7BvS5g9SMqFDQx52fW7NWV44IvfJ2xGXT+wT+DgR6ZQ+6yxskQNqV5YcXj4Aa5Zz4jJfsYjDuO2MDTZNIzNvBNzaBJ+r2WIWAJ/Xq54kyF63B6WE38vKuDE7nSd1FqQuEoNBFLPInvgggYe2Ym1Refe2z71wNcJ2kY+q0h1BSHrSM8RWuJIw7MXwF9iQncg9jYzUlNJomozQzAG5wSRfbplcCYNY40xvGd/aAmO0m+Y+XFMrKwtLCwseHPvj843qVno6x4BJN9bpWnoPo9sdsbGoiK3QIDAQAB", "Fingerprint": "8933b39ddc64d26d8e14ffbf6566fee4" }, { "ValidityStartTime": "1434589370.0", "ValidityEndTime": "1437181370.0", "Value": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqlzPJbvZJ42UdcmLfPUqXYNfOs6I8lCfao/tOs8CmzPOEdtLWugB9xoIUz78qVHdKIqxbaG4jWHfJBiOSSFBM0lt8cdVo4TnRa7oG9io5pysS6DJhBBAeXsicufsiFJR+wrUNh8RSLxL4k6G1+BhLX20tJkZ/erT97tDGBujAelqseGg3vPZbTx9SMfOLN65PdLFudLP7Gat0Z9p5jw/rjpclKfo9Bfc3heeBxWGKwBBOKnFAaN9V57pOaosCvPKmHd9bg7jsQkI9Xp22IzGLsTFJZYVA3KiTAElDMu80iFXPHEq9hKNbt9e4URFam+1utKVEiLkR2disdCmPTK0VQIDAQAB", "Fingerprint": "31e8b5433410dfb61a9dc45cc65b22ff" } ] }
Verwenden der CloudTrail API für den Abruf der öffentlichen Schlüssel
Um öffentliche Schlüssel für Digest-Dateien mithilfe von abzurufen CloudTrail API, übergeben Sie die Werte für die Startzeit und die Endzeit an die ListPublicKeys
API. Das ListPublicKeys
API gibt die öffentlichen Schlüssel zurück, deren private Schlüssel zum Signieren von Digest-Dateien innerhalb des angegebenen Zeitraums verwendet wurden. Für jeden öffentlichen Schlüssel gibt der API auch den entsprechenden Fingerabdruck zurück.
ListPublicKeys
In diesem Abschnitt werden die Anforderungsparameter und Antwortelemente für die beschrieben ListPublicKeys
API.
Anmerkung
Hinsichtlich der Codierung der binären Felder von ListPublicKeys
sind Änderungen vorbehalten.
Anfrageparameter
Name | Beschreibung |
---|---|
StartTime
|
Gibt optional den Beginn des Zeitbereichs anUTC, in dem nach öffentlichen Schlüsseln für CloudTrail Digest-Dateien gesucht werden soll. Wenn StartTime nicht angegeben, wird die aktuelle Uhrzeit verwendet und der aktuelle öffentliche Schlüssel zurückgegeben. Typ: DateTime |
EndTime
|
Gibt optional das Ende des Zeitbereichs anUTC, in dem nach öffentlichen Schlüsseln für CloudTrail Digest-Dateien gesucht werden soll. Wenn nicht angegeben, EndTime wird die aktuelle Uhrzeit verwendet. Typ: DateTime |
Antwortelemente
PublicKeyList
ist ein Array aus PublicKey
-Objekten und enthält folgende Elemente:
Name | Beschreibung |
Value
|
Der DER codierte Wert des öffentlichen Schlüssels im Format PKCS #1. Typ: Blob |
ValidityStartTime
|
Dies gibt den Beginn des Gültigkeitszeitraums für den öffentlichen Schlüssel an. Typ: DateTime |
ValidityEndTime
|
Dies gibt das Ende des Gültigkeitszeitraums für den öffentlichen Schlüssel an. Typ: DateTime |
Fingerprint
|
Die Fingerabdruck des öffentlichen Schlüssels. Mit dem Fingerabdruck kann der öffentliche Schlüssel identifiziert werden, der zur Validierung der Digest-Datei verwendet werden muss. Typ: Zeichenfolge |
C. Auswählen des öffentlichen Schlüssels für die Validierung
Wählen Sie aus den von list-public-keys
oder ListPublicKeys
abgerufenen öffentlichen Schlüsseln denjenigen aus, dessen Fingerabdruck mit dem Fingerabdruck im Feld digestPublicKeyFingerprint
der Digest-Datei übereinstimmt. Diesen öffentlichen Schlüssel verwenden Sie für die Validierung der Digest-Datei.
D. Neues Erstellen der Datensignatur-Zeichenfolge
Nachdem Sie über die Signatur der Digest-Datei und den entsprechenden öffentlichen Schlüssel verfügen, berechnen Sie die Datensignatur-Zeichenfolge. Wenn Sie die Datensignatur-Zeichenfolge berechnet haben, stehen Ihnen alle für die Signaturvalidierung benötigten Daten zur Verfügung.
Die Datensignatur-Zeichenfolge hat folgendes Format:
Data_To_Sign_String = Digest_End_Timestamp_in_UTC_Extended_format + '\n' + Current_Digest_File_S3_Path + '\n' + Hex(Sha256(current-digest-file-content)) + '\n' + Previous_digest_signature_in_hex
Ein Data_To_Sign_String
-Beispiel folgt.
2015-08-12T04:01:31Z amzn-s3-demo-bucket/AWSLogs/111122223333/CloudTrail-Digest/us-east-2/2015/08/12/111122223333_us-east-2_CloudTrail-Digest_us-east-2_20150812T040131Z.json.gz 4ff08d7c6ecd6eb313257e839645d20363ee3784a2328a7d76b99b53cc9bcacd 6e8540b83c3ac86a0312d971a225361d28ed0af20d70c211a2d405e32abf529a8145c2966e3bb47362383a52441545ed091fb81 d4c7c09dd152b84e79099ce7a9ec35d2b264eb92eb6e090f1e5ec5d40ec8a0729c02ff57f9e30d5343a8591638f8b794972ce15bb3063a01972 98b0aee2c1c8af74ec620261529265e83a9834ebef6054979d3e9a6767dfa6fdb4ae153436c567d6ae208f988047ccfc8e5e41f7d0121e54ed66b1b904f80fb2ce304458a2a6b91685b699434b946c52589e9438f8ebe5a0d80522b2f043b3710b87d2cda43e5c1e0db921d8d540b9ad5f6d4$31b1f4a8ef2d758424329583897339493a082bb36e782143ee5464b4e3eb4ef6
Wenn Sie diese Zeichenfolge neu erstellt haben, können Sie die Digest-Datei validieren.
E. Validieren der Digest-Datei
Übergeben Sie den Hash SHA -256 der neu erstellten Datensignaturzeichenfolge, der digitalen Signatur und des öffentlichen Schlüssels an den RSA Signaturüberprüfungsalgorithmus. Wenn das Ergebnis „True“ lautet, wurde die Signatur der Digest-Datei überprüft und die Digest-Datei ist gültig.
F. Validieren der Protokolldateien
Nachdem Sie die Digest-Dateien validiert haben, können Sie die referenzierten Protokolldateien überprüfen. Die Digest-Datei enthält die SHA -256-Hashes der Protokolldateien. Wenn eine der Protokolldateien nach der CloudTrail Lieferung geändert wurde, ändern sich die SHA -256-Hashes und die Signatur der Digest-Datei stimmt nicht überein.
Das folgende Beispiel veranschaulicht die Validierung der Protokolldateien:
-
Führen Sie einen
S3 Get
-Vorgang für die Protokolldatei aus. Verwenden Sie dabei die S3-Speicherortinformationen aus den FeldernlogFiles.s3Bucket
undlogFiles.s3Object
. -
Wenn der
S3 Get
Vorgang erfolgreich ist, durchlaufen Sie die Protokolldateien, die im logFiles Array der Digest-Datei aufgeführt sind. Gehen Sie dabei wie folgt vor:-
Rufen Sie den ursprünglichen Hash der Datei aus dem Feld
logFiles.hashValue
des entsprechenden Protokolls in der Digest-Datei ab. -
Führen Sie für den unkomprimierten Inhalt der Protokolldatei einen Hash mit dem Hash-Algorithmus in
logFiles.hashAlgorithm
aus. -
Vergleichen Sie den generierten Hashwert mit dem Hashwert für das Protokoll in der Digest-Datei. Stimmen die Hashwerte überein, ist die Protokolldatei gültig.
-
G. Validieren weiterer Digest- und Protokolldateien
In jeder Digest-Datei enthalten die folgenden Felder den Speicherort und die Signatur der vorherigen Digest-Datei:
-
previousDigestS3Bucket
-
previousDigestS3Object
-
previousDigestSignature
Mithilfe der Schritte in den vorigen Abschnitten und mit diesen Informationen können Sie vorherige Digest-Dateien sequenziell aufrufen und die jeweilige Signatur sowie die referenzierten Protokolldateien validieren. Der einzige Unterschied besteht darin, dass Sie für vorherige Digest-Dateien nicht die digitale Signatur aus den Amazon-S3-Metadateneigenschaften des Digest-Datei-Objekts abrufen müssen. Die Signatur der vorherigen Digest-Datei wird im Feld previousDigestSignature
bereitgestellt.
Sie können bis zur ersten Digest-Datei oder bis zur Unterbrechung der Kette von Digest-Dateien zurückkehren, je nachdem, was zuerst auftritt.
Ausführen der Offline-Validierung von Digest- und Protokolldateien
Wenn Sie Digest- und Protokolldateien offline validieren möchten, können Sie dazu die in den vorherigen Abschnitten beschriebenen Verfahren nutzen. Dabei sind folgende Aspekte zu berücksichtigen:
Verwenden der neuesten Digest-Datei
Die digitale Signatur der neuesten (also der „aktuellen“) Digest-Datei befindet sich in den Amazon-S3-Metadateneigenschaften des Digest-Dateiobjekts. In einem Offline-Szenario steht daher die digitale Signatur der aktuellen Digest-Datei nicht zur Verfügung.
Nachfolgend finden Sie zwei Möglichkeiten für dieses Szenario:
-
Da sich die digitale Signatur für die vorherige Digest-Datei in der aktuellen Digest-Datei befindet, beginnen Sie mit der Validierung von der Digest-Datei aus. next-to-last Bei dieser Methode kann die neueste Digest-Datei nicht validiert werden.
-
In einem ersten Schritt wird die Signatur für die aktuelle Digest-Datei aus den Metadateneigenschaften des Digest-Dateiobjekts abgerufen und anschließend sicher offline gespeichert. Auf diese Weise können Sie neben den vorherigen Dateien in der Kette auch die aktuelle Digest-Datei validieren.
Pfadauflösung
In den heruntergeladenen Digest-Dateien verweisen Felder wie s3Object
und previousDigestS3Object
nach wie vor auf die Online-Speicherorte der Protokoll- und Digest-Dateien in Amazon S3. Bei einer Offline-Lösung muss eine Möglichkeit gefunden werden, um diese auf den aktuellen Pfad der heruntergeladenen Protokoll- und Digest-Dateien umzuleiten.
Öffentliche Schlüssel
Bei einer Offline-Validierung müssen alle öffentlichen Schlüssel, die für die Validierung der Protokolldateien in einem bestimmten Zeitraum erforderlich sind, zuvor online abgerufen (z. B. über den Aufruf von ListPublicKeys
) und dann sicher offline gespeichert werden. Dieser Schritt muss stets wiederholt werden, wenn Sie weitere Dateien außerhalb des ursprünglich angegebenen Zeitraums validieren möchten.
Snippet mit Beispielvalidierung
Der folgende Beispielausschnitt enthält einen Grundcode für die Validierung von Digest- und Protokolldateien. CloudTrail Das Code-Skelett basiert nicht auf einer Online- oder Offline-Validierung, sodass Sie entscheiden können, ob es mit oder ohne Online-Verbindung zu AWS implementiert werden soll. Die vorgeschlagene Implementierung verwendet die Java Cryptography Extension (JCE)
Das Beispiel-Snippet zeigt die folgenden Schritte:
-
So erstellen Sie die Datensignaturzeichenfolge für die Validierung der Digest-Dateisignatur.
-
So überprüfen Sie die Digest-Dateisignatur.
-
So überprüfen Sie die Hashwerte der Protokolldatei.
-
Eine Codestruktur zur Validierung einer Kette von Digest-Dateien.
import java.util.Arrays; import java.security.MessageDigest; import java.security.KeyFactory; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.spec.X509EncodedKeySpec; import org.json.JSONObject; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.apache.commons.codec.binary.Hex; public class DigestFileValidator { public void validateDigestFile(String digestS3Bucket, String digestS3Object, String digestSignature) { // Using the Bouncy Castle provider as a JCE security provider - http://www.bouncycastle.org/ Security.addProvider(new BouncyCastleProvider()); // Load the digest file from S3 (using Amazon S3 Client) or from your local copy JSONObject digestFile = loadDigestFileInMemory(digestS3Bucket, digestS3Object); // Check that the digest file has been retrieved from its original location if (!digestFile.getString("digestS3Bucket").equals(digestS3Bucket) || !digestFile.getString("digestS3Object").equals(digestS3Object)) { System.err.println("Digest file has been moved from its original location."); } else { // Compute digest file hash MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(convertToByteArray(digestFile)); byte[] digestFileHash = messageDigest.digest(); messageDigest.reset(); // Compute the data to sign String dataToSign = String.format("%s%n%s/%s%n%s%n%s", digestFile.getString("digestEndTime"), digestFile.getString("digestS3Bucket"), digestFile.getString("digestS3Object"), // Constructing the S3 path of the digest file as part of the data to sign Hex.encodeHexString(digestFileHash), digestFile.getString("previousDigestSignature")); byte[] signatureContent = Hex.decodeHex(digestSignature); /* NOTE: To find the right public key to verify the signature, call CloudTrail ListPublicKey API to get a list of public keys, then match by the publicKeyFingerprint in the digest file. Also, the public key bytes returned from ListPublicKey API are DER encoded in PKCS#1 format: PublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, PublicKey BIT STRING } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } */ pkcs1PublicKeyBytes = getPublicKey(digestFile.getString("digestPublicKeyFingerprint"))); // Transform the PKCS#1 formatted public key to x.509 format. RSAPublicKey rsaPublicKey = RSAPublicKey.getInstance(pkcs1PublicKeyBytes); AlgorithmIdentifier rsaEncryption = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, null); SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(rsaEncryption, rsaPublicKey); // Create the PublicKey object needed for the signature validation PublicKey publicKey = KeyFactory.getInstance("RSA", "BC").generatePublic(new X509EncodedKeySpec(publicKeyInfo.getEncoded())); // Verify signature Signature signature = Signature.getInstance("SHA256withRSA", "BC"); signature.initVerify(publicKey); signature.update(dataToSign.getBytes("UTF-8")); if (signature.verify(signatureContent)) { System.out.println("Digest file signature is valid, validating log files…"); for (int i = 0; i < digestFile.getJSONArray("logFiles").length(); i++) { JSONObject logFileMetadata = digestFile.getJSONArray("logFiles").getJSONObject(i); // Compute log file hash byte[] logFileContent = loadUncompressedLogFileInMemory( logFileMetadata.getString("s3Bucket"), logFileMetadata.getString("s3Object") ); messageDigest.update(logFileContent); byte[] logFileHash = messageDigest.digest(); messageDigest.reset(); // Retrieve expected hash for the log file being processed byte[] expectedHash = Hex.decodeHex(logFileMetadata.getString("hashValue")); boolean signaturesMatch = Arrays.equals(expectedHash, logFileHash); if (!signaturesMatch) { System.err.println(String.format("Log file: %s/%s hash doesn't match.\tExpected: %s Actual: %s", logFileMetadata.getString("s3Bucket"), logFileMetadata.getString("s3Object"), Hex.encodeHexString(expectedHash), Hex.encodeHexString(logFileHash))); } else { System.out.println(String.format("Log file: %s/%s hash match", logFileMetadata.getString("s3Bucket"), logFileMetadata.getString("s3Object"))); } } } else { System.err.println("Digest signature failed validation."); } System.out.println("Digest file validation completed."); if (chainValidationIsEnabled()) { // This enables the digests' chain validation validateDigestFile( digestFile.getString("previousDigestS3Bucket"), digestFile.getString("previousDigestS3Object"), digestFile.getString("previousDigestSignature")); } } } }