Checksum Saja Tidak Cukup: Cara Memverifikasi Installer dengan SHA-256 dan Tanda Tangan OpenSSL
- Authors

- Name
- Samsul Hadi
- Threads
- @Threads


Kamu menjalankan satu perintah di server: unduh paket, ekstrak, pasang. Paketnya datang dari link resmi, lewat HTTPS, dan halaman unduhannya bahkan mencantumkan checksum SHA-256. Kamu cocokkan, hasilnya sama. Aman.
Belum tentu. Kalau orang yang bisa mengubah paket juga bisa mengubah halaman tempat checksum itu ditulis, checksum yang cocok hanya membuktikan satu hal: file yang kamu unduh sama dengan file yang dia taruh. Bukan sama dengan file yang dibuat pembuatnya.
Ini yang saya pikirkan waktu menulis installer HeyUrAssistant. Installer itu dijalankan pembeli di VPS miliknya sendiri, dengan akses root, lalu memasang asisten yang nantinya memegang akun WhatsApp dan data keluarga mereka. Kalau paket yang terpasang bukan paket asli, semua pengamanan lain di dalam aplikasi tidak ada artinya.
Artikel ini membahas empat pemeriksaan yang dijalankan installer itu sebelum memasang apa pun, kenapa setiap pemeriksaan ada, lalu cara menerapkannya di installer kamu sendiri, langkah demi langkah. Semua screenshot berasal dari demo yang saya jalankan dengan pemeriksaan yang sama persis.
Checksum dan tanda tangan menjawab pertanyaan yang berbeda
Checksum SHA-256 menjawab: apakah file ini utuh? SHA-256 mengubah isi file menjadi 64 karakter heksadesimal. Ubah satu baris saja, hasilnya berubah total. Checksum bagus untuk menangkap unduhan yang rusak atau terpotong, dan untuk menangkap perubahan kalau checksum yang kamu pegang berasal dari tempat yang tidak ikut diubah.
Masalahnya ada di kalimat terakhir itu. Checksum tidak punya pemilik. Siapa pun bisa menghitung checksum dari file apa pun. Kalau penyusup mengganti paket di server unduhan dan sekaligus mengganti checksum di halaman yang sama, keduanya cocok.
Tanda tangan digital menjawab pertanyaan lain: apakah file ini dibuat oleh pemegang kunci tertentu? Pembuat menandatangani paket dengan kunci privat yang hanya ada di tangannya. Siapa pun bisa memeriksa tanda tangan itu dengan kunci publik pasangannya, tapi tidak ada yang bisa membuat tanda tangan baru yang sah tanpa kunci privat. Penyusup yang mengubah paket tidak bisa menandatanganinya ulang.
Kecuali dia juga mengganti kunci publiknya. Kalau installer menerima kunci publik apa pun yang diberikan, penyusup cukup membuat pasangan kunci sendiri, menandatangani paket palsunya, lalu menyerahkan kunci publik miliknya. Tanda tangannya sah, untuk kunci yang salah. Karena itu kunci publik yang benar harus dipatok di dalam installer: installer tahu checksum kunci publik yang seharusnya, dan menolak kunci lain.
Ada satu celah lagi yang tidak ada hubungannya dengan keaslian. Arsip tar bisa berisi path seperti app/../../etc/sesuatu. Saat diekstrak dengan hak root, file itu bisa mendarat di luar folder tujuan. Paket yang ditandatangani dengan sah pun bisa membawa path seperti ini kalau proses build-nya keliru, jadi isi arsip tetap diperiksa sebelum diekstrak.
Yang dijalankan installer HeyUrAssistant
Versi pertama installer, 13 Agustus 2026, sudah mewajibkan checksum SHA-256 dan bisa memeriksa tanda tangan, tapi tanda tangannya masih opsional. Seminggu kemudian, 20 Agustus, saya mengeraskannya: tanda tangan menjadi wajib untuk mode --apply, dan checksum kunci publik dipatok di dalam script.
Urutan pemeriksaannya sekarang begini, dan semuanya terjadi sebelum ada satu file pun yang diekstrak ke server:
- Runtime Node.js diunduh dari nodejs.org dan dicocokkan dengan checksum yang dipatok per arsitektur (x64 dan arm64). Versi Node tidak diambil dari server pembeli.
- Paket rilis dicocokkan dengan checksum yang diberikan.
- Kunci publik dicocokkan dengan checksum yang dipatok di script.
- Tanda tangan paket diperiksa dengan
openssl dgst -sha256 -verify. Kalau tanda tangan diunduh, URL-nya wajib HTTPS. - Isi arsip diperiksa. Path yang mengandung
..atau.sebagai salah satu bagiannya membuat pemasangan berhenti.
Tanpa checksum, tanpa kunci publik, atau tanpa tanda tangan, mode --apply menolak berjalan sama sekali. Setiap kegagalan menghentikan script dengan pesan yang jelas, dan folder sementara dibersihkan lewat trap.
Untuk membuktikan setiap pemeriksaan benar-benar menangkap kasusnya, saya menyalin keempat pemeriksaan paket itu ke script kecil verify.sh, lalu menjalankannya terhadap lima skenario:

Skenario 3 adalah alasan tanda tangan ada: checksum di halaman unduhan ikut diganti, jadi pemeriksaan checksum lolos, tapi tanda tangan pembuat tidak cocok dengan paket yang diubah. Skenario 4 adalah alasan kunci publik dipatok: penyusup menandatangani paket palsunya dengan kunci miliknya sendiri, dan yang menolaknya adalah checksum kunci publik.
Memasang empat pemeriksaan di installer kamu
Demo ini memakai bash, sha256sum, dan OpenSSL 3 di Linux. Paket contohnya hanya berisi satu file JavaScript.
Langkah 1: buat pasangan kunci, sekali saja
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out pembuat.pem
openssl pkey -in pembuat.pem -pubout -out pembuat.pub.pem
pembuat.pem adalah kunci privat. Simpan di luar repo dan di luar server unduhan. Kalau kunci ini bocor, semua pemeriksaan di artikel ini tidak lagi berarti.
Langkah 2: di sisi pembuat, buat checksum dan tanda tangan setiap rilis
sha256sum release.tar.gz > release.tar.gz.sha256
openssl dgst -sha256 -sign pembuat.pem -out release.sig release.tar.gz
sha256sum pembuat.pub.pem

Perintah ketiga hanya dijalankan sekali. Hasilnya adalah nilai yang akan dipatok di installer. Di installer HeyUrAssistant, dua perintah pertama ada di script build rilis, jadi setiap paket otomatis punya file .sha256 dan .sig di sebelahnya.
Langkah 3: lihat sendiri bedanya checksum dan tanda tangan
Ubah satu baris di paket, lalu bandingkan:

Paket yang diubah hanya menambah satu panggilan fungsi di index.js, dan checksumnya berubah total. Tanda tangan lama juga tidak berlaku untuk paket itu. Bedanya, checksum baru bisa dibuat siapa pun, sedangkan tanda tangan baru hanya bisa dibuat pemegang pembuat.pem.
Langkah 4: tulis pemeriksaan di installer, urutannya penting
#!/usr/bin/env bash
set -u
file=$1; sha=$2; sig=$3; pub=$4; pinned_pub_sha=$5
printf '%s %s\n' "$sha" "$file" | sha256sum --check --status \
|| { echo "GAGAL: checksum paket tidak cocok"; exit 1; }
printf '%s %s\n' "$pinned_pub_sha" "$pub" | sha256sum --check --status \
|| { echo "GAGAL: checksum kunci publik tidak cocok"; exit 1; }
openssl dgst -sha256 -verify "$pub" -signature "$sig" "$file" >/dev/null 2>&1 \
|| { echo "GAGAL: tanda tangan tidak valid"; exit 1; }
tar -tzf "$file" | grep -Eq '(^|/)\.\.?(/|$)' \
&& { echo "GAGAL: arsip berisi path tidak aman"; exit 1; }
echo "OK: paket asli, boleh dipasang"
Tiga hal yang sering terlewat di sini:
sha256sum --checkdipakai, bukan membandingkan string sendiri. Format input-nya dua spasi di antara checksum dan nama file.- Kunci publik diperiksa sebelum dipakai untuk memeriksa tanda tangan. Kalau urutannya dibalik, kamu sudah memercayai kunci yang belum terbukti.
tar -tzfhanya membaca daftar isi, tidak mengekstrak. Pemeriksaan path terjadi sebelum ada file yang ditulis.
Langkah 5: patok checksum kunci publik di installer
Di installer HeyUrAssistant, nilainya menjadi default variabel, jadi pembeli tidak perlu mengetik apa pun:
public_key_sha256="${HYA_PUBLIC_KEY_SHA256:-<checksum kunci publik dari langkah 2>}"
Kunci publiknya sendiri boleh diunduh dari mana saja, karena installer hanya menerima kunci yang checksum-nya sama dengan nilai ini.
Langkah 6: tolak berjalan kalau bahan pemeriksaan tidak lengkap
Pemeriksaan yang bisa dilewati dengan cara tidak memberi argumen sama saja dengan tidak ada. Untuk mode yang benar-benar memasang, wajibkan semuanya:
[ -n "$release_sha256" ] || { echo "--sha256 is required for --apply." >&2; exit 2; }
[ -n "$public_key_file" ] && [ -f "$public_key_file" ] || { echo "--public-key is required for --apply." >&2; exit 2; }
[ -n "$signature_url" ] || [ -n "$signature_file" ] || { echo "A release signature is required for --apply." >&2; exit 2; }
case "$signature_url" in https://*) ;; *) echo "Signature URL must use HTTPS." >&2; exit 2;; esac
Baris terakhir hanya berlaku saat tanda tangan diunduh lewat URL. Di installer aslinya, baris itu ada di dalam cabang yang mengunduh tanda tangan.
Checklist untuk installer kamu
- Checksum SHA-256 dibuat otomatis di script build, bukan diketik manual.
- Setiap rilis ditandatangani dengan kunci privat yang tidak pernah ada di server unduhan.
- Checksum kunci publik dipatok di dalam installer.
- Kunci publik diperiksa sebelum dipakai memeriksa tanda tangan.
- Isi arsip diperiksa dengan
tar -tsebelum diekstrak, dan path dengan..ditolak. - Dependensi yang diunduh saat pemasangan, misalnya runtime, juga punya checksum yang dipatok.
- Mode yang memasang menolak berjalan tanpa checksum, tanda tangan, dan kunci publik.
- Semua URL unduhan wajib HTTPS.
- Ada skenario uji untuk setiap kegagalan, bukan hanya jalur yang berhasil.
Kalau kamu hanya pengguna, bukan pembuat: saat sebuah proyek menyediakan file .sig atau .asc di sebelah paketnya, periksa tanda tangannya, dan ambil kunci publiknya dari sumber yang terpisah dari halaman unduhan, misalnya repo resmi atau dokumentasi yang sudah kamu kenal.
Apa yang tidak dijamin pemeriksaan ini
- Semua ini bergantung pada kunci privat. Kalau kunci privat bocor, penyusup bisa menandatangani paket palsu yang lolos semua pemeriksaan. Mengganti kunci berarti merilis installer baru dengan checksum kunci yang baru.
- Installer itu sendiri harus didapat dari sumber yang benar. Pemeriksaan ini melindungi paket yang diunduh installer. Kalau seseorang mengganti script installer-nya, dia bisa menghapus pemeriksaannya. Karena itu installer sebaiknya diambil dari repo atau rilis resmi, bukan dari salinan yang dikirim orang.
- Demo ini menyederhanakan.
verify.shhanya berisi pemeriksaan paket. Installer aslinya juga memeriksa runtime Node.js, sumber tanda tangan, dan konfigurasi lain sebelum memasang. - Saat paket berbahaya di skenario 5 diperiksa,
tarjuga mencetak peringatan bahwa ia membuang awalanapp/../../. Peringatan itu disembunyikan dari screenshot supaya fokus pada hasil pemeriksaan.tarversi GNU memang sudah membuang awalan seperti itu saat mengekstrak, tapi installer sebaiknya tidak bergantung pada perilaku satu versitar. - Tanda tangan membuktikan siapa pembuatnya, bukan bahwa isinya bebas bug. Paket asli tetap bisa punya celah. Itu urusan tes dan review kode, bukan urusan verifikasi unduhan.
Setiap baris curl atau wget di script deploy yang langsung diikuti ekstrak atau eksekusi adalah tempat langkah 4 perlu dipasang.
Artikel terkait
Tulisan lain yang nyambung dengan topik ini.


Tanggal Kedaluwarsa di Botol Obat Bisa Menipu: Batas Pakai Setelah Dibuka Sering Jauh Lebih Pendek
Tanggal di botol obat berlaku selama segelnya utuh. Dari catatan obat di rumah kami, batas setelah dibuka bisa hanya sebulan padahal kemasannya sampai 2028.


Nomor Urut Kembar di Laravel: Kenapa Rule::unique Tidak Cukup dan Cara Membuatnya Aman dengan lockForUpdate
Dua pengguna mendapat nomor urut yang sama walaupun sudah ada Rule::unique dan unique index. Penyebabnya, demo MySQL, dan perbaikan dengan transaksi dan lockForUpdate.


Pengingat yang Mati Tidak Pernah Bilang "Saya Mati". Cara Supaya Kamu Tahu Lebih Cepat
Pengingat vitamin anak kami berhenti tiga hari tanpa ada yang sadar. Kenapa pengingat bisa mati diam-diam, dan lima kebiasaan supaya cepat ketahuan.
Comments
Komentar akan tampil setelah disetujui.