---
# System prepended metadata

title: Modul 4 - Kriptografi

---

# Kriptografi

# Definisi

Kriptografi merupakan ilmu dan seni menyembunyikan informasi menggunakan teknik matematika dan algoritma untuk menjaga kerahasiaan, integritas, dan keaslian data (CIA Triad). Kriptografi memiliki satu tujuan utama - melindungi data dari akses tidak sah.

Kata kunci:
- Encryption / decryption (enkripsi / dekripsi)
- Cipher 
- Key (kunci)

# Tipe-tipe Enkripsi

**Symmetric (Simetris)**

Menggunakan kunci yang sama untuk enkripsi dan dekripsi.

Contoh algoritma: 

- AES (Advanced Encryption Standard)
- DES (Data Encryption Standard) - **insecure**

**Asymmetric (Asimetris)**

Menggunakan dua (pasangan) kunci: satu public key (kunci publik) untuk melakukan enkripsi dan satu private key (kunci privat) untuk melakukan dekripsi.

Contoh algoritma: 
- RSA (Rivest-Shamir-Adleman)
- Diffie-Hellman
- ElGamal

**Elliptic Curve Cryptography (ECC)**

Varian dari kriptografi asimetris yang menggunakan sifat elliptic curve (kurva eliptis) untuk enkripsi.
Menawarkan keamanan yang setara dengan RSA tetapi dengan kunci yang lebih pendek.

Contoh algoritma:
- ECDH (Elliptic-curve Diffie–Hellman key agreement scheme)
- ECDSA (Elliptic Curve Digital Signature Algorithm)

**Hash Functions (Fungsi Hash)**

Mengubah data menjadi nilai tetap (hash) yang unik, tidak dapat dikembalikan ke bentuk asli atau bersifat satu arah.

Contoh algoritma: 
- MD5 - **insecure**
- SHA-1 - **insecure**
- SHA-256

# Encoding / Decoding

Dalam komputer, encoding adalah proses menempatkan urutan karakter (huruf, angka, tanda baca, dan simbol tertentu) ke dalam format khusus untuk transmisi atau penyimpanan yang efisien. Decoding adalah proses kebalikannya - konversi format yang disandikan kembali ke urutan karakter asli.

## Basic Encoding 

Karena cryptosystem seperti RSA bekerja pada angka, namun sebuah pesan seperti kalian tahu biasanya ditulis dengan karakter. Sehingga, digunakan encoding/decoding untuk mendapat bytes yang dapat digunakan dalam operasi cryptography.

**Bytes**

Byte adalah satuan informasi digital yang umumnya terdiri dari delapan bit.

`1 byte (B) = 8 bit (bit)`

**ASCII**

ASCII merupakan standar kode yang digunakan untuk menulis karakter yang sedang kalian baca sekarang ini. Representasi **bytes** dalam `python` secara default menggunakan ASCII/UTF-8.

![Ascii Example](https://files.catbox.moe/6ypobo.png)

**Base**

Semua angka memiliki basis, contohnya base-10 (decimal), base-16 (hexadecimal), bahkan terdapat base-64 yang menggunakan berbagai macam simbol.

![Base64](https://files.catbox.moe/amhwla.png)

Tool [CyberChef](https://gchq.github.io/CyberChef/) bisa digunakan untuk berbagai macam encoding dan juga cryptosystem nantinya.

![CyberChef](https://files.catbox.moe/esxcyy.png)

# Penggunaan Python

Umumnya, untuk melakukan hal-hal terkait kriptografi, dilakukan melalui scripting dengan **Python**. Berbagai bagian dari kriptografi, misal encoding, pembuatan public key, memerlukan sebuah library yang bernama `PyCryptodome`. Library ini penuh dengan fitur yang dibutuhkan untuk seluruh materi yang akan disampaikan.

`pip install pycryptodome`

# Classical / Basic Ciphers

**Caesar Cipher**

Metode enkripsi substitusi sederhana di mana setiap huruf dalam teks digeser sejumlah posisi tertentu dalam alfabet. Ini merupakan cipher monoalphabetic substitution yang paling sederhana.

Contoh: 

`Shift` = 3
- A -> D (1 -> 4)
- F -> I (6 -> 9)
- Z -> C (26 -> 29 mod 26 -> 3)

`Shift` = -9
- A -> R (1 -> -8 mod 26 -> 18)
- F -> W (6 -> -3 mod 26 -> 23)
- Z -> Q (26 -> 17)

**Vigenère Cipher**

Metode enkripsi substitusi polialphabetic (polyalphabetic substitution) yang menggunakan serangkaian Caesar cipher berdasarkan huruf-huruf kunci. Ini lebih kuat dari Caesar cipher karena menggunakan huruf kunci yang berbeda untuk setiap huruf.

![Vigenere](https://cdn.britannica.com/50/7850-050-219843C0/letter-plaintext-table-Vigenere-cipher-intersection-row.jpg)

**XOR**

Menggunakan operasi XOR (exclusive OR) antara plaintext dan kunci.

Prinsip kerja: jika bit yang sama, hasilnya 0; jika bit berbeda, hasilnya 1. Operasi yang sama digunakan untuk enkripsi dan dekripsi.

Contoh XOR:
- Plaintext: 01001101 (pt)
- Key: 11001010 (k)
- Hasil XOR: 10000111 (ct)

Untuk mendekripsi, XOR kembali hasil dengan kunci yang sama:
- Ciphertext: 10000111 (ct)
- Key: 11001010 (k)
- Hasil XOR: 01001101 (pt)

![XOR](https://user-images.githubusercontent.com/4745789/85919742-d1520600-b88b-11ea-8d71-aa36c58dc48a.png)

**Contoh XOR Cipher (Sederhana):**

```python
def xor_encrypt_decrypt(plaintext, key):
    # Mengulang kunci agar panjangnya sama dengan plaintext
    key_repeated = (key * (len(plaintext) // len(key) + 1))[:len(plaintext)]
    
    # Melakukan operasi XOR
    result = ''.join(chr(ord(p) ^ ord(k)) for p, k in zip(plaintext, key_repeated))
    return result

# Input
pt = 'Institut Teknologi Sepuluh Nopember'
key = 'kripto'

# Enkripsi
ciphertext = xor_encrypt_decrypt(pt, key)
print(f"Ciphertext (XOR, hex): {ciphertext.encode().hex()}")

# Dekripsi (XOR dengan kunci yang sama)
decrypted = xor_encrypt_decrypt(ciphertext, key)
print(f"Decrypted: {decrypted}")
```

Output:
```
Ciphertext (XOR, hex): 221c1a041d1b1e0649241104051d051f13064b210c0001031e1a493e1b1f0e1f0b1506
Decrypted: Institut Teknologi Sepuluh Nopember
```

# Symmetric Ciphers

Enkripsi simetris, atau disebut juga sebagai enkripsi kunci-rahasia, menggunakan kunci yang sama untuk mengenkripsi dan mendekripsi data. Keuntungan utama enkripsi simetris adalah kecepatan dan efisiensi, terutama untuk enkripsi data dalam jumlah besar.

## Advanced Encryption Standard (AES)

AES adalah algoritma enkripsi simetris yang menjadi standar global untuk enkripsi data. Dikembangkan oleh Vincent Rijmen dan Joan Daemen, AES menggantikan DES yang tidak lagi aman.

**Karakteristik AES:**
- Ukuran blok selalu 128 bit (16 byte)
- Ukuran kunci: 128, 192, atau 256 bit
- Tidak rentan terhadap serangan kriptanalisis praktis

**Cara Kerja AES:**

1. **Key Expansion:**
   - Kunci utama diubah menjadi beberapa sub-kunci (round keys)
   - Setiap putaran enkripsi menggunakan sub-kunci yang berbeda

2. **Tahapan dalam Enkripsi AES:**

![AES](https://www.researchgate.net/profile/Isaac-Nti-3/publication/317594840/figure/fig8/AS:661429896105985@1534708584339/Overall-Structure-of-AES-Algorithm-Source.png)

   - **AddRoundKey:** XOR antara state dan round key
   - **SubBytes:** Substitusi byte menggunakan S-box
   - **ShiftRows:** Rotasi byte dalam baris
   - **MixColumns:** Operasi aljabar linier pada kolom

3. **Mode Operasi AES:**

![AES modes](https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/BlockCipherModesofOperation.svg/1920px-BlockCipherModesofOperation.svg.png)

   a. **ECB (Electronic Codebook):**
      - Setiap blok dienkripsi secara terpisah dengan kunci yang sama
      - Lemah: Blok plaintext identik menghasilkan ciphertext identik
      - **Tidak direkomendasikan** untuk kebanyakan penggunaan

   b. **CBC (Cipher Block Chaining):**
      - Setiap blok plaintext di-XOR dengan ciphertext blok sebelumnya
      - Membutuhkan IV (Initialization Vector) unik untuk blok pertama
      - Kesalahan merambat: Kerusakan pada satu blok mempengaruhi blok berikutnya

   c. **CTR (Counter):**
      - Mengenkripsi nilai counter bukan plaintext
      - Hasil enkripsi counter di-XOR dengan plaintext
      - Memungkinkan enkripsi paralel dan akses acak
      - Tidak ada masalah perambatan kesalahan

   d. **GCM (Galois/Counter Mode):**
      - Mode operasi yang menyediakan enkripsi dan autentikasi
      - Menggunakan CTR untuk enkripsi
      - Menambahkan GMAC untuk autentikasi
      - Sangat efisien dan populer untuk komunikasi aman

> Demonstrasi AES
> https://legacy.cryptool.org/en/cto/aes-animation

**Contoh Kode AES dalam Python:**

```python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
import base64

# Input
pt = 'Institut Teknologi Sepuluh Nopember'
key = 'kripto'  # Kunci harus 16, 24, atau 32 byte untuk AES-128, AES-192, atau AES-256

# Persiapan
key = key.encode('utf-8')
key = pad(key, AES.block_size)[:16]  # Menggunakan 16 byte (AES-128)
iv = get_random_bytes(AES.block_size)  # Inisialisasi vektor (IV) untuk CBC mode
print(f"Key (AES-128): {key}")
print(f"IV (AES-CBC): {iv}")

# Enkripsi
cipher = AES.new(key, AES.MODE_CBC, iv)
ct_bytes = cipher.encrypt(pad(pt.encode('utf-8'), AES.block_size))
ct = base64.b64encode(ct_bytes).decode('utf-8')
print(f"Ciphertext (AES-CBC): {ct}")

# Dekripsi
cipher = AES.new(key, AES.MODE_CBC, iv)
pt_bytes = unpad(cipher.decrypt(base64.b64decode(ct)), AES.block_size)
decrypted_pt = pt_bytes.decode('utf-8')
print(f"Decrypted: {decrypted_pt}")
```

Output:
```
Ciphertext (AES-CBC): VC9zG1H04xLfWiWDz/msHCVgAZget4gMYNuruH/JLP8DVKxwz3adsdNVboJVD6Mi
Decrypted: Institut Teknologi Sepuluh Nopember
```

### Attacks

> AES yang paling umum dipakai, AES-CBC sudah sangat aman dari serangan untuk mendapatkan plaintext. Tetapi, terkadang developer memiliki kesalahan implementasi yang pada akhirnya, bisa dieksploitasi. Mode AES yang lain juga memiliki kerentanan/vulnerability yang spesifik.

**Lebih lengkapnya bisa cek: https://github.com/jvdsn/crypto-attacks/tree/master**

## Algoritma Lainnya

1. **DES (Data Encryption Standard):**
   - Ukuran kunci 56-bit (terlalu kecil untuk keamanan modern)
   - Struktur Feistel dengan 16 putaran
   - **Tidak aman** untuk penggunaan saat ini

2. **3DES (Triple DES):**
   - Menerapkan DES tiga kali dengan 2-3
   - Lebih aman dari DES, tapi jauh lebih lambat dari AES
   - Sedang difase-out dalam banyak standar keamanan

3. **ChaCha20:**
   - Cipher aliran cepat
   - Sering digunakan dengan Poly1305 untuk autentikasi
   - Alternatif yang baik untuk AES pada perangkat dengan kemampuan komputasi terbatas

4. **Blowfish/Twofish:**
   - Blowfish: Cipher blok cepat dengan ukuran kunci variabel (didesain oleh Bruce Schneier)
   - Twofish: Finalis kompetisi AES, mendukung kunci hingga 256-bit

**Keuntungan Enkripsi Simetris:**
- Sangat cepat dibandingkan enkripsi asimetris
- Membutuhkan kunci yang lebih pendek untuk tingkat keamanan yang sama
- Efisien untuk enkripsi data dalam jumlah besar

**Kelemahan Enkripsi Simetris:**
- Masalah distribusi kunci: Bagaimana cara berbagi kunci secara aman?
- Membutuhkan kunci terpisah untuk setiap pasangan pengguna yang berkomunikasi
- Tidak menyediakan non-repudiation (penyangkalan) seperti enkripsi asimetris

# Asymmetric Ciphers

Enkripsi asimetris, atau disebut juga enkripsi kunci-publik, menggunakan pasangan kunci: kunci publik untuk enkripsi dan kunci privat untuk dekripsi. Berbeda dengan enkripsi simetris, pengirim dan penerima tidak perlu berbagi kunci rahasia.

## RSA (Rivest-Shamir-Adleman)

RSA adalah algoritma enkripsi asimetris yang paling terkenal dan banyak digunakan. Keamanannya didasarkan pada kesulitan memfaktorkan bilangan hasil perkalian dua bilangan prima besar.

**Prinsip Kerja RSA:**

1. **Pembuatan Kunci:**
   - Pilih dua bilangan prima besar p dan q (biasanya ribuan digit)
   - Hitung n = p × q (modulus)
   - Hitung φ(n) = (p-1) × (q-1) (fungsi Euler's totient)
   - Pilih bilangan e (eksponen enkripsi) yang relatif prima dengan φ(n)
   - Hitung d (eksponen dekripsi) sehingga d × e ≡ 1 (mod φ(n))
   - Kunci publik: (n, e), Kunci privat: (n, d)

2. **Enkripsi:**
   - Konversi plaintext M menjadi nilai numerik m
   - Enkripsi: c = m^e mod n

3. **Dekripsi:**
   - Dekripsi: m = c^d mod n
   - Konversi nilai numerik m kembali ke plaintext M

> Demonstrasi RSA
> https://www.cryptool.org/en/cto/rsa-step-by-step/

**Contoh Kode RSA dalam Python:**

```python
from Crypto.Util.number import *

p = getPrime(512)
q = getPrime(512)
n = p * q
e = 65537
phi = (p - 1) * (q - 1)
d = inverse(e, phi)

pt = b'Institut Teknologi Sepuluh Nopember'
ct = pow(bytes_to_long(pt), e, n)

print(f'ct = {ct}')
print(f'n = {n}')
print(f'p = {p}')
```

```python
from Crypto.Util.number import *

ct = 2699239613457833832720319517158496328470134291465773134777456583411772501634237421060887346951258659031869803309488933169388122467249769310112393785522007670386264941939811138618847649481890919836258086845065584152125071494958443655210217986493354658057047982149383792274022397140604728555795729471443192180
n = 97532442693426020435820245243615769950487854865514509293964937492395294555185912917273730437233598628522375021623965082852471492487603048718239595923067399653488267500227449425675931999549154696040946450722844055333727071135081720509117600088436334765340245825825846539009457498856214666252503616653849419553
p = 9462753695092080742767955795250011811763326630113098906390560441958387110467306519218110160533664538732944765260309462266418088428819775351221902548838873

def main():
    q = n // p
    e = 65537
    phi = (p - 1) * (q - 1)
    d = inverse(e, phi)
    pt = long_to_bytes(pow(ct, d, n))
    print(f'pt = {pt}')

if __name__ == '__main__':
    main()
```

Menggunakan library:

```python
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64

# Input
pt = 'Institut Teknologi Sepuluh Nopember'

# Membuat pasangan kunci RSA
key = RSA.generate(2048)
private_key = key
public_key = key.publickey()

print(f"Modulus (n): {private_key.n}")
print(f"Public Exponent (e): {private_key.e}")
print(f"Private Exponent (d): {private_key.d}")

# Enkripsi (menggunakan kunci publik)
cipher = PKCS1_OAEP.new(public_key)
ct_bytes = cipher.encrypt(pt.encode('utf-8'))
ct = base64.b64encode(ct_bytes).decode('utf-8')
print(f"Ciphertext (RSA): {ct}")

# Dekripsi (menggunakan kunci private)
cipher = PKCS1_OAEP.new(private_key)
pt_bytes = cipher.decrypt(base64.b64decode(ct))
decrypted_pt = pt_bytes.decode('utf-8')
print(f"Decrypted: {decrypted_pt}")
```

Output:
```
Modulus (n): 279574690220906617981011290085460651454686148558520373043584...
Public Exponent (e): 65537
Private Exponent (d): 638535049634547999879829306665833069033405124892318...
Ciphertext (RSA): p2Yh75eAdkhpemB0nAbNZjlGrpZIf8Si4tVH2RtRu97UXrFctp5qi9TGj7CsHqXctQ9M8TbuUi...
Decrypted: Institut Teknologi Sepuluh Nopember
```

### Attacks

> RSA, jika sesuai guideline atau menggunakan library, sudah sangat aman di masa sekarang yang belum mempunyai quantum computing. Tetapi, semisal tidak sesuai guideline sedikit saja atau terdapat kesalahan implementasi, banyak attack yang bisa dipakai sesuai dengan misimplementasi RSA.

**Elementary Attacks**

- Common Modulus - Mendekripsi ciphertext ketika plaintext yang sama dienkripsi dua kali menggunakan modulus `n` yang sama tapi eksponen berbeda.
- Common Prime - Mendapatkan faktor dari modulus `n1` dan `n2` ketika keduanya memiliki faktor prima yang sama.

**Factorization**

- Fermat’s Factorization - Teknik untuk memfaktorkan modulus `n` ketika nilai `p` dan `q` berdekatan.
- Pollard Rho’s Factorization - Teknik untuk memfaktorkan `n` ketika faktor-faktornya `p` dan `q`, yang dimana `p-1` dan `q-1` memiliki pembagi prima yang sangat kecil.

**Advanced**

- Wiener’s Attack - Menggunakan continued fractions untuk mendapatkan nilai eksponen kunci dekripsi `d` ketika `d < N^0.25`.
- Boneh Durfee’s Attack - Extension dari Wiener’s attack, mendapatkan nilai eksponen kunci dekripsi d ketika d sedikit lebih besar dari `N^0.25`, tepatnya `d < N^0.292`.
- Coppersmith’s Attack - Menggunakan teorema Coppersmith untuk menyerang pesan stereotip dan memfaktorkan n dengan bit-bit tinggi yang sudah diketahui.
- Franklin Reiter’s Related Message Attack - Serangan untuk mendapatkan pesan-pesan terkait yang dienkripsi menggunakan modulus yang sama, atau yang sudah melalui transformasi linear.
- Hastad’s Broadcast Attack - Serangan untuk mendapatkan pesan yang disiarkan ke beberapa orang, dienkripsi menggunakan eksponen yang sama tapi modulus berbeda.

**Implementasi:**
- https://github.com/jvdsn/crypto-attacks/tree/master
- https://github.com/ashutosh1206/Crypton/

## Diffie-Hellman Key Exchange 

Diffie-Hellman bukan algoritma enkripsi, melainkan metode pertukaran kunci aman melalui saluran tidak aman. Keamanannya bergantung pada masalah logaritma diskrit.

**Cara Kerja Diffie-Hellman:**

1. **Inisialisasi:**
   - Alice dan Bob setuju pada dua angka publik: bilangan prima p dan basis g
   - g dan p tidak perlu dirahasiakan dan bisa diketahui oleh siapapun

2. **Pertukaran:**
   - Alice memilih bilangan rahasia a, menghitung A = g^a mod p, dan mengirim A ke Bob
   - Bob memilih bilangan rahasia b, menghitung B = g^b mod p, dan mengirim B ke Alice

3. **Penghitungan Kunci Bersama:**
   - Alice menghitung s = B^a mod p = (g^b mod p)^a mod p = g^(ab) mod p
   - Bob menghitung s = A^b mod p = (g^a mod p)^b mod p = g^(ab) mod p
   - Keduanya sekarang memiliki nilai rahasia yang sama (s)

4. **Keamanan:** 
   - Pengintip hanya bisa melihat g, p, A, dan B
   - Menemukan a atau b dari nilai tersebut membutuhkan penyelesaian masalah logaritma diskrit

**Contoh Diffie-Hellman Key Exchange:**

```python
from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.hazmat.primitives import serialization

# Membuat parameter Diffie-Hellman
parameters = dh.generate_parameters(generator=2, key_size=512)

# Membuat kunci untuk Alice dan Bob
alice_private_key = parameters.generate_private_key()
bob_private_key = parameters.generate_private_key()

# Pertukaran kunci publik (dalam praktik nyata, pertukaran ini melalui jaringan)
alice_public_key = alice_private_key.public_key()
bob_public_key = bob_private_key.public_key()

# Alice menghitung kunci rahasia bersama
alice_shared_key = alice_private_key.exchange(bob_public_key)
print(f"Alice's shared key: {alice_shared_key.hex()[:20]}...")

# Bob menghitung kunci rahasia bersama
bob_shared_key = bob_private_key.exchange(alice_public_key)
print(f"Bob's shared key: {bob_shared_key.hex()[:20]}...")

# Verifikasi bahwa keduanya mendapatkan kunci yang sama
print(f"Keys match: {alice_shared_key == bob_shared_key}")
```

Output:
```
Alice's shared key: 7dc4ba57b61f23d53f0a...
Bob's shared key: 7dc4ba57b61f23d53f0a...
Keys match: True
```

## Elliptic Curve Cryptography (ECC)

ECC adalah pendekatan kriptografi asimetris yang menggunakan matematika kurva eliptis. Dibandingkan RSA, ECC menawarkan keamanan setara dengan ukuran kunci yang jauh lebih kecil.

**Karakteristik ECC:**
- Kunci ECC 256-bit menawarkan keamanan setara dengan RSA 3072-bit
- Lebih efisien dalam komputasi dan bandwidth
- Ideal untuk perangkat dengan sumber daya terbatas

**Algoritma ECC Populer:**
- **ECDH (Elliptic Curve Diffie-Hellman):** Versi Diffie-Hellman berbasis kurva eliptis
- **ECDSA (Elliptic Curve Digital Signature Algorithm):** Algoritma tanda tangan digital
- **EdDSA (Edwards-curve Digital Signature Algorithm):** Varian tanda tangan digital ECC modern

**Keuntungan Enkripsi Asimetris:**
- Mengatasi masalah distribusi kunci pada enkripsi simetris
- Mendukung digital signatures (tanda tangan digital)
- Menyediakan non-repudiation (pengirim tidak dapat menyangkal pengiriman)

**Kelemahan Enkripsi Asimetris:**
- Jauh lebih lambat dibanding enkripsi simetris (tidak signifikan untuk data kecil)
- Membutuhkan kunci yang lebih panjang, kecuali memakai ECC
- Tidak praktis untuk enkripsi data dalam jumlah besar

**Enkripsi Hybrid**

Dalam praktiknya, sistem kriptografi modern sering menggunakan pendekatan hybrid:
- Enkripsi asimetris digunakan untuk pertukaran kunci sesi
- Kunci sesi kemudian digunakan dengan enkripsi simetris yang lebih cepat untuk data aktual
- Contoh: TLS/SSL menggunakan RSA atau ECDHE untuk pertukaran kunci, dan AES untuk enkripsi data

# Hash Functions

Fungsi hash adalah algoritma satu arah yang mengubah data input berukuran sembarang menjadi string output berukuran tetap, biasanya disebut sebagai nilai hash, digest, atau fingerprint. Tidak seperti enkripsi, proses hash tidak dapat dibalik (one-way function).

**Karakteristik Kunci Fungsi Hash:**

1. **Deterministic (Deterministik)**
   - Input yang sama akan selalu menghasilkan hash yang sama
   - Esensial untuk verifikasi data

2. **Fixed Output Length (Panjang Output Tetap)**
   - Output selalu memiliki panjang yang sama, terlepas dari ukuran input
   - Contoh: SHA-256 selalu menghasilkan output 256 bit

3. **Pre-image Resistance (Ketahanan Pre-image)**
   - Sulit secara komputasi untuk menemukan input dari hash yang diketahui
   - Jika H(x) = h, hampir tidak mungkin menemukan x hanya dari h

4. **Second Pre-image Resistance (Ketahanan Pre-image Kedua)**
   - Diberikan input x, sulit menemukan input y berbeda yang menghasilkan hash sama
   - Jika H(x) = h, hampir tidak mungkin menemukan y ≠ x di mana H(y) = h

5. **Collision Resistance (Ketahanan Tabrakan)**
   - Sulit menemukan dua input berbeda yang menghasilkan hash yang sama
   - Hampir tidak mungkin menemukan x dan y di mana x ≠ y dan H(x) = H(y)

6. **Avalanche Effect (Efek Avalanche)**
   - Perubahan kecil pada input menghasilkan perubahan besar pada output
   - Mengubah satu bit input seharusnya mengubah ~50% bit output

**Algoritma Hash Populer:**

1. **MD5 (Message Digest Algorithm 5)**
   - Menghasilkan hash 128-bit (16 byte / 32 karakter heksadesimal)
   - Dikembangkan oleh Ron Rivest pada tahun 1991
   - **Tidak aman lagi**: Kolisi dapat ditemukan dalam hitungan detik
   - Masih digunakan untuk checksum dan verifikasi integritas non-kriptografis

2. **SHA-1 (Secure Hash Algorithm 1)**
   - Menghasilkan hash 160-bit (20 byte / 40 karakter heksadesimal)
   - Dikembangkan oleh NSA
   - **Tidak aman lagi sejak 2017**: Google berhasil mendemonstrasikan kolisi praktis
   - Sebagian besar sistem telah migrasi ke SHA-2 atau SHA-3

3. **SHA-2 (Secure Hash Algorithm 2)**
   - Keluarga fungsi hash yang mencakup SHA-224, SHA-256, SHA-384, SHA-512
   - SHA-256: Menghasilkan hash 256-bit (32 byte / 64 karakter heksadesimal)
   - SHA-512: Menghasilkan hash 512-bit (64 byte / 128 karakter heksadesimal)
   - Standar industri saat ini untuk aplikasi keamanan

4. **SHA-3 (Secure Hash Algorithm 3)**
   - Sebelumnya dikenal sebagai Keccak, pemenang kompetisi NIST Hash Function
   - Didesain berbeda dari SHA-2 untuk diversifikasi kriptografis
   - Mendukung panjang output yang sama dengan SHA-2
   - Lebih tahan terhadap serangan side-channel dan quantum

5. **BLAKE2**
   - Lebih cepat dari MD5, SHA-1, SHA-2, dan SHA-3
   - Tersedia dalam varian BLAKE2b (untuk 64-bit) dan BLAKE2s (untuk 32-bit)
   - Keamanan sebanding dengan SHA-3
   - Populer di aplikasi yang membutuhkan kinerja tinggi

**Penggunaan Fungsi Hash:**

1. **Password Storage (Penyimpanan Password)**
   - Hash password sebelum disimpan dalam database
   - Menggunakan salt (nilai acak) untuk mencegah serangan rainbow table dan dictionary
   - Contoh: bcrypt, Argon2, PBKDF2

2. **Data Integrity (Integritas Data)**
   - Verifikasi bahwa data tidak berubah selama transmisi atau penyimpanan
   - Menghasilkan checksum untuk file untuk deteksi korupsi atau modifikasi

3. **Digital Signatures (Tanda Tangan Digital)**
   - Hash dokumen sebelum ditandatangani
   - Lebih efisien daripada menandatangani seluruh dokumen

4. **Proof of Work (Bukti Kerja)**
   - Digunakan dalam blockchain dan cryptocurrency
   - Bitcoin menggunakan SHA-256 dalam algoritma proof-of-work

5. **Derivasi Kunci**
   - Membuat kunci kriptografi dari password
   - HKDF (HMAC-based Key Derivation Function)

6. **Hash Tables**
   - Struktur data untuk penyimpanan dan akses cepat
   - Bukan untuk penggunaan kriptografis, tetapi menggunakan konsep yang sama

**Salting dan Key Stretching:**

1. **Salting**
   - Menambahkan nilai acak (salt) ke input sebelum hashing
   - Mencegah serangan precomputed table (rainbow tables)
   - Salt harus unik untuk setiap hash dan disimpan bersama hash

2. **Key Stretching**
   - Membuat proses hashing lebih lambat dan membutuhkan banyak sumber daya
   - Mencegah brute force dengan membuat serangan lebih mahal
   - Contoh: bcrypt, PBKDF2, Argon2

3. **Fungsi Hash Khusus Password**
   - **bcrypt:** Berdasarkan cipher Blowfish, menyediakan factor work yang dapat disesuaikan
   - **PBKDF2:** Password-Based Key Derivation Function 2, menggunakan iterasi HMAC
   - **Argon2:** Pemenang Password Hashing Competition (PHC) 2015, tahan terhadap serangan hardware

**Contoh Kode Hash dalam Python:**

```python
import hashlib
import hmac

# Input
pt = 'Institut Teknologi Sepuluh Nopember'
key = 'kripto'

# MD5 (tidak aman untuk penggunaan kriptografis)
md5_hash = hashlib.md5(pt.encode()).hexdigest()
print(f"MD5: {md5_hash}")

# SHA-1 (tidak direkomendasikan untuk penggunaan baru)
sha1_hash = hashlib.sha1(pt.encode()).hexdigest()
print(f"SHA-1: {sha1_hash}")

# SHA-256 (direkomendasikan)
sha256_hash = hashlib.sha256(pt.encode()).hexdigest()
print(f"SHA-256: {sha256_hash}")

# SHA-512 (lebih kuat)
sha512_hash = hashlib.sha512(pt.encode()).hexdigest()
print(f"SHA-512: {sha512_hash}")

# Contoh salting
salt = "garam_rahasia"
salted_input = pt + salt
sha256_salted = hashlib.sha256(salted_input.encode()).hexdigest()
print(f"SHA-256 dengan salt: {sha256_salted}")

# HMAC (Hash-based Message Authentication Code)
hmac_sha256 = hmac.new(key.encode(), pt.encode(), hashlib.sha256).hexdigest()
print(f"HMAC-SHA256: {hmac_sha256}")
```

Output:
```
MD5: 9fee4eca8227fa5700eda3c75c66ea25
SHA-1: e85c3f1dde4b2fe8841181e33642952a5c73151c
SHA-256: dc56d4b16655b69592a47f07ddb4f708561b12560cae8e7d22b6178a3d144e15
SHA-512: 62dc1b435fd032c12e066ed717fa918e9ceabc63d20a59c851d8a92ccbd867948b1161...
SHA-256 dengan salt: c474513a67428e8aff17a51bcc2a923c4b9201825d55e709ce688cfcc054c61b
HMAC-SHA256: 6b65bf69bc6fb03e70c3c4f143470010faed5c0c8e2857c8f5dce40597babbe1
```

**Contoh Verifikasi Integritas Data:**

```python
def verify_data_integrity(data, stored_hash):
    """Verifikasi integritas data dengan membandingkan hash."""
    calculated_hash = hashlib.sha256(data.encode()).hexdigest()
    if calculated_hash == stored_hash:
        return True, "Data tidak berubah"
    else:
        return False, "Integritas data rusak"

# Data asli dan hash tersimpan
original_data = 'Institut Teknologi Sepuluh Nopember'
stored_hash = hashlib.sha256(original_data.encode()).hexdigest()

# Kasus 1: Data tidak berubah
test_data1 = 'Institut Teknologi Sepuluh Nopember'
result1, message1 = verify_data_integrity(test_data1, stored_hash)
print(f"Kasus 1: {message1}")

# Kasus 2: Data berubah
test_data2 = 'Institut Teknologi Sepuluh November'
result2, message2 = verify_data_integrity(test_data2, stored_hash)
print(f"Kasus 2: {message2}")
```

Output:
```
Kasus 1: Data tidak berubah
Kasus 2: Integritas data rusak
```

## Hash Cracking

Hash Cracking adalah jenis serangan siber yang melibatkan proses memulihkan biasanya password dari data yang telah disimpan atau dikirim oleh sistem komputer dalam bentuk acak dengan memecahkan (atau berhasil menebak) password yang digunakan untuk melindungi akun-akun sensitif. Umumnya terdapat 2 cara untuk melakukan Password Cracking seperti tabel dibawah ini

| Brute Force Attack | Dictionary Attack | 
| :---: | :---: |
| Mencoba menebak kata sandi dengan mencoba secara sistematis setiap kombinasi karakter yang mungkin | Mencoba menebak kata sandi dengan mencoba secara sistematis setiap kata yang mungkin ada di dalam kamus |
| Lambat dan intensif secara komputasi | Cepat tetapi dibatasi oleh kata-kata dalam kamus |
| Dapat menebak kata sandi dengan panjang berapa pun | Biasanya terbatas pada kata sandi dengan panjang yang masuk akal |

Pada modul ini kita akan melakukan serangan yang berbasis _Dictionary Attack_. Di dalam Kali Linux, terdapat sebuah file yang disebut **rockyou.txt**. File ini sangat besar dan diisi baris per baris dengan password yang bocor dan disebarkan kepada publik yang pernah terjadi ini.

_Dictionary Attack_ akan mencoba meng-hash baris per baris dalam file tersebut (atau kita sebut dengan kamus/wordlist) dan akan membandingkannya dengan hash yang telah dibocorkan. Apabila hashnya sama maka password sebenarnya telah ditemukan.
<p align="center">
    <img src="https://github.com/lab-kcks/Modul_Ethical-Hacking/assets/106898320/c62401c8-9dc4-48bd-b739-723c9b944e9d" alt="" width=600>
</p>

terdapat banyak dictionary lain untuk kasus dan kegunaannya masing, diantara lain:
- [SecList](https://github.com/danielmiessler/SecLists)
- [Indonesian Wordlist](https://github.com/geovedi/indonesian-wordlist)
- etc...

### John the Ripper
John adalah command-line tool yang paling mudah digunakan dan ramah pemula untuk password cracking. Asumsikan kita memiliki file `hashes.txt` dengan konten sebagai berikut:
```bash
┌──(kali㉿kali)-[~/Documents/wiki]
└─$ cat hashes.txt 
MisterH:$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12
MyMom:$2a$12$SOn8Pf6z8fO/nVsNbAAequ/P6vLRJJl7gCUEiYBU2iLHn4G/p/Zw2
``` 

cara umum untuk crack password menggunakan john adalah seperti berikut, tanpa menspesifikasikan sebuah wordlist, john akan menggunakan dictionary defaultnya sendiri.
```bash
john <hash_file> 
```

untuk menggunakan dictionary khusus atau custom selain dictionary default john dapat dilakukan sebagai berikut
```bash
john <hash_file> --wordlist=/path/to/wordlist.txt
```

untuk menampilkan password dari hash yang berhasil di crack, dapat menggunakan perintah berikut
```bash
john --show <hash_file>
```

berikut contoh menggunakan file hash yang sebelumnya telah dicontohkan
```bash
┌──(kali㉿kali)-[~/Documents/wiki]
└─$ john hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (bcrypt [Blowfish 32/64 X3])
Remaining 1 password hash
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 6 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
spongebob1       (MyMom)     
1g 0:00:00:25 DONE (2024-04-23 13:03) 0.03974g/s 53.65p/s 53.65c/s 53.65C/s winston..eunice
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

┌──(kali㉿kali)-[~/Documents/wiki]
└─$ john --show hashes.txt                                     
MisterH:tequieromucho
MyMom:spongebob1

2 password hashes cracked, 0 left
```

gunakan `john -h` atau `man john` untuk detail lebih lanjut. Atau gunakan cheatsheet dibawah ini untuk kasus-kasus dimana john sering digunakan:

| Command | tldr; |
| :--- | :---- |
| `john path/to/hashes.txt` | Crack password hashes |
| `john --show path/to/hashes.tx`t | Show passwords cracked |
| `john --show --users=user_ids path/to/hashes1.txt path/to/hashes2.txt ...` | Display users' cracked passwords by user identifier from multiple files |
| `john --wordlist=path/to/wordlist.txt path/to/hashes.txt` | Crack password hashes, using a custom wordlist |
| `john --list=formats` | List available hash formats |
| `john --format=md5crypt path/to/hashes.txt` | Crack password hashes, using a specific hash format |
| `john --rules path/to/hashes.txt` | Crack password hashes, enabling word mangling rules |
| `john --restore=path/to/mycrack.rec` | Restore an interrupted cracking session from a state file, e.g. mycrack.rec |

### Hashcat
Hashcat adalah alternatif lain untuk tool cracking password. Hashcat sendiri menawarkan fitur yang lebih advanced dan mungkin saja tidak ramah untuk pemula. 

cara umum untuk crack password menggunakan Hashcat adalah seperti berikut
```bash
hashcat -a <attack mode> -m <hash type> <hash file> <wordlist>
```

`attack mode` adalah jenis serangan yang akan dipakai.
| # | Mode |
| :--: | :-- |
| 0 | Straight |
| 1 | Combination |
| 3 | Brute-force |
| 6 | Hybrid Wordlist + Mask |
| 7 | Hybrid Mask + Wordlist |
| 9 | Association |

`hash type` adalah jenis hash yang dicoba untuk di crack. tanpa menspesifikan hash type, Hashcat akan mencoba menentukan tipe hash secara otomatis, namun hal ini tidak akan selalu berhasil. hash type serta contohnya hashnya dapat dilihat pada [hashcat examples](https://hashcat.net/wiki/doku.php?id=example_hashes).

Dalam contoh ini kita akan menggunakan jenis hash tipe NetNTLMv2 yang dipakai oleh Windows dan Active Directory.
```
┌──(kali㉿kali)-[~/Documents/wiki]
└─$ cat NetNTLMv2.txt   
Administrator::WIN-487IMQOIA8E:997b18cc61099ba2:3CC46296B0CCFC7A231D918AE1DAE521:0101000000000000B09B51939BA6D40140C54ED46AD58E890000000002000E004E004F004D00410054004300480001000A0053004D0042003100320004000A0053004D0042003100320003000A0053004D0042003100320005000A0053004D0042003100320008003000300000000000000000000000003000004289286EDA193B087E214F3E16E2BE88FEC5D9FF73197456C9A6861FF5B5D3330000000000000000
```

Berikut contoh penggunaan untuk hashcat untuk crash password diatas:
```bash
┌──(kali㉿kali)-[~/Documents/wiki]
└─$ hashcat -a 0 -m 5600 NetNTLMv2.txt /usr/share/wordlists/rockyou.txt 
hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 3.1+debian  Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: pthread-sandybridge-AMD Ryzen 5 5600H with Radeon Graphics, 5613/11290 MB (2048 MB allocatable), 6MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Not-Iterated
* Single-Hash
* Single-Salt

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.
See the above message to find out about the exact limits.

Watchdog: Temperature abort trigger set to 90c

Host memory required for this attack: 1 MB

Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385

ADMINISTRATOR::WIN-487IMQOIA8E:997b18cc61099ba2:3cc46296b0ccfc7a231d918ae1dae521:0101000000000000b09b51939ba6d40140c54ed46ad58e890000000002000e004e004f004d00410054004300480001000a0053004d0042003100320004000a0053004d0042003100320003000a0053004d0042003100320005000a0053004d0042003100320008003000300000000000000000000000003000004289286eda193b087e214f3e16e2be88fec5d9ff73197456c9a6861ff5b5d3330000000000000000:P@ssword
                                                          
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 5600 (NetNTLMv2)
Hash.Target......: ADMINISTRATOR::WIN-487IMQOIA8E:997b18cc61099ba2:3cc...000000
Time.Started.....: Tue Apr 23 13:24:28 2024 (1 sec)
Time.Estimated...: Tue Apr 23 13:24:29 2024 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  1686.5 kH/s (2.33ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 79872/14344385 (0.56%)
Rejected.........: 0/79872 (0.00%)
Restore.Point....: 73728/14344385 (0.51%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#1....: compu -> Bulldog
Hardware.Mon.#1..: Util: 21%

Started: Tue Apr 23 13:24:28 2024
Stopped: Tue Apr 23 13:24:31 2024
```

gunakan `hashcat -h` atau `man hashcat` untuk detail lebih lanjut. Atau gunakan cheatsheet dibawah ini untuk kasus-kasus dimana hashcat sering digunakan:

| Command | tldr; |
| :--- | :---- |
| `hashcat --hash-type hash_type_id --attack-mode 3 hash_value` | Perform a brute-force attack (mode 3) with the default hashcat mask |
| `hashcat --hash-type hash_type_id --attack-mode 3 hash_value "?d?d?d?d"` | Perform a brute-force attack (mode 3) with a known pattern of 4 digits|
| `hashcat --hash-type hash_type_id --attack-mode 3 --increment hash_value "?a?a?a?a?a?a?a?a"` | Perform a brute-force attack (mode 3) using at most 8 of all printable ASCII characters |
| `hashcat --hash-type hash_type_id --attack-mode 0 hash_value /usr/share/wordlists/rockyou.txt` | Perform a dictionary attack (mode 0) using the RockYou wordlist of a Kali Linux box |
| `hashcat --hash-type hash_type_id --attack-mode 0 --rules-file /usr/share/hashcat/rules/best64.rule hash_value /usr/share/wordlists/rockyou.txt` | Perform a rule-based dictionary attack (mode 0) using the RockYou wordlist mutated with common password variations |
| `hashcat --hash-type hash_type_id --attack-mode 1 hash_value /path/to/dictionary1.txt /path/to/dictionary2.txt` | Perform a combination attack (mode 1) using the concatenation of words from two different custom dictionaries |
| `hashcat --show hash_value` | Show result of an already cracked hash |
| `hashcat --example-hashes` | Show all example hashes | 

# Referensi

- https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
- https://cryptohack.org/
- https://book.jorianwoltjer.com/cryptography/
- https://github.com/ashutosh1206/Crypton/
- https://cryptohack.gitbook.io/cryptobook
- https://github.com/jvdsn/crypto-attacks/tree/master