Valider les résultats de requête enregistrés par CloudTrail Lake - AWS CloudTrail

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Valider les résultats de requête enregistrés par CloudTrail Lake

Pour déterminer si les résultats de la requête ont été modifiés, supprimés ou inchangés après CloudTrail leur réception, vous pouvez utiliser la validation de l'intégrité des résultats de CloudTrail requête. Cette fonctionnalité est développée à l'aide d'algorithmes standard : SHA -256 pour le hachage et SHA -256 RSA pour la signature numérique. Il est donc impossible, sur le plan informatique, de modifier, de supprimer ou de falsifier des fichiers de résultats de CloudTrail requêtes sans détection. Vous pouvez utiliser la ligne de commande pour valider les fichiers de résultat d'une requête.

Pourquoi l'utiliser ?

Les fichiers de résultat d'une requête validés s'avèrent utiles lors d'enquêtes de sécurité et légales. Par exemple, un fichier de résultat d'une requête validé vous permet d'affirmer de manière positive que le fichier lui-même n'a pas été modifié. Le processus de validation de l'intégrité du fichier de résultats de CloudTrail requête vous permet également de savoir si un fichier de résultats de requête a été supprimé ou modifié.

Validez les résultats de requête enregistrés à l'aide du AWS CLI

Vous pouvez valider l'intégrité des fichiers de résultat d'une requête et du fichier de signature à l'aide de la commande aws cloudtrail verify-query-results.

Prérequis

Pour valider l'intégrité des résultats d'une requête à l'aide de la ligne de commande, les conditions suivantes doivent être remplies :

  • Vous devez disposer d'une connexion en ligne pour AWS.

  • Vous devez utiliser AWS CLI la version 2.

  • Pour valider les fichiers de résultats d'une requête et le fichier de signature localement, les conditions suivantes s'appliquent :

    • Vous devez placer les fichiers de résultats d'une requête et le fichier de signature dans le chemin d'accès spécifié. Indiquez le chemin d'accès au fichier comme valeur du paramètre --local-export-path.

    • Ne renommez ni les fichiers de résultats d'une requête, ni le fichier de signature.

  • Pour valider les fichiers de résultats d'une requête et le fichier de signature dans le compartiment S3, les conditions suivantes s'appliquent :

    • Ne renommez ni les fichiers de résultats d'une requête, ni le fichier de signature.

    • Vous devez disposer d'un accès en lecture au compartiment Amazon S3 qui contient les fichiers de résultat d'une requête et le fichier de signature.

    • Le préfixe S3 spécifié doit contenir les fichiers de résultats d'une requête et le fichier de signature. Spécifiez le préfixe S3 comme valeur du paramètre --s3-prefix.

verify-query-results

La commande verify-query-results vérifie la valeur de hachage de chaque fichier de résultats d'une requête fileHashValue en la comparant à la valeur du fichier de signature, puis en validant hashSignature dans le fichier de signature.

Lorsque vous vérifiez les résultats d'une requête, vous pouvez utiliser les options de ligne de commande --s3-bucket et --s3-prefix pour valider les fichiers de résultats d'une requête et le fichier de signature stockés dans un compartiment S3, ou vous pouvez utiliser l'option de ligne de commande --local-export-path pour effectuer une validation locale des fichiers de résultats d'une requête et du fichier de signature téléchargés.

Note

La commande verify-query-results est spécifique à la région. Vous devez spécifier l'option --region globale pour valider les résultats d'une requête spécifique Région AWS.

Voici les options pour la commande verify-query-results.

--s3-bucket <string>

Spécifie le nom du compartiment S3 qui stocke les fichiers de résultats d'une requête et le fichier de signature. Vous ne pouvez pas utiliser ce paramètre avec --local-export-path.

--s3-prefix <string>

Spécifie le chemin S3 du dossier S3 qui contient les fichiers de résultats d'une requête et le fichier de signature (par exemple, s3/path/). Vous ne pouvez pas utiliser ce paramètre avec --local-export-path. Il n'est pas nécessaire de fournir ce paramètre si les fichiers se trouvent dans le répertoire racine du compartiment S3.

--local-export-path <string>

Spécifie le répertoire local qui contient les fichiers de résultats d'une requête et le fichier de signature (par exemple, /local/path/to/export/file/). Vous ne pouvez pas utiliser ce paramètre avec --s3-bucket ou --s3-prefix.

Exemples

L'exemple suivant valide les résultats d'une requête à l'aide des options de ligne de commande --s3-bucket et --s3-prefix pour spécifier le nom du compartiment S3 et le préfixe contenant les fichiers de résultats d'une requête et le fichier de signature.

aws cloudtrail verify-query-results --s3-bucket amzn-s3-demo-bucket --s3-prefix prefix --region region

L'exemple suivant valide les résultats d'une requête téléchargés en utilisant l'option de ligne de commande --local-export-path pour spécifier le chemin local pour les fichiers de résultats d'une requête et le fichier de signature. Pour plus d'informations sur le téléchargement des résultats d'une requête, veuillez consulter Téléchargez les résultats de vos requêtes enregistrés sur CloudTrail Lake.

aws cloudtrail verify-query-results --local-export-path local_file_path --region region

Résultats de la validation

Le tableau suivant décrit les messages de validation possibles pour les fichiers de résultats d'une requête et le fichier de signature.

Type de fichier Message de validation Description
Sign file Successfully validated sign and query result files La signature du fichier de signature est valide. Les fichiers de résultats d'une requête auxquels il fait référence peuvent être vérifiés.
Query result file

ValidationError: "File file_name has inconsistent hash value with hash value recorded in sign file, hash value in sign file is expected_hash, but get computed_hash

La validation a échoué, car la valeur de hachage du fichier de résultats d'une requête ne correspondait pas au fileHashValue dans le fichier de signature.
Sign file

ValidationError: Invalid signature in sign file

La validation du fichier de signature a échoué, car la signature n'est pas valide.

CloudTrail structure du fichier de signes

Le fichier de signature contient le nom de chaque fichier de résultat d'une requête qui a été envoyé à votre compartiment Amazon S3 lorsque vous avez enregistré les résultats d'une requête, la valeur de hachage de chaque fichier de résultat de la requête et la signature numérique du fichier. La signature numérique et les valeurs de hachage sont utilisées pour valider l'intégrité des fichiers de résultat de la requête et du fichier de signature lui-même.

Emplacement du fichier de signature

Le fichier de signature est envoyé à un emplacement de compartiment Amazon S3 qui respecte cette syntaxe.

s3://amzn-s3-demo-bucket/optional-prefix/AWSLogs/aws-account-ID/CloudTrail-Lake/Query/year/month/date/query-ID/result_sign.json

Exemple de contenu du fichier de signature

L'exemple de fichier de signes suivant contient des informations relatives aux résultats des requêtes CloudTrail Lake.

{ "version": "1.0", "region": "us-east-1", "files": [ { "fileHashValue" : "de85a48b8a363033c891abd723181243620a3af3b6505f0a44db77e147e9c188", "fileName" : "result_1.csv.gz" } ], "hashAlgorithm" : "SHA-256", "signatureAlgorithm" : "SHA256withRSA", "queryCompleteTime": "2022-05-10T22:06:30Z", "hashSignature" : "7664652aaf1d5a17a12ba50abe6aca77c0ec76264bdf7dce71ac6d1c7781117c2a412e5820bccf473b1361306dff648feae20083ad3a27c6118172a81635829bdc7f7b795ebfabeb5259423b2fb2daa7d1d02f55791efa403dac553171e7ce5f9307d13e92eeec505da41685b4102c71ec5f1089168dacde702c8d39fed2f25e9216be5c49769b9db51037cb70a84b5712e1dffb005a74580c7fdcbb89a16b9b7674e327de4f5414701a772773a4c98eb008cca34228e294169901c735221e34cc643ead34628aabf1ba2c32e0cdf28ef403e8fe3772499ac61e21b70802dfddded9bea0ddfc3a021bf2a0b209f312ccee5a43f2b06aa35cac34638f7611e5d7", "publicKeyFingerprint" : "67b9fa73676d86966b449dd677850753" }

Description des champs du fichier de signature

Voici la description de chaque champ du fichier de signature :

version

La version du fichier de signature.

region

Région du AWS compte utilisé pour enregistrer les résultats de la requête.

files.fileHashValue

La valeur de hachage codée en hexadécimal du contenu compressé du fichier de résultat de la requête.

files.fileName

Le nom du fichier de resultat de la requête.

hashAlgorithm

L'algorithme de hachage utilisé pour hacher le fichier de résultat de la requête.

signatureAlgorithm

L'algorithme utilisé pour signer le fichier.

queryCompleteTime

Indique à CloudTrail quel moment les résultats de la requête ont été transmis au compartiment S3. Vous pouvez utiliser cette valeur pour trouver la clé publique.

hashSignature

La signature de hachage du fichier.

publicKeyFingerprint

L'empreinte digitale codée en hexadécimal de la clé publique utilisée pour signer le fichier.

Implémentations personnalisées de la validation de l'intégrité des fichiers de résultats de CloudTrail requêtes

Grâce à l' CloudTrail utilisation d'algorithmes cryptographiques et de fonctions de hachage conformes aux normes du secteur et librement disponibles, vous pouvez créer vos propres outils pour valider l'intégrité des fichiers de résultats des CloudTrail requêtes. Lorsque vous enregistrez les résultats d'une requête dans un compartiment Amazon S3, CloudTrail un fichier de signature est envoyé à votre compartiment S3. Vous pouvez mettre en œuvre votre propre solution de validation pour valider les fichiers de signature et les fichiers de résultats d'une requête. Pour plus d'informations sur le fichier de signature, consultez CloudTrail structure du fichier de signes.

Cette rubrique décrit comment le fichier de signature est signé, puis détaille les étapes que vous devrez suivre pour mettre en œuvre une solution qui valide le fichier de signature et les fichiers de résultat d'une requête auxquels le fichier de signature fait référence.

Comprendre comment CloudTrail les fichiers de signature sont signés

CloudTrail les fichiers de signature sont signés avec des signatures RSA numériques. Pour chaque fichier de signes, CloudTrail effectue les opérations suivantes :

  1. Crée une liste de hachage qui contient la valeur de hachage de chaque fichier de résultat d'une requête.

  2. Obtient une clé privée unique pour la région.

  3. Transmet le hachage SHA -256 de la chaîne et la clé privée à l'algorithme de RSA signature, qui produit une signature numérique.

  4. Code le code d'octet de la signature dans un format hexadécimal.

  5. Ajoute la signature numérique dans le fichier de signature.

Contenu de la chaîne de signature des données

La chaîne de signature des données est constituée de la valeur de hachage de chaque fichier de résultat d'une requête, séparés par un espace. Le fichier de signature énumère la valeur fileHashValue de chaque fichier de résultat d'une requête.

Étapes d'implémentation de la validation personnalisée

Lors de la mise en œuvre d'une solution de validation personnalisée, vous devrez valider le fichier de signature et les fichiers de résultat d'une requête auxquels il fait référence.

Validation du fichier de signature

Pour valider un fichier de signature, vous avez besoin de sa signature, de la clé publique dont la clé privée a été utilisée pour le signer et d'une chaîne de signature de données que vous calculez.

  1. Obtenir le fichier de signature.

  2. Vérifier que le fichier de signature a été récupéré depuis son emplacement d'origine.

  3. Obtenir la signature codée en hexadécimal du fichier de signature.

  4. Obtenir l'empreinte digitale codée en hexadécimal de la clé publique dont la clé privée a été utilisée pour signer le fichier de signature.

  5. Récupérer la clé publique pour la plage de temps correspondant à queryCompleteTime dans le fichier de signature. Pour la plage de temps, choisissez une StartTime antérieure à la queryCompleteTime et une EndTime postérieure à la queryCompleteTime.

  6. Parmi les clés publiques récupérées, choisissez la clé publique dont l'empreinte digitale correspond à la valeur publicKeyFingerprint dans le fichier de signature.

  7. À l'aide d'une liste de hachage contenant la valeur de hachage de chaque fichier de résultat d'une requête séparées par un espace, recréez la chaîne de signature des données utilisée pour vérifier la signature du fichier de signature. Le fichier de signature énumère la valeur fileHashValue de chaque fichier de résultat d'une requête.

    Par exemple, si le tableau files de votre fichier de signature contient les trois fichiers de résultat d'une requête suivants, votre liste de hachage est « aaa bbb ccc ».

    “files": [
 {
 "fileHashValue" : “aaa”,
 "fileName" : "result_1.csv.gz"
 }, {
 "fileHashValue" : “bbb”,
 "fileName" : "result_2.csv.gz"
 }, {
 "fileHashValue" : “ccc”,
 "fileName" : "result_3.csv.gz"
 } ],
  8. Validez la signature en transmettant le hachage SHA -256 de la chaîne, la clé publique et la signature en tant que paramètres à l'algorithme de vérification de RSA signature. Si le résultat est true, le fichier de signature est valide.

Validation des fichiers de résultat d'une requête

Si le fichier de signature est valide, validez les fichiers de résultat d'une requête auxquels le fichier de signature fait référence. Pour valider l'intégrité d'un fichier de résultats de requête, calculez sa valeur de hachage SHA -256 sur son contenu compressé et comparez les résultats avec ceux du fichier fileHashValue de résultats de requête enregistré dans le fichier de signature. Si les hachages correspondent, le fichier de résultat de la requête est valide.

Les sections suivantes décrivent en détail le processus de validation.

A. Obtenir le fichier de signature

Les premières étapes consistent à obtenir le fichier de signature et l'empreinte digitale de la clé publique.

  1. Obtenez le fichier de signature à partir de votre compartiment Amazon S3 pour les résultats de la requête que vous voulez valider.

  2. Ensuite, obtenez la valeur hashSignature à partir du fichier de signature.

  3. Dans le fichier de signature, obtenez l'empreinte digitale de la clé publique dont la clé privée a été utilisée pour signer le fichier à partir du champ publicKeyFingerprint.

B. Récupérer la clé publique pour valider le fichier de signature

Pour obtenir la clé publique permettant de valider le fichier de signature, vous pouvez utiliser le AWS CLI ou le CloudTrail API. Dans les deux cas, vous spécifiez une plage de temps (c'est-à-dire, une heure de début et une heure de fin) pour le fichier de signature que vous voulez valider. Utilisez une plage horaire correspondant à la queryCompleteTime dans le fichier de signature. Une ou plusieurs clés publiques peuvent être retournées pour l'intervalle de temps que vous spécifiez. Les clés renvoyées peuvent avoir des plages de temps de validité qui se chevauchent.

Note

Comme il CloudTrail utilise différentes paires de clés publiques/privées par région, chaque fichier de signes est signé avec une clé privée propre à sa région. Par conséquent, lorsque vous validez un fichier de signature à partir d'une région donnée, vous devez récupérer sa clé publique à partir de la même région.

Utilisez le AWS CLI pour récupérer les clés publiques

Pour récupérer une clé publique pour un fichier de signes à l'aide de AWS CLI, utilisez la cloudtrail list-public-keys commande. La commande a le format suivant :

aws cloudtrail list-public-keys [--start-time <start-time>] [--end-time <end-time>]

Les paramètres d'heure de début et de fin sont des UTC horodatages et sont facultatifs. S'ils ne sont pas spécifiés, l'heure actuelle est utilisée et la ou les clés publiques actives sont renvoyées.

Exemple de réponse

La réponse sera une liste d'JSONobjets représentant la clé (ou les clés) renvoyée :

Utiliser la CloudTrail API pour récupérer des clés publiques

Pour récupérer une clé publique pour un fichier de signature à l'aide du CloudTrail API, transmettez les valeurs d'heure de début et de fin au ListPublicKeysAPI. ListPublicKeysAPIRenvoie les clés publiques dont les clés privées ont été utilisées pour signer le fichier dans le délai spécifié. Pour chaque clé publique, le renvoie API également l'empreinte digitale correspondante.

ListPublicKeys

Cette section décrit les paramètres de demande et les éléments de réponse pour ListPublicKeysAPI.

Note

L'encodage pour les champs binaires pour ListPublicKeys est susceptible d'être modifié.

Paramètres de requête

Name (Nom) Description
StartTime

Spécifie éventuellement, dansUTC, le début de la plage de temps pour rechercher la clé publique pour le fichier de CloudTrail signature. Si StartTime ce n'est pas spécifié, l'heure actuelle est utilisée et la clé publique actuelle est renvoyée.

Type : DateTime

EndTime

Spécifie éventuellement, dansUTC, la fin de la plage de temps pour rechercher les clés publiques pour les fichiers de CloudTrail signature. Si EndTime ce n'est pas spécifié, l'heure actuelle est utilisée.

Type : DateTime

Éléments de réponse

PublicKeyList, un tableau des objets PublicKey qui contient les éléments suivants :

Name (Nom) Description
Value

La valeur de la clé publique DER codée au format PKCS #1.

Type : Blob

ValidityStartTime

Heure de début de validité de la clé publique.

Type : DateTime

ValidityEndTime

Heure de fin de validité de la clé publique.

Type : DateTime

Fingerprint

Empreinte de la clé publique. L'empreinte peut servir à identifier la clé publique que vous devez utiliser pour valider le fichier de signature.

Type : String

C. Sélectionner la clé publique à utiliser pour la validation

Parmi les clés publiques récupérées par list-public-keys ou ListPublicKeys, sélectionnez la clé publique dont l'empreinte digitale correspond à l'empreinte digitale enregistrée dans le champ publicKeyFingerprint du fichier de signature. C'est la clé publique que vous utiliserez pour valider le fichier de signature.

D. Recréer la chaîne de signature des données

Maintenant que vous avez la signature du fichier de signature et la clé publique associée, vous devez calculer la chaîne de signature des données. Une fois que vous aurez calculé les chaîne de signature des données, vous aurez les entrées nécessaires pour vérifier la signature.

La chaîne de signature des données est constituée de la valeur de hachage de chaque fichier de résultat d'une requête, séparés par un espace. Une fois que vous avez recréé cette chaîne, vous pouvez valider le fichier de signature.

E. Validation du fichier de signature

Transmettez la chaîne de signature des données, la signature numérique et la clé publique recréées à l'algorithme de vérification de RSA signature. Si le résultat est true, la signature du fichier de signature est vérifiée et le fichier de signature est valide.

F. Validation des fichiers de résultat d'une requête

Une fois que vous avez validé le fichier signature, vous pouvez valider les fichiers de résultat de la requête auxquels il fait référence. Le fichier de signature contient les SHA -256 hachages des fichiers de résultats de requête. Si l'un des fichiers de résultats de requête a été modifié après l'avoir CloudTrail livré, les hachages SHA -256 seront modifiés et la signature du fichier de signature ne correspondra pas.

Utilisez la procédure suivante pour valider les fichiers de résultat d'une requête répertoriés dans le tableau files du fichier de signature.

  1. Récupérez le hachage original du fichier dans le champ files.fileHashValue du fichier de signature.

  2. Hachez le contenu compressé du fichier de résultat d'une requête avec l'algorithme de hachage spécifié dans hashAlgorithm.

  3. Comparez la valeur de hachage que vous avez générée pour chaque fichier de résultat de la requête avec la valeur files.fileHashValue du fichier de signature. Si les hachages correspondent, les fichiers de résultat de la requête sont valides.

Validation des fichiers de signature et de résultat d'une requête hors ligne

Lors de la validation des fichiers de signature et des fichiers de résultats d'une requête hors connexion, vous pouvez généralement suivre les procédures décrites dans les sections précédentes. Cependant, vous devez prendre en compte les informations suivantes concernant les clés publiques.

Clés publiques

Pour effectuer une validation hors ligne, la clé publique dont vous avez besoin pour valider les fichiers de résultat d'une requête dans une plage de temps donnée doit d'abord être obtenue en ligne (en appelant ListPublicKeys, par exemple), puis stockée hors ligne. Cette étape doit être répétée chaque fois que vous souhaitez valider des fichiers supplémentaires en dehors de la plage de temps que vous avez spécifiée au départ.

Extrait de code de validation

L'exemple d'extrait suivant fournit un code squelette pour valider les fichiers de résultats de CloudTrail signes et de requêtes. Ce squelette de code peut aussi bien être implémenter avec ou sans connexion à AWS ; c'est à vous de décider. L'implémentation suggérée utilise l'extension de cryptographie Java (JCE) et Bouncy Castle comme fournisseur de sécurité.

L'exemple d'extrait de code montre :

  • Procédure de création de la chaîne de signature des données utilisée pour valider la signature du fichier de signature.

  • Procédure de vérification de la signature du fichier de signature.

  • Procédure de calcul de la valeur de hachage pour le fichier de résultat d'une requête et comparaison avec la valeur fileHashValue répertoriée dans le fichier de signature pour vérifier l'authenticité du fichier de résultat d'une requête.

import org.apache.commons.codec.binary.Hex; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.json.JSONArray; import org.json.JSONObject; import java.security.KeyFactory; import java.security.MessageDigest; import java.security.PublicKey; import java.security.Security; import java.security.Signature; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class SignFileValidationSampleCode { public void validateSignFile(String s3Bucket, String s3PrefixPath) throws Exception { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); // Load the sign file from S3 (using Amazon S3 Client) or from your local copy JSONObject signFile = loadSignFileToMemory(s3Bucket, String.format("%s/%s", s3PrefixPath, "result_sign.json")); // Using the Bouncy Castle provider as a JCE security provider - http://www.bouncycastle.org/ Security.addProvider(new BouncyCastleProvider()); List<String> hashList = new ArrayList<>(); JSONArray jsonArray = signFile.getJSONArray("files"); for (int i = 0; i < jsonArray.length(); i++) { JSONObject file = jsonArray.getJSONObject(i); String fileS3ObjectKey = String.format("%s/%s", s3PrefixPath, file.getString("fileName")); // Load the export file from S3 (using Amazon S3 Client) or from your local copy byte[] exportFileContent = loadCompressedExportFileInMemory(s3Bucket, fileS3ObjectKey); messageDigest.update(exportFileContent); byte[] exportFileHash = messageDigest.digest(); messageDigest.reset(); byte[] expectedHash = Hex.decodeHex(file.getString("fileHashValue")); boolean signaturesMatch = Arrays.equals(expectedHash, exportFileHash); if (!signaturesMatch) { System.err.println(String.format("Export file: %s/%s hash doesn't match.\tExpected: %s Actual: %s", s3Bucket, fileS3ObjectKey, Hex.encodeHexString(expectedHash), Hex.encodeHexString(exportFileHash))); } else { System.out.println(String.format("Export file: %s/%s hash match", s3Bucket, fileS3ObjectKey)); } hashList.add(file.getString("fileHashValue")); } String hashListString = hashList.stream().collect(Collectors.joining(" ")); /* 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 sign 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 } */ byte[] pkcs1PublicKeyBytes = getPublicKey(signFile.getString("queryCompleteTime"), signFile.getString("publicKeyFingerprint")); byte[] signatureContent = Hex.decodeHex(signFile.getString("hashSignature")); // 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(hashListString.getBytes("UTF-8")); if (signature.verify(signatureContent)) { System.out.println("Sign file signature is valid."); } else { System.err.println("Sign file signature failed validation."); } System.out.println("Sign file validation completed."); } }