Fast hashing: kombinasi berbagai teknik untuk mengidentifikasi perubahan pada file?


9

Saya ingin membuat cara cepat untuk mendeteksi apakah suatu file mungkin atau tidak sama. Untuk kepastian hampir 100% saya akan menggunakan algoritma hash yang ada, misalnya SHA256. Namun, file tersebut diharapkan menjadi file video besar dengan beberapa GB, sehingga menghitung hash SHA256 dapat memakan waktu, terutama melalui jaringan.

Karena itu saya ingin menggabungkan berbagai teknik lain:

  • ukuran file: jika ukuran file telah berubah, konten telah berubah (pasti)
  • kepala / ekor hash
  • hash acak

2 yang terakhir adalah bagian dari pertanyaan saya:

Dugaan saya adalah bahwa di header ada beberapa hal seperti:

  • frame rate (mis. Video)
  • resolusi (mis. Video, Gambar)
  • (file) panjang (mis. dalam bingkai, piksel, dll.)
  • tanggal perubahan terakhir (mis. dokumen Word, bukan khusus Video)

Mengapa saya mempertimbangkan untuk memeriksa ekornya adalah:

  • MP3 memiliki informasi tag di sana
  • EXIF menambahkan data khusus pada akhirnya jika saya benar

Hash acak akan memilih misalnya 126 wilayah pada posisi acak dalam file dengan panjang tertentu, misalnya 64 kB dan membuat hash untuknya. Tentu saja saya ingat offset untuk perbandingan nanti. Secara keseluruhan saya akan menggunakan (1 + 126 + 1) * 64 kB data untuk hash saya, jadi saya hanya perlu membaca 8 MB daripada beberapa GB untuk mendapatkan hash.

Mungkin ini lebih merupakan pertanyaan Matematika sekarang, tetapi: seberapa besar kemungkinannya untuk mendeteksi perubahan menggunakan kombinasi ukuran file, kepala, ekor dan data acak untuk menghasilkan jumlah hash cepat ini?

Saya berasumsi bahwa file selalu file yang legal. Tidak ada manfaatnya memanipulasi byte tunggal. Pengguna akan menggunakan alat pengeditan video normal untuk mengubah file.

UPDATE : Saya menerima jawaban ini yang berasal dari Crypto.StackExchange. Saya setuju bahwa proposal saya bukan kriptografi dan tidak dimaksudkan untuk aman. Saya juga setuju bahwa CRCing file cepat, tetapi dalam kasus saya saya benar-benar membutuhkan hash - saya akan menjelaskan alasannya:

  • Aplikasi saya diharapkan untuk menyimpan bookmark di video. Basis data saya diharapkan untuk menyimpan hash video dan bookmark.
  • Pengguna terkadang memindahkan atau mengganti nama file. Program saya akan melihat bahwa file tidak ada lagi, tetapi tidak akan menghapus bookmark dari database. Alih-alih, ketika video yang sama diputar secara tidak sengaja, saya ingin mengenali bahwa itu mungkin file yang sama.
  • Pengguna diharapkan untuk menyimpan file di drive jaringan (NAS) dan streaming video. Itu adalah penyimpanan bodoh. Saya tidak dapat menginstal komponen server. Dan mereka mungkin sangat lambat, jadi saya benar-benar tidak ingin hash penuh. Menghitung hash penuh pada file 3 GB membutuhkan setidaknya 5 menit @ 10 MB / s, tidak peduli seberapa cepat algoritma hashing.
  • Jika pengguna telah mengedit file, saya entah bagaimana berharap hash tidak akan cocok lagi, karena kalau tidak saya akan menampilkan bookmark yang salah.

Saya akan baik-baik saja dengan peluang ~ 80% untuk memiliki bookmark yang benar. Berapa banyak potongan hash yang harus saya kumpulkan dan di mana dalam file itu?


1
Selama perusakan berbahaya atau file korupsi tidak menjadi perhatian, tidak perlu untuk semua ini. Cukup gunakan program khusus untuk menginterpretasikan tajuk file media, yang harus berisi tanggal dan ukuran penyandian / penandaan arus. Anda dapat memotong informasi media untuk perbandingan mudah.

Juga, sebagian besar sistem operasi menjaga 'tanggal modifikasi terakhir' tersedia untuk setiap file. Jika Anda tidak perlu khawatir tentang perusakan berbahaya (tanggal modifikasi terakhir umumnya dapat diatur oleh seseorang), Anda bisa melihatnya, dan tidak repot dengan konten file sama sekali.
ponco

EXIF atau MP3tag hampir tidak berguna untuk mendeteksi perubahan: Banyak program manipulasi tidak dapat menyentuh ini sehingga mereka mempertahankan konten mereka sebelumnya. Misalnya EXIF ​​mungkin mempertahankan gambar aslinya .

1
Pergi dengan "Saya menganggap bahwa file selalu file yang legal", saya kira Anda tidak mencari keamanan apa pun? Dalam hal ini Anda berada di situs yang salah. Ilmu Komputer seharusnya menjadi bantuan yang lebih baik. Jawaban yang Anda miliki di sini tidak relevan jika Anda tidak menginginkan keamanan, jadi jika ini masalahnya saya sarankan untuk memposting ulang tentang Ilmu Komputer dan mengklarifikasi hal itu dalam pertanyaan yang Anda posting ulang.
Gilles 'SANGAT berhenti menjadi jahat'

2
1) Perhitungan hash yang sebenarnya biasanya akan lebih murah dibandingkan dengan IO. MD5 akan mendeteksi semua perubahan yang tidak berbahaya dan cukup cepat. Apalagi jika Anda memparalelkannya. Anda membutuhkan RAID SSD atau sesuatu yang serupa dengan cepat untuk melebihi kecepatannya. 2) Untuk file lokal OS sering dapat memberi tahu Anda jika itu berubah. Bukan hanya tanggal perubahan terakhir, ada beberapa API khusus juga.
CodesInChaos

Jawaban:


8

Ada dua sisi pada koin Anda:

  1. jika Anda ingin melakukannya dengan aman, Anda harus menggunakan hash yang aman secara kriptografis seperti SHA256 (crypto-hashes dimaksudkan untuk menjadi cepat, tetapi cenderung agak lambat karena kendala keamanan),
  2. hal-hal seperti CRC pasti lebih cepat, tetapi tidak akan pernah bisa menawarkan jenis keamanan yang sama (terutama ketika kita berbicara tentang.

Opsi 1: CRC - Melakukannya dengan cepat dengan harga keamanan:

Jika Anda baru saja mendeteksi perubahan, pilih checksum alih-alih hash. Untuk itulah checksum dibuat: dengan cepat mendeteksi perubahan dalam file atau aliran data. Tetapi perlu diingat bahwa CRC dirancang untuk mencegah kesalahan transmisi, bukan tindakan jahat!

Secara praktis, CRC32 adalah kandidat yang paling jelas (tetapi bahkan CRC8 aditif akan melakukan pekerjaan jika Anda hanya ingin mendeteksi jika ada sesuatu yang berubah dan tidak mengharapkan apa pun selain itu dari CRC.)

Opsi 2: Melampaui CRC - Melakukannya dengan lebih cepat sambil meningkatkan deteksi perubahan:

Opsi valid lainnya (melihat komentar @ ponco ) memang cukup dengan memeriksa stempel waktu mod terakhir .

Atau, Anda menggabungkan keduanya (untuk mencegah kemacetan), menggunakan sesuatu seperti pseudo-code ini:

if(LastMod != knownLastMod) { CreateNewCRCandCompare(FileName, knownCRC) };

Tetapi apakah ini menawarkan keamanan nyata? Tidak. Sama berlaku untuk Anda ...

Mengapa saya mempertimbangkan untuk memeriksa ekornya adalah:
- MP3 memiliki informasi tag di sana
- EXIF ​​menambahkan data khusus pada akhirnya jika saya benar

Sekali lagi, itu tergantung pada seberapa banyak keamanan yang Anda harapkan. Anda harus menyadari bahwa musuh pasti akan memanipulasi file untuk menyimpan (atau menyalin-dan-tempel) data ID3 dan EXIF ​​lama ... karena siapa pun (dengan hak akses file RW yang sesuai) dapat memodifikasinya. Hal yang sama berlaku untuk cap waktu Modifikasi Terakhir, frame rate, resolusi, tanggal perubahan terakhir, dan bahkan panjang (file). Bergantung pada data "tambahan" dan "dapat dimodifikasi" - yang dapat dimodifikasi dan dihapus oleh siapa pun dengan hak akses file yang cukup - akan memperkenalkan kelemahan keamanan.

Tapi Anda memang mengharapkan keamanan, bukan? Bagaimanapun, itulah alasan mengapa Anda memikirkan semua ini sejak awal. Nah, maka tidak ada jalan lain menggunakan hash crypto-secure ...

Opsi 3: Hrip Cryptographically Secure - Melakukannya dengan aman dengan harga kecepatan:

Jika Anda mengharapkan keamanan nyata, Anda harus mengandalkan hashing; lebih tepatnya: hashing yang aman secara kriptografis (menggunakan hash yang tidak diketahui menghasilkan benturan). Butuh waktu (beberapa microsecs per MB) tetapi itu sangat berharga.

2 sen (pribadi) saya:

Cobalah untuk hidup dengan fakta bahwa hashing membutuhkan waktu dan hash seluruh file dengan hash yang aman secara kriptografis . Karena, ketika barang mulai mengenai kipas angin ... Anda lebih baik menjadi lambat, daripada menyesal.

EDIT berdasarkan EDIT Anda ...

Jika keamanan kriptografi bukan fokus utama Anda, Anda bisa melihat MD5 atau SHA1. Baik MD5 dan SHA1 "rusak secara kriptografi" karena tabrakan telah terdeteksi ... namun untuk tujuan deteksi perubahan yang Anda jelaskan (terutama setelah EDIT Anda), kemungkinan tabrakan seperti tabrakan harus cukup minimal.

Melihat semuanya lagi (termasuk EDIT Anda), saya pribadi kemungkinan besar akan menggunakan MD5, karena ia menawarkan resistensi tabrakan yang dapat digunakan (untuk tujuan deteksi perubahan) sementara masih cukup cepat untuk sepenuhnya mem-hash file multi-gigabyte.

Jika itu masih tidak memuaskan Anda dalam arti “kecepatan” atau jika sumber daya perangkat keras Anda benar-benar yang terbatas, Anda harus mencoba untuk menyeimbangkan tabrakan resistensi / perubahan-deteksi dengan kecepatan. Berarti…

Ambil stempel waktu individual, nama file individual, dan hash header (panjangnya tergantung pada jenis media dan format file yang digunakan) serta potongan yang baik dari tengah dan potongan ekor yang baik (= akhir file). Gabungkan kelima angka itu dan Anda harus bisa menyaring paling banyak

Saya akan baik-baik saja dengan peluang ~ 80% untuk memiliki bookmark yang benar. Berapa banyak potongan hash yang harus saya kumpulkan dan di mana dalam file itu?

Itu lebih dari pendapat pribadi, karena itu tergantung pada satu truk penuh detail (jenis media, format file, sumber daya yang tersedia, rasio deteksi-perubahan yang diharapkan, kesamaan file, dll.) Sehingga Anda harus menyeimbangkannya sendiri tergantung pada pribadi Anda harapan, implementasi Anda, dan hasil lokal karena hambatan perangkat keras dan / atau perangkat lunak.

Akan tetapi, saya mencoba memberi Anda beberapa panduan:

Jika hashing file lengkap bukan pilihan untuk alasan apa pun, saya akan - setidaknya - mengambil: header (dan mungkin beberapa KB lebih), potongan yang baik dari tengah (setidaknya ukuran "header & co . "Bagian), dan potongan yang baik dari ujung file (sekali lagi, setidaknya ukuran bagian" header & co. ").

Semakin banyak sumber daya yang dapat Anda investasikan (atau bersedia diinvestasikan), semakin banyak potongan yang dapat Anda ambil dan / atau semakin besar potongan tersebut. Jika Anda berpikir sumber daya / rasa / apa pun Anda masih menawarkan ruang lebih, tambah ukuran potongan yang Anda hash dan / atau tambah jumlah potongan yang Anda hash.

Menambah jumlah potongan mudah: karena yang perlu Anda lakukan adalah menjaga distribusi yang sama (dengan membagi ukuran file yang sesuai, menghasilkan potongan ukuran yang sama yang Anda ekstrak dari bagian dengan jarak yang sama pada seluruh panjang file).

Dan jika Anda bertanya pada diri sendiri “Mengapa posisi chunk yang terdistribusi secara acak dan tidak acak?”, Izinkan saya untuk mencatat bahwa memilih posisi chunk acak secara praktis dapat membuat upaya deteksi perubahan Anda batal karena menggabungkan risiko melewatkan beberapa bagian penting media di mana Anda biasanya akan mendeteksi peluang yang ingin Anda deteksi. Memilih distribusi yang sama - secara sederhana - lebih netral.


1
Saya tidak akan menggunakan CRC32, kemungkinan kegagalan terlalu besar bahkan tanpa serangan jahat. Crypto cukup cepat. Anda harus mendapatkan 1GB / s pada satu inti dengan hash standar. Jika Anda melemahkannya sedikit 3GB / s harus dimungkinkan. Hampir bisa dipastikan bahwa IO lebih mahal daripada hashing.
CodesInChaos

@CodesInChaos Saya setuju. Itu sebabnya kata-kata penutup saya menyarankan untuk menggunakan hash yang aman secara kriptografis.
e-sushi

1
Hash Carter-Wegman dan hash universal lainnya dapat membantu. Ini memiliki kecepatan CRC yang luas, dan keamanan hash, dengan asumsi kunci tetap tidak diketahui oleh penyerang dan tidak digunakan kembali. Lihat jawaban ini untuk referensi.
fgrieu

@ fgrieu Tapi bukankah itu - dalam situasi OP - berarti OP akan membutuhkan kunci individual per file? Agak tidak praktis bagi saya. Terutama, karena akan memperkenalkan kebutuhan untuk manajemen kunci dll. Hanya untuk memverifikasi modifikasi file yang potensial.
e-sushi

1
@ e-suschi: jika ada beberapa pengidentifikasi file unik (seperti path), kunci master dan HMAC adalah semua yang diperlukan untuk mendapatkan kunci unik per file. Yang mengatakan, jika musuh mendapat akses baca ke kunci, dia bisa membuat pemalsuan, ketika dia tidak bisa dengan hash file dan akses read-only.
fgrieu

5

Pintasan

Jika Anda memiliki banyak file dan ingin mendeteksi perubahan pada file, gunakan ukuran file dan cap waktu modifikasi terakhir.

Ada kemungkinan bahwa sistem operasi yang Anda gunakan menyediakan fasilitas untuk mendeteksi perubahan file, misalnya Linux memungkinkan untuk mendapatkan pemberitahuan tentang perubahan pada direktori.

Pemrosesan file lengkap

Jika Anda perlu membaca konten file yang sebenarnya untuk memeriksa apakah file telah berubah, lanjutkan dengan hash kriptografi aktual. CRC memiliki potensi signifikan untuk memberikan false negative. SHA-256 bisa sangat bagus, tetapi sebenarnya, SHA-512 lebih cepat pada banyak platform modern.

Jika Anda memiliki banyak core CPU, mungkin berguna untuk menghitung hash yang berbeda untuk bagian file yang berbeda atau menggunakan pohon hash untuk memparalelkan pemrosesan.

Alasan untuk menyarankan hash yang tepat adalah bahwa setelah Anda pergi ke data file yang sebenarnya, pemrosesan kriptografi tidak akan terlalu banyak, sebaliknya akan ada banyak hal yang lebih lambat, biasanya misalnya disk I / O atau mengirim dan menerima paket jaringan.

Catatan: Untuk (setidaknya) file kecil juga dimungkinkan untuk menyimpan seluruh isi file, dan melakukan perbandingan konten alih-alih hash.

Catatan 2: Jika penyimpanan Anda sangat ketat, CRC atau kriptografi terpotong bisa menjadi pilihan yang baik. CRC32 membutuhkan 4 byte per file, dan SHA-256 adalah 32 byte. Tag kecil 4 byte tidak dapat melindungi dari upaya jahat untuk menyembunyikan suntingan.

Pemrosesan file parsial

Dalam kebanyakan kasus, saya akan merekomendasikan hanya menggunakan pemrosesan file lengkap.

Mungkin ini lebih merupakan pertanyaan Matematika sekarang, tetapi: seberapa besar kemungkinannya untuk mendeteksi perubahan menggunakan kombinasi ukuran file, kepala, ekor dan data acak untuk menghasilkan jumlah hash cepat ini?

Untuk file gambar, biasanya dilakukan pengeditan kecil, seperti menghilangkan mata merah, tambahkan kumis atau tanduk, dll. Pengeditan ini dalam format JPG kadang-kadang tidak akan memengaruhi ukuran file (dengan program pengeditan yang dapat membuat perubahan pada JPG dengan mengkompresi ulang hanya diubah. area) atau salah satu atribut lain yang Anda sebutkan.

Waktu modifikasi file biasanya akan terpengaruh.

Mempertimbangkan file video: banyak format video menghasilkan bit rate yang konstan. Untuk file laju bit konstan, jika beberapa frame di tengah diubah, itu juga tidak akan muncul dalam ukuran file, kepala atau ekor. Menghapus atau menambahkan bingkai hampir selalu menghasilkan perbedaan ukuran.

Jadi saya melihat sepenuhnya mungkin bahwa bidang mendapatkan perubahan tanpa terdeteksi.

Sangat sulit untuk memperkirakan kemungkinan pengeditan terdeteksi dengan skema ini, tetapi ada skenario penggunaan umum untuk video dan gambar yang tidak terdeteksi dengan baik.


Ya, pengeditan kecil pada file PNG atau WAV berpeluang besar untuk dilewatkan jika hanya sebagian yang diproses.
galinette
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.