Kembali ke jurnalCATATAN FAJAR
Cryptography4 menit baca

[Crypto: age] scrypt, Dari Password ke Key

Pelajari gimana scrypt menurunkan wrapping key age, kenapa setiap percobaan memakai waktu dan memory, dan apa yang nggak bisa dicegah kalkulasi lambat.

BAGIAN 3 DARI 6Crypto: age
  1. 01[Crypto: age] Dari Password ke Ciphertext
  2. 02[Crypto: age] Membaca Header
  3. 03[Crypto: age] scrypt, Dari Password ke KeyKamu di sini
  4. 04[Crypto: age] ChaCha20-Poly1305, Menyegel Isi File
  5. 05[Crypto: age] Passphrase atau Key Pair
  6. 06[Crypto: age] Berapa Lama Serangan Passphrase Berlangsung?
Di artikel ini 5 bagian

age pakai scrypt untuk menurunkan key dari passphrase. Key derivation function adalah algoritma yang menghitung key dari nilai-nilai input lain. Setiap operasi scrypt memakai waktu dan memory.

Post header menunjukkan sebuah salt dan sebuah work factor. Bersama passphrase, nilai-nilai itu memungkinkan scrypt menghasilkan wrapping key yang sama saat enkripsi dan dekripsi.

Key yang lebih panjang nggak bikin passphrase lebih sulit ditebak

Algoritma enkripsi memakai key dengan ukuran tetap. Passphrase bisa punya panjang yang berbeda-beda. scrypt mengubah passphrase jadi key dengan ukuran tersebut.

Konversi ini nggak menambahkan pilihan acak ke passphrase. Kalau penyerang mencoba passphrase yang benar, scrypt menghasilkan key yang benar. Password yang umum tetap mudah ditebak walaupun key hasil turunannya berukuran 32 byte.

Biaya yang berguna adalah kerja untuk setiap percobaan. Pemiliknya biasanya menurunkan key sekali untuk mendekripsi file. Penyerang harus mengulang kalkulasi itu untuk setiap kandidat passphrase.

Parameter di file age

Untuk header contoh, work factor yang tersimpan adalah 18. age menginterpretasikannya sebagai N = 2^18, atau 262.144.

Pseudocode ini menunjukkan input-nya. Ini rumus, bukan command:

text
wrapping key = scrypt(
    passphrase = user input,
    salt = "age-encryption.org/v1/scrypt" followed by the 16 salt bytes,
    N = 262144,
    r = 8,
    p = 1,
    output length = 32 bytes
)
ParameterArti di contoh ini
NCost parameter utama
rParameter block size, tetap di 8
pParameter paralelisasi, tetap di 1
SaltLabel age yang tetap, diikuti salt acak dari header
Panjang output32 byte untuk wrapping key

Label yang tetap ini memisahkan pemakaian scrypt di sini dari pemakaian dengan label yang berbeda. Salt acak juga membuat kalkulasinya spesifik untuk file ini. Kedua nilai itu bukan rahasia.

Implementasi age 1.3.1 memakai parameter-parameter ini dan default-nya work factor 18. Format-nya mengizinkan work factor lain. Jadi, nilai di header penting waktu age mendekripsi file.

Kenapa satu percobaan memakai sekitar 256 MiB

scrypt memakai area memory yang besar selama kalkulasinya. Area memory utamanya berukuran kira-kira 128 × N × r byte.

Untuk contoh ini:

text
128 × 262144 × 8 = 268435456 bytes = 256 MiB

MiB artinya mebibyte. Satu MiB adalah 1.048.576 byte. GiB artinya gibibyte. Satu GiB adalah 1.024 MiB. Program ini juga memakai sebagian memory di luar area utama ini.

Sepuluh percobaan dalam waktu bersamaan memakai sekitar 2,5 GiB untuk area memory utamanya. Kebutuhan ini bikin serangan paralel berskala besar jadi lebih mahal. Kapasitas memory membatasi berapa banyak percobaan yang muat sekaligus. Memory bandwidth membatasi seberapa cepat hardware bisa memindahkan data.

Batasan-batasan ini nggak mencegah serangan. Pilihan hardware dan implementasi memengaruhi lajunya. Beberapa implementasi mengorbankan lebih banyak kerja kalkulasi demi memory yang lebih sedikit. Spesifikasi scrypt menjelaskan algoritma dan parameternya.

Mengukur scrypt di komputer kamu

Pengukuran awal memakai Apple M5 dan hashlib.scrypt dari Python. Pengukuran itu mencatat sekitar 0,3701 detik untuk setiap kalkulasi, atau 2,70 kalkulasi per detik. Angka-angka itu berlaku untuk pengukuran tersebut. Komputer lain bisa memberikan hasil yang berbeda.

Contoh Python ini cuma mengukur scrypt. Contoh ini nggak mendekripsi file age atau menguji authentication tag. Salt-nya menyertakan label age yang dipakai di format file.

Pakai Python 3 yang mendukung hashlib.scrypt. Pastikan memory yang tersedia lebih dari 256 MiB. Dokumentasi Python menjelaskan parameter function-nya.

  1. Simpan kode ini di file baru bernama measure_scrypt.py:

    python
    import hashlib
    import os
    import time
    
    cost = 1 << 18
    block_size = 8
    parallelism = 1
    main_memory = 128 * cost * block_size
    salt = b"age-encryption.org/v1/scrypt" + os.urandom(16)
    
    def derive_key(passphrase):
        return hashlib.scrypt(
            passphrase,
            salt=salt,
            n=cost,
            r=block_size,
            p=parallelism,
            dklen=32,
            # Permit memory for internal work outside the main area.
            maxmem=main_memory + (64 << 20),
        )
    
    # Exclude the initial call from the measured calls.
    derive_key(b"warmup")
    attempts = 8
    start = time.perf_counter()
    for index in range(attempts):
        derive_key(f"guess{index}".encode("ascii"))
    elapsed = time.perf_counter() - start
    
    print("seconds per calculation:", round(elapsed / attempts, 4))
    print("calculations per second:", round(attempts / elapsed, 2))
    
  2. Jalankan file-nya:

    bash
    python3 measure_scrypt.py
    

Angka output pertama adalah rata-rata waktu untuk satu kalkulasi. Angka kedua adalah jumlah kalkulasi per detik. Hasil kamu bisa berbeda tergantung kecepatan prosesor, memory, versi Python, dan program lain yang sedang jalan.

Apa yang berubah dengan work factor yang lebih tinggi

Kenaikan dari 18 ke 19 bikin N jadi dua kali lipat. Area memory utama naik dari 256 MiB jadi 512 MiB. Di work factor 20, ukurannya naik jadi 1 GiB.

Waktunya biasanya ikut naik juga, tapi kamu harus mengukurnya untuk mendapat hasil yang akurat. Work factor yang lebih besar juga menaikkan biaya dekripsi yang sah.

Kalkulasi yang lambat nggak bisa menutupi passphrase yang mudah ditebak. Kalau passphrase yang benar adalah kandidat pertama, cuma butuh satu percobaan. Pemilihan acak dari kumpulan yang besar menaikkan jumlah percobaan yang diharapkan dalam exhaustive search.

Post waktu serangan menghitung perbedaan ini. Sebelum itu, post berikutnya mengikuti wrapping key sampai ke file key terenkripsi dan payload.

TOPIK

SELANJUTNYA DI SERI INI[Crypto: age] ChaCha20-Poly1305, Menyegel Isi File

MAKASIH UDAH BACA

Gimana menurutmu?

Reaksi atau obrolan, dua-duanya selalu ditunggu.

Memuat reaksi…

Bagikan

Memuat komentar...

LANJUT JELAJAH

Satu pikiran bawa ke pikiran lain.

Semua tulisan
Kembali ke semua tulisanSatu catatan, pelan-pelan.