Back to IF4020 Kriptografi

Tanda-tangan Digital dengan Hash dan RSA

Questions/Cues

  • Mengapa tanda tangan digital biasanya memakai hash, bukan mengenkripsi seluruh pesan?
  • Bagaimana langkah signing dan verification dengan hash + RSA?
  • Bagaimana contoh numerik signature dan verifikasinya?
  • Apa saja algoritma tanda tangan digital standar (DSA, ElGamal, ECDSA)?
  • Bagaimana programnya di Python dan apa yang terjadi bila pesan diubah?

Reference Points

  • IF4020 Kriptografi — Tanda-tangan Digital (Slides 15-35)

Mengapa Kombinasi Hash + Kunci Publik?

Menandatangani dengan mengenkripsi seluruh pesan memberi dua fungsi: kerahasiaan dan otentikasi pengirim, tetapi tidak menjamin keaslian pesan. Sering kali otentikasi diperlukan tanpa kerahasiaan (pesan tidak rahasia). Untuk itu dipakai kombinasi fungsi hash dan kriptografi kunci publik: yang ditandatangani adalah message digest (kecil dan berukuran tetap), bukan seluruh pesan, sehingga jauh lebih cepat.

flowchart LR
    subgraph SG["Signer (Alice)"]
        direction LR
        M["Pesan M"] --> H1["Hash"] --> MD["digest h"]
        MD -->|"enkripsi dengan<br/>kunci privat Alice"| SIG["Signature S"]
    end
    subgraph VR["Verifier (Bob)"]
        direction LR
        MR["M + S diterima"] --> H2["Hash"] --> MD2["digest h (dihitung)"]
        MR --> DEC["dekripsi S dengan<br/>kunci publik Alice"] --> MD3["digest h'"]
        MD2 --> CMP{"h = h' ?"}
        MD3 --> CMP
    end
    SG -->|"M + S"| VR

Versi gambar lain (slide 17-18): Sender: pesan fungsi hash message digest enkripsi dengan kunci privat pengirim signed digest; signed digest digabung dengan pesan lalu dikirim. Receiver: pesan dihash menjadi message digest, sementara signed digest didekripsi dengan kunci publik pengirim menjadi message digest; keduanya dibandingkan (Compare) lalu keluar hasil “signature is valid or not”.

Algoritma Tanda Tangan Digital Standar

RSA signature, ElGamal signature (varian ElGamal khusus tanda tangan), DSA (Digital Signature Algorithm, standar NIST), dan ECDSA (Elliptic Curve DSA). Pada RSA, enkripsi dan dekripsi identik sehingga signing dan verifying juga identik.

Tanda Tangan Digital dengan RSA

Signing (pengirim):

  1. Hitung hash pesan: .
  2. Enkripsi dengan kunci privat () memakai persamaan RSA: ().
  3. Kirim .

Verifying (penerima):

  1. Hitung hash pesan yang diterima: .
  2. Dekripsi dengan kunci publik pengirim (): .
  3. Bandingkan: tanda tangan otentik; tidak sama tanda tangan/pesan tidak asli atau pengirim bukan yang dikira.

Contoh Numerik (dari slide)

(heks) (desimal). (), , .

  • Nilai yang dipakai: .
  • Signing: .
  • Verifying: .
  • () tanda tangan valid.

Pesan pada contoh ini berupa artikel pendek tentang wisudawan ITB termuda (“Pada wisuda sarjana baru ITB, … Kuliah di ITB selama empat tahun sehingga wajar saja menjadi sarjana pada umur 19 tahun”). Digest panjangnya 128 bit (32 digit heksa) sehingga dalam desimal () jauh lebih besar dari ; karena itu penerima membandingkan . Bob menerima (pesan dengan 46489 di bawahnya), menghitung ulang , lalu memeriksa bahwa : “Tanda tangan valid!”

Demo daring (slide 24-27): alat RSA Signature Generation and Validation (8gwifi.org) membangkitkan pasangan kunci (pilihan 512/1024/2048/4096 bit; contoh memakai 512 bit, format PEM). Pesan Selamat Hari Raya Idul Fitri 1445 H / Mohon maaf lahir dan batin menghasilkan signature Base64 (H4nhw0cj7ZPP7SvM2CaXVZmpVFEheobJTCpDUfZymTER+KiTt2mEUDvd6IzRWarqseC0Dc2Yj1RcxFnZ2pQqSg==, 64 byte = 512 bit); verifikasi: “Signature Verification Passed”. Setelah 1445 H diubah menjadi 1446 H dengan signature yang sama: “Signature Verification Failed”.

Slide juga memperlihatkan bahwa mengubah isi pesan sedikit saja (mis. 1445 H menjadi 1446 H) membuat hash berbeda dan verifikasi gagal.

Program Python (PyCryptodome)

Alur program (RSA 1024 bit, SHA-256, skema pkcs1_15):

key = RSA.generate(1024)                 # e = 65537
nilai_hash = SHA256.new(pesan.encode('utf-8'))
tanda_tangan = pkcs1_15.new(kunci_privat).sign(nilai_hash)      # signing
pkcs1_15.new(kunci_publik).verify(nilai_hash, tandatangan)      # verifying

verify melempar ValueError bila tidak cocok (dianggap tidak valid). Pada demo, pesan Guys, apakah kalian sudah membuat proposal Tugas Akhir? terverifikasi valid; setelah huruf pertama diganti * pesan menjadi *uys, apakah ... dan verifikasi tidak valid. Pada hasil jalannya, modulus berukuran 1024 bit (309 digit desimal), , dan signature ditampilkan dalam heksadesimal (34ba0e6e...5a5e206). Kunci disimpan format PEM (privat dilindungi password passwordku pada contoh).

Summary

Karena enkripsi pesan penuh tidak menjamin keaslian dan lambat, tanda tangan digital biasanya mengombinasikan fungsi hash dan kunci publik: pengirim menghitung , menandatangani digest dengan kunci privat ( pada RSA), dan mengirim ; penerima menghitung , mendekripsi dengan kunci publik (), dan membandingkan dengan : sama berarti otentik. Contoh slide: , , , , valid. Algoritma standar: RSA, ElGamal signature, DSA (NIST), ECDSA. Mengubah satu bit pesan membuat verifikasi gagal (terlihat pada program Python berbasis pkcs1_15 dan SHA-256).