Implementasi kustom validasi integritas file CloudTrail log - AWS CloudTrail

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Implementasi kustom validasi integritas file CloudTrail log

Karena CloudTrail menggunakan standar industri, algoritma kriptografi yang tersedia secara terbuka dan fungsi hash, Anda dapat membuat alat sendiri untuk memvalidasi integritas file log. CloudTrail Saat validasi integritas file log diaktifkan, kirimkan file CloudTrail intisari ke bucket Amazon S3 Anda. Anda dapat menggunakan file-file ini untuk menerapkan solusi validasi Anda sendiri. Untuk informasi selengkapnya tentang file digest, lihatCloudTrail struktur file digest.

Topik ini menjelaskan bagaimana file digest ditandatangani, dan kemudian merinci langkah-langkah yang perlu Anda ambil untuk menerapkan solusi yang memvalidasi file digest dan file log yang mereka referensikan.

Memahami bagaimana file CloudTrail digest ditandatangani

CloudTrail file digest ditandatangani dengan tanda tangan RSA digital. Untuk setiap file digest, CloudTrail lakukan hal berikut:

  1. Membuat string untuk penandatanganan data berdasarkan bidang file digest yang ditunjuk (dijelaskan di bagian berikutnya).

  2. Mendapat kunci pribadi yang unik untuk Wilayah.

  3. Melewati hash SHA -256 dari string dan kunci pribadi ke algoritma RSA penandatanganan, yang menghasilkan tanda tangan digital.

  4. Mengkodekan kode byte tanda tangan ke dalam format heksadesimal.

  5. Menempatkan tanda tangan digital ke properti x-amz-meta-signature metadata objek file intisari Amazon S3.

Isi string penandatanganan data

CloudTrail Objek berikut disertakan dalam string untuk penandatanganan data:

  • Stempel waktu akhir dari file digest dalam format yang UTC diperluas (misalnya,) 2015-05-08T07:19:37Z

  • Jalur S3 file intisari saat ini

  • Hash -256 yang dikodekan heksadesimal dari file intisari saat SHA ini

  • Tanda tangan heksadesimal yang dikodekan dari file intisari sebelumnya

Format untuk menghitung string ini dan string contoh disediakan nanti dalam dokumen ini.

Langkah-langkah implementasi validasi kustom

Saat menerapkan solusi validasi kustom, Anda harus memvalidasi file digest terlebih dahulu, dan kemudian file log yang direferensikannya.

Validasi file intisari

Untuk memvalidasi file intisari, Anda memerlukan tanda tangannya, kunci publik yang kunci pribadinya digunakan untuk menandatanganinya, dan string penandatanganan data yang Anda hitung.

  1. Dapatkan file intisari.

  2. Verifikasi bahwa file intisari telah diambil dari lokasi aslinya.

  3. Dapatkan tanda tangan heksadesimal yang dikodekan dari file digest.

  4. Dapatkan sidik jari yang dikodekan heksadesimal dari kunci publik yang kunci pribadinya digunakan untuk menandatangani file intisari.

  5. Ambil kunci publik untuk rentang waktu yang sesuai dengan file digest.

  6. Dari antara kunci publik yang diambil, pilih kunci publik yang sidik jarinya cocok dengan sidik jari dalam file intisari.

  7. Menggunakan hash file digest dan bidang file digest lainnya, buat ulang string penandatanganan data yang digunakan untuk memverifikasi tanda tangan file digest.

  8. Validasi tanda tangan dengan meneruskan hash SHA -256 string, kunci publik, dan tanda tangan sebagai parameter ke algoritma verifikasi RSA tanda tangan. Jika hasilnya benar, file digest valid.

Validasi file log

Jika file digest valid, validasi setiap file log yang direferensikan file digest.

  1. Untuk memvalidasi integritas file log, hitung nilai hash SHA -256 pada konten yang tidak terkompresi dan bandingkan hasilnya dengan hash untuk file log yang direkam dalam heksadesimal dalam intisari. Jika hash cocok, file log valid.

  2. Dengan menggunakan informasi tentang file intisari sebelumnya yang disertakan dalam file intisari saat ini, validasi file intisari sebelumnya dan file log yang sesuai secara berurutan.

Bagian berikut menjelaskan langkah-langkah ini secara rinci.

A. Dapatkan file digest

Langkah pertama adalah mendapatkan file intisari terbaru, memverifikasi bahwa Anda telah mengambilnya dari lokasi aslinya, memverifikasi tanda tangan digitalnya, dan mendapatkan sidik jari kunci publik.

  1. Menggunakan S3 GetObjectatau kelas Amazons3Client (misalnya), dapatkan file intisari terbaru dari bucket Amazon S3 Anda untuk rentang waktu yang ingin Anda validasi.

  2. Periksa apakah bucket S3 dan objek S3 yang digunakan untuk mengambil file cocok dengan lokasi objek S3 bucket S3 yang direkam dalam file digest itu sendiri.

  3. Selanjutnya, dapatkan tanda tangan digital dari file digest dari properti x-amz-meta-signature metadata objek file digest di Amazon S3.

  4. Dalam file digest, dapatkan sidik jari kunci publik yang kunci pribadinya digunakan untuk menandatangani file intisari dari bidang. digestPublicKeyFingerprint

B. Ambil kunci publik untuk memvalidasi file digest

Untuk mendapatkan kunci publik untuk memvalidasi file digest, Anda dapat menggunakan file AWS CLI atau file. CloudTrail API Dalam kedua kasus, Anda menentukan rentang waktu (yaitu, waktu mulai dan waktu akhir) untuk file intisari yang ingin Anda validasi. Satu atau beberapa kunci publik dapat dikembalikan untuk rentang waktu yang Anda tentukan. Kunci yang dikembalikan mungkin memiliki rentang waktu validitas yang tumpang tindih.

catatan

Karena CloudTrail menggunakan pasangan kunci pribadi/publik yang berbeda per Wilayah, setiap file intisari ditandatangani dengan kunci pribadi yang unik untuk Wilayahnya. Oleh karena itu, ketika Anda memvalidasi file intisari dari Wilayah tertentu, Anda harus mengambil kunci publiknya dari Wilayah yang sama.

Gunakan tombol AWS CLI untuk mengambil kunci publik

Untuk mengambil kunci publik untuk mencerna file dengan menggunakan AWS CLI, gunakan perintah. cloudtrail list-public-keys Perintah memiliki format berikut:

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

Parameter waktu mulai dan akhir waktu adalah UTC stempel waktu dan bersifat opsional. Jika tidak ditentukan, waktu saat ini digunakan, dan kunci publik atau kunci yang saat ini aktif dikembalikan.

Sampel Respon

Responsnya akan berupa daftar JSON objek yang mewakili kunci (atau kunci) yang dikembalikan:

{ "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" } ] }

Gunakan tombol CloudTrail API untuk mengambil kunci publik

Untuk mengambil kunci publik untuk mencerna file dengan menggunakan CloudTrail API, teruskan nilai waktu mulai dan waktu akhir ke file. ListPublicKeys API ListPublicKeysAPIMengembalikan kunci publik yang kunci pribadinya digunakan untuk menandatangani file digest dalam rentang waktu yang ditentukan. Untuk setiap kunci publik, API juga mengembalikan sidik jari yang sesuai.

ListPublicKeys

Bagian ini menjelaskan parameter permintaan dan elemen respons untuk ListPublicKeysAPI.

catatan

Pengkodean untuk bidang biner ListPublicKeys untuk dapat berubah.

Parameter Permintaan

Nama Penjelasan
StartTime

Secara opsional menentukan, diUTC, awal rentang waktu untuk mencari kunci publik untuk file CloudTrail digest. Jika tidak StartTime ditentukan, waktu saat ini digunakan, dan kunci publik saat ini dikembalikan.

Jenis: DateTime

EndTime

Secara opsional menentukan, diUTC, akhir rentang waktu untuk mencari kunci publik untuk file CloudTrail intisari. Jika tidak EndTime ditentukan, waktu saat ini digunakan.

Jenis: DateTime

Elemen Respon

PublicKeyList, array PublicKey objek yang berisi:

Nama Deskripsi
Value

Nilai kunci publik DER yang dikodekan dalam format PKCS #1.

Jenis: Gumpalan

ValidityStartTime

Waktu mulai validitas kunci publik.

Jenis: DateTime

ValidityEndTime

Waktu akhir validitas kunci publik.

Jenis: DateTime

Fingerprint

Sidik jari kunci publik. Sidik jari dapat digunakan untuk mengidentifikasi kunci publik yang harus Anda gunakan untuk memvalidasi file intisari.

Tipe: String

C. Pilih kunci publik yang akan digunakan untuk validasi

Dari antara kunci publik yang diambil oleh list-public-keys atauListPublicKeys, pilih kunci publik yang dikembalikan yang sidik jarinya cocok dengan sidik jari yang direkam di digestPublicKeyFingerprint bidang file intisari. Ini adalah kunci publik yang akan Anda gunakan untuk memvalidasi file digest.

D. Buat ulang string penandatanganan data

Sekarang setelah Anda memiliki tanda tangan file digest dan kunci publik terkait, Anda perlu menghitung string penandatanganan data. Setelah menghitung string penandatanganan data, Anda akan memiliki input yang diperlukan untuk memverifikasi tanda tangan.

String penandatanganan data memiliki format berikut:

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

Contoh Data_To_Sign_String berikut.

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

Setelah Anda membuat ulang string ini, Anda dapat memvalidasi file digest.

E. Validasi file intisari

Lulus hash SHA -256 dari string penandatanganan data yang dibuat ulang, tanda tangan digital, dan kunci publik ke algoritma verifikasi RSA tanda tangan. Jika output benar, tanda tangan dari file digest diverifikasi dan file digest valid.

F. Validasi file log

Setelah Anda memvalidasi file intisari, Anda dapat memvalidasi file log yang direferensikannya. File DIGEST berisi SHA -256 hash dari file log. Jika salah satu file log diubah setelah CloudTrail dikirimkan, hash SHA -256 akan berubah, dan tanda tangan file digest tidak akan cocok.

Berikut ini menunjukkan bagaimana memvalidasi file log:

  1. Lakukan file S3 Get log menggunakan informasi lokasi S3 di file digest logFiles.s3Bucket dan logFiles.s3Object bidang.

  2. Jika S3 Get operasi berhasil, ulangi melalui file log yang tercantum dalam logFiles array file digest menggunakan langkah-langkah berikut:

    1. Ambil hash asli file dari logFiles.hashValue bidang log yang sesuai dalam file digest.

    2. Hash konten yang tidak terkompresi dari file log dengan algoritma hashing yang ditentukan dalam. logFiles.hashAlgorithm

    3. Bandingkan nilai hash yang Anda hasilkan dengan nilai untuk log di file intisari. Jika hash cocok, file log valid.

G. Validasi intisari tambahan dan file log

Di setiap file intisari, bidang berikut menyediakan lokasi dan tanda tangan dari file intisari sebelumnya:

  • previousDigestS3Bucket

  • previousDigestS3Object

  • previousDigestSignature

Gunakan informasi ini untuk mengunjungi file intisari sebelumnya secara berurutan, memvalidasi tanda tangan masing-masing dan file log yang mereka referensikan dengan menggunakan langkah-langkah di bagian sebelumnya. Satu-satunya perbedaan adalah bahwa untuk file digest sebelumnya, Anda tidak perlu mengambil tanda tangan digital dari properti metadata Amazon S3 objek file digest. Tanda tangan untuk file intisari sebelumnya disediakan untuk Anda di previousDigestSignature lapangan.

Anda dapat kembali sampai file intisari awal tercapai, atau sampai rantai file digest rusak, mana yang lebih dulu.

Memvalidasi file intisari dan log secara offline

Saat memvalidasi file intisari dan log secara offline, Anda biasanya dapat mengikuti prosedur yang dijelaskan di bagian sebelumnya. Namun, Anda harus mempertimbangkan bidang-bidang berikut:

Menangani file intisari terbaru

Tanda tangan digital dari file intisari terbaru (yaitu, “saat ini”) ada di properti metadata Amazon S3 dari objek file digest. Dalam skenario offline, tanda tangan digital untuk file intisari saat ini tidak akan tersedia.

Dua cara yang mungkin untuk menangani ini adalah:

  • Karena tanda tangan digital untuk file intisari sebelumnya ada di file intisari saat ini, mulailah memvalidasi dari file intisari. next-to-last Dengan metode ini, file intisari terbaru tidak dapat divalidasi.

  • Sebagai langkah awal, dapatkan tanda tangan untuk file intisari saat ini dari properti metadata objek file digest dan kemudian simpan secara offline dengan aman. Ini akan memungkinkan file intisari saat ini divalidasi selain file sebelumnya dalam rantai.

Resolusi jalur

Bidang dalam file intisari yang diunduh seperti s3Object dan masih previousDigestS3Object akan menunjuk ke lokasi online Amazon S3 untuk file log dan file cerna. Solusi offline harus menemukan cara untuk mengubah rute ini ke jalur log dan mencerna file yang diunduh saat ini.

Kunci publik

Untuk memvalidasi offline, semua kunci publik yang Anda butuhkan untuk memvalidasi file log dalam rentang waktu tertentu harus diperoleh terlebih dahulu secara online (dengan meneleponListPublicKeys, misalnya) dan kemudian disimpan secara offline dengan aman. Langkah ini harus diulang setiap kali Anda ingin memvalidasi file tambahan di luar rentang waktu awal yang Anda tentukan.

Contoh cuplikan validasi

Contoh cuplikan berikut menyediakan kode kerangka untuk memvalidasi file CloudTrail digest dan log. Kode kerangka adalah agnostik online/offline; artinya, terserah Anda untuk memutuskan apakah akan menerapkannya dengan atau tanpa konektivitas online ke. AWS Implementasi yang disarankan menggunakan Java Cryptography Extension (JCE) dan Bouncy Castle sebagai penyedia keamanan.

Cuplikan sampel menunjukkan:

  • Cara membuat string penandatanganan data yang digunakan untuk memvalidasi tanda tangan file digest.

  • Cara memverifikasi tanda tangan file digest.

  • Cara memverifikasi hash file log.

  • Struktur kode untuk memvalidasi rantai file intisari.

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")); } } } }