Skip to content

ALIF101XL/CryptoToolkit

Repository files navigation

CryptoMultifungsi - Program Enkripsi Multi-Algoritma

📋 Daftar Isi


🎯 Deskripsi

CryptoMultifungsi adalah aplikasi Python berbasis CLI (Command Line Interface) yang menyediakan implementasi berbagai algoritma kriptografi modern. Program ini dirancang untuk kebutuhan enkripsi data, hashing password, dan verifikasi integritas data dengan antarmuka yang user-friendly.

Aplikasi ini menggunakan library cryptography yang teruji dan bcrypt untuk password hashing, memastikan implementasi yang aman dan sesuai standar industri.


✨ Fitur

Fitur Tipe Keterangan
Fernet Enkripsi Simetris Enkripsi symmetric key dengan format yang aman
RSA Enkripsi Asimetris Public-key cryptography dengan key size 2048-bit
SHA-256 Hash Function Menghasilkan message digest 256-bit
HMAC Message Authentication Verifikasi integritas dan autentikasi pesan
bcrypt Password Hash Hashing password dengan salt untuk keamanan maksimal

📦 Requirements

  • Python 3.7+
  • Library:
    • cryptography >= 41.0.0
    • bcrypt >= 4.0.0

🔧 Instalasi

1. Clone atau Download Repository

git clone https://github.com/ALIF101XL/CryptoToolkit.git
cd CryptoToolkit && chmod 755 *.py

2. Install Dependencies

pip install -r requirements.txt

Atau manual install:

pip install cryptography bcrypt

3. Verifikasi Instalasi

python crypto_multifungsi.py

Jika berhasil, akan muncul menu utama program.


🚀 Cara Penggunaan

Menjalankan Program

python crypto_multifungsi.py

Menu Utama

=== CRYPTO MULTIFUNGSI ===
1. Fernet (Simetris)
2. RSA (Asimetris)
3. SHA-256 Hash
4. HMAC
5. Password Hash (bcrypt)
6. Keluar

Pilih menu (1-6): 

Alur Penggunaan Umum

1️⃣ Fernet (Enkripsi Simetris)

Pilih menu: 1
--- FERNET ---
1. Generate Key
2. Enkripsi
3. Deskripsi
Pilih: 1

Langkah:

  • Generate Key → Simpan key dengan aman
  • Gunakan key tersebut untuk enkripsi
  • Gunakan key yang sama untuk dekripsi

2️⃣ RSA (Enkripsi Asimetris)

Pilih menu: 2
--- RSA ---
1. Generate Key Pair
2. Enkripsi
3. Deskripsi
Pilih: 1

Langkah:

  • Generate Key Pair (private & public key)
  • Gunakan public key untuk enkripsi
  • Gunakan private key untuk dekripsi

3️⃣ SHA-256 Hash

Pilih menu: 3
--- SHA-256 ---
Masukkan pesan: hello world
Hash SHA-256: a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192145447

4️⃣ HMAC

Pilih menu: 4
--- HMAC ---
Masukkan pesan: hello world
Masukkan kunci HMAC: secret_key
HMAC: 8b1a9953c4611296aed9e1fe...

5️⃣ Password Hash (bcrypt)

Pilih menu: 5
--- PASSWORD HASH ---
1. Hash Password
2. Verifikasi Password
Pilih: 1
Masukkan password: MySecurePass123!
Hashed password: b'$2b$12$...'

🔐 Penjelasan Algoritma

1. Fernet (Enkripsi Simetris)

Definisi: Enkripsi simetris yang menggunakan kunci yang sama untuk enkripsi dan dekripsi.

Karakteristik:

  • Key Size: 256-bit
  • Algoritma Dasar: AES-128 dalam mode CBC
  • Timestamp: Includes timestamp dalam ciphertext (proteksi replay attack)
  • Kecepatan: Sangat cepat
  • Use Case: Enkripsi file, database, cookies

Keuntungan: ✅ Cepat dan efisien ✅ Built-in integrity checking ✅ Format standar dan aman

Kelemahan: ❌ Key harus dijaga rahasia ❌ Sulit untuk key distribution

Contoh Implementasi:

from cryptography.fernet import Fernet

# Generate key
key = Fernet.generate_key()
cipher = Fernet(key)

# Encrypt
ciphertext = cipher.encrypt(b"secret message")

# Decrypt
plaintext = cipher.decrypt(ciphertext)

2. RSA (Enkripsi Asimetris)

Definisi: Enkripsi public-key cryptography dengan dua kunci berbeda (public & private).

Karakteristik:

  • Key Size: 2048-bit (industry standard)
  • Public Exponent: 65537 (standard)
  • Padding: OAEP (Optimal Asymmetric Encryption Padding)
  • Hash Algorithm: SHA-256
  • Kecepatan: Lebih lambat dari simetris
  • Use Case: Digital signature, key distribution, secure communication

Keuntungan: ✅ Public key dapat dibagikan ✅ Tidak perlu pre-shared secret ✅ Cocok untuk multiple recipients

Kelemahan: ❌ Lebih lambat ❌ Key size lebih besar ❌ Hanya cocok untuk data kecil (<245 bytes untuk RSA-2048)

Contoh Implementasi:

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes

# Generate keys
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048
)
public_key = private_key.public_key()

# Encrypt dengan public key
ciphertext = public_key.encrypt(
    b"secret",
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

# Decrypt dengan private key
plaintext = private_key.decrypt(ciphertext, padding.OAEP(...))

3. SHA-256 (Cryptographic Hash)

Definisi: One-way hash function yang menghasilkan fixed-size output (256-bit).

Karakteristik:

  • Output Size: 256-bit (64 karakter hex)
  • One-Way: Tidak dapat di-reverse
  • Collision Resistant: Sangat sulit menemukan 2 input dengan hash sama
  • Deterministic: Input sama selalu menghasilkan output sama
  • Sensitivity: Kecil perubahan input = besar perubahan output (avalanche effect)

Use Case:

  • File integrity verification
  • Digital signature
  • Blockchain (Bitcoin)
  • Password storage (jika dikombinasi dengan salt)

Tidak Cocok Untuk: ❌ Password hashing (gunakan bcrypt/argon2) ❌ Reverse engineering (bukan encryption)

Contoh:

Input: "hello"
Output: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Input: "hello1"
Output: ce06092fb48d9ffac7d1a376e404b26b7575bcc11ee05a4615feda8f553cc8e4

4. HMAC (Hash-Based Message Authentication Code)

Definisi: Kombinasi hash function dengan secret key untuk verifikasi integritas dan autentikasi.

Karakteristik:

  • Secret Key: Diperlukan untuk generate dan verify HMAC
  • Algorithm: SHA-256
  • Verifikasi: Sender & receiver harus tahu key yang sama
  • Use Case: API authentication, message verification, session tokens

Keuntungan: ✅ Proteksi terhadap tampering ✅ Autentikasi pesan ✅ Lebih aman dari plain hash

Contoh Alur:

Pengirim:
message = "transaction data"
key = "secret_key"
hmac = HMAC(message, key)
kirim: message + hmac

Penerima:
terima: message + hmac
hitung: expected_hmac = HMAC(message, key)
if received_hmac == expected_hmac:
    ✅ Pesan authentic & tidak diubah
else:
    ❌ Pesan dipalsukan atau diubah

5. bcrypt (Password Hashing)

Definisi: Algorithm khusus password hashing dengan built-in salt dan adaptive cost factor.

Karakteristik:

  • Salt: Generated otomatis & random setiap hash
  • Work Factor: Dapat ditingkatkan seiring waktu
  • Algorithm: Blowfish cipher derivative
  • Output Format: $2b$cost$salt$hash
  • Resistant: Brute force, rainbow table, GPU attack

Contoh bcrypt Hash:

$2b$12$R9h7cIPz0gi.URNNX3kh2OPST9EYWckgx3/bdGHC7TN6xJnvUx2WG
│  │  │               │                                        │
│  │  │               └─ Salt (22 chars)                       └─ Hash (31 chars)
│  │  └─ Cost Factor (12 = 2^12 iterations)
│  └─ Format (2b = bcrypt)
└─ Identifier ($2b$)

Keuntungan: ✅ Built-in salt protection ✅ Adaptif terhadap hardware improvement ✅ Khusus dirancang untuk password ✅ Tahan terhadap GPU/FPGA attacks

Kelemahan: ❌ Lebih lambat (by design) ❌ Limit input hingga 72 bytes

Cost Factor:

  • Cost 10: ~10ms
  • Cost 12: ~250ms (recommended)
  • Cost 14: ~6.5 seconds

📝 Contoh Penggunaan

Skenario 1: Backup File Terenkripsi

crypto = CryptoMultifungsi()

# 1. Generate key
key = crypto.generate_fernet_key()
print(f"Simpan key ini: {key.decode()}")

# 2. Encrypt file content
dengan open('sensitive_data.txt', 'r') as f:
    data = f.read()

encrypted = crypto.encrypt_fernet(data)

# 3. Simpan encrypted file
dengan open('sensitive_data.enc', 'wb') as f:
    f.write(encrypted)

# 4. Nanti, untuk decrypt
dengan open('sensitive_data.enc', 'rb') as f:
    encrypted_data = f.read()

decrypted = crypto.decrypt_fernet(encrypted_data)
print(decrypted)

Skenario 2: Secure Communication

crypto = CryptoMultifungsi()

# Alice generates key pair
alice_private, alice_public = crypto.generate_rsa_keys()

# Bob dapat public key Alice
bob_ciphertext = crypto.encrypt_rsa("Pesan rahasia untuk Alice")

# Alice decrypt dengan private key-nya
alice_message = crypto.decrypt_rsa(bob_ciphertext)
print(alice_message)  # "Pesan rahasia untuk Alice"

Skenario 3: User Registration

crypto = CryptoMultifungsi()

# Registration - hash password
password = "MySecurePassword123!"
hashed_pwd = crypto.hash_password(password)
# Simpan hashed_pwd di database

# Login - verify password
input_pwd = "MySecurePassword123!"
jika crypto.verify_password(input_pwd, hashed_pwd):
    print("✅ Login berhasil")
else:
    print("❌ Password salah")

Skenario 4: API Request Verification

crypto = CryptoMultifungsi()

# Server generate HMAC untuk API request
api_secret = "api_secret_key_12345"
request_data = '{"user_id": 123, "action": "transfer", "amount": 5000}'

hmac_signature = crypto.create_hmac(request_data, api_secret)

# Client verifikasi
received_hmac = "8b1a9953c4611296aed9e1fe..."
expected_hmac = crypto.create_hmac(request_data, api_secret)

jika received_hmac == expected_hmac:
    print("✅ Request verified & authentic")

Skenario 5: File Integrity Check

crypto = CryptoMultifungsi()

# 1. Pengirim mengirim file + hash
dengan open('document.pdf', 'rb') as f:
    file_data = f.read()

file_hash = crypto.hash_sha256(file_data.decode('latin1'))
print(f"SHA-256: {file_hash}")

# 2. Penerima verify
received_hash = "abc123def456..."
dengan open('document.pdf', 'rb') as f:
    received_file = f.read()

computed_hash = crypto.hash_sha256(received_file.decode('latin1'))

jika computed_hash == received_hash:
    print("✅ File tidak berubah")
else:
    print("❌ File telah dimodifikasi!")

🛡️ Keamanan

Best Practices

1. Key Management

# ❌ JANGAN - hardcode key
SECRET_KEY = "my_secret_key_12345"

# ✅ LAKUKAN - load dari environment variable
SECRET_KEY = os.getenv('FERNET_KEY')

# ✅ LAKUKAN - simpan di file terpisah dengan restricted permission
with open('/etc/app/keys.conf', 'r') as f:
    SECRET_KEY = f.read()

2. Password Hashing

# ❌ JANGAN - gunakan plain SHA256 untuk password
hashed = hashlib.sha256(password.encode()).hexdigest()

# ✅ LAKUKAN - gunakan bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

3. RSA Key Handling

# ✅ Simpan private key dengan encryption & strict permission
from cryptography.hazmat.primitives import serialization

pem = private_key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.BestAvailableEncryption(b"passphrase")
)

# File permission: 600 (user only)
os.chmod('private_key.pem', 0o600)

4. Input Validation

# ✅ Validate input sebelum encrypt
def encrypt_safe(self, plaintext):
    if not isinstance(plaintext, str):
        raise TypeError("Input harus string")
    if len(plaintext) > 10000:
        raise ValueError("Input terlalu panjang")
    return self.encrypt_fernet(plaintext)

5. Timing Attack Prevention

# ✅ Gunakan constant-time comparison
import hmac

# ❌ JANGAN
if received_hmac == computed_hmac:
    pass

# ✅ LAKUKAN
if hmac.compare_digest(received_hmac, computed_hmac):
    print("Valid")

Security Considerations

Metode Kegunaan Keamanan Kecepatan
Fernet Enkripsi data at-rest Sangat Aman Cepat ⭐⭐⭐⭐
RSA Key distribution, signature Sangat Aman Lambat ⭐⭐
SHA-256 Integrity check Aman (bukan password) Cepat ⭐⭐⭐⭐⭐
HMAC Message authentication Sangat Aman Cepat ⭐⭐⭐⭐
bcrypt Password hashing Sangat Aman Lambat ⭐⭐

⚠️ Troubleshooting

Error: "ModuleNotFoundError: No module named 'cryptography'"

Solusi:

pip install --upgrade cryptography bcrypt

Error: "Key belum di-generate, tolol!"

Penyebab: Mencoba decrypt tanpa generate key terlebih dahulu

Solusi:

crypto = CryptoMultifungsi()
# 1. Generate key dulu
crypto.generate_fernet_key()
# 2. Baru encrypt/decrypt
ciphertext = crypto.encrypt_fernet("data")

Error: "Private key belum ada, goblok!"

Penyebab: Mencoba decrypt RSA tanpa generate key pair

Solusi:

crypto = CryptoMultifungsi()
# 1. Generate RSA key pair
crypto.generate_rsa_keys()
# 2. Baru encrypt/decrypt
ciphertext = crypto.encrypt_rsa("data")

Error: "Input tidak valid" pada RSA Decrypt

Penyebab: Format input ciphertext salah

Solusi:

  • Gunakan repr() untuk display ciphertext dengan format benar
  • Copy output dengan format b'...' untuk input decrypt
# Generate ciphertext
ciphertext = crypto.encrypt_rsa("test")
print(repr(ciphertext))  # Output: b'\x00\x01\x02...'

# Input ke program: b'\x00\x01\x02...'

Error: "Input hash tidak valid!"

Penyebab: Format input hash salah

Solusi:

# Program akan print hash dalam format: b'$2b$12$...'
# Input ke program: b'$2b$12$...'

bcrypt "password hashed" terlalu panjang

Keterangan: Ini normal. bcrypt output selalu 60 karakter termasuk salt dan cost factor.

$2b$12$R9h7cIPz0gi.URNNX3kh2OPST9EYWckgx3/bdGHC7TN6xJnvUx2WG
└─────────────────────────────────────────────────────────────┘
                          60 characters

📚 Referensi


📄 MIT Lisensi

Project ini tersedia untuk keperluan edukatif dan personal. Gunakan dengan bertanggung jawab.


👤 Author


💡 Tips Pembelajaran

  1. Pahami konsep sebelum implementasi

    • Baca tentang symmetric vs asymmetric encryption
    • Pahami perbedaan hashing vs encryption
  2. Eksperimen dengan data kecil dulu

    • Test dengan string pendek
    • Naikkan complexity secara bertahap
  3. Jaga keamanan key

    • Jangan commit key ke git
    • Gunakan environment variable
    • Rotate key secara berkala
  4. Monitor performa

    • RSA lebih lambat dari Fernet
    • bcrypt intentionally slow untuk security
    • Pilih sesuai kebutuhan
  5. Stay updated

    • Update library cryptography & bcrypt
    • Ikuti security advisories
    • Research algoritma baru

Last Updated: June 2026 Status: Active Development


Tambahan :


Kode Script Awal Version 1.0

import hashlib
import hmac
import os
import sys
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
import bcrypt

class CryptoMultifungsi:
    def __init__(self):
        self.fernet_key = None
        self.rsa_private_key = None
        self.rsa_public_key = None

    def generate_fernet_key(self):
        self.fernet_key = Fernet.generate_key()
        return self.fernet_key

    def encrypt_fernet(self, plaintext):
        if not self.fernet_key:
            self.generate_fernet_key()
        cipher = Fernet(self.fernet_key)
        return cipher.encrypt(plaintext.encode())

    def decrypt_fernet(self, ciphertext):
        if not self.fernet_key:
            print("Key belum di-generate, tolol!")
            return None
        cipher = Fernet(self.fernet_key)
        return cipher.decrypt(ciphertext).decode()

    def generate_rsa_keys(self):
        self.rsa_private_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=4096
        )
        self.rsa_public_key = self.rsa_private_key.public_key()
        return self.rsa_private_key, self.rsa_public_key

    def encrypt_rsa(self, plaintext):
        if not self.rsa_public_key:
            self.generate_rsa_keys()
        return self.rsa_public_key.encrypt(
            plaintext.encode(),
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA256()),
                algorithm=hashes.SHA256(),
                label=None
            )
        )

    def decrypt_rsa(self, ciphertext):
        if not self.rsa_private_key:
            print("Private key belum ada, goblok!")
            return None
        return self.rsa_private_key.decrypt(
            ciphertext,
            padding.OAEP(
                mgf=padding.MGF1(algorithm=hashes.SHA256()),
                algorithm=hashes.SHA256(),
                label=None
            )
        ).decode()

    def hash_sha256(self, message):
        return hashlib.sha256(message.encode()).hexdigest()

    def create_hmac(self, message, key):
        return hmac.new(key.encode(), message.encode(), hashlib.sha256).hexdigest()

    def hash_password(self, password):
        return bcrypt.hashpw(password.encode(), bcrypt.gensalt())

    def verify_password(self, password, hashed):
        return bcrypt.checkpw(password.encode(), hashed)

def main():
    crypto = CryptoMultifungsi()
    
    while True:
        print("\n=== CRYPTO MULTIFUNGSI ===")
        print("1. Fernet (Simetris)")
        print("2. RSA (Asimetris)")
        print("3. SHA-256 Hash")
        print("4. HMAC")
        print("5. Password Hash (bcrypt)")
        print("6. Keluar")
        
        pilihan = input("Pilih menu (1-6): ")
        
        if pilihan == "1":
            print("\n--- FERNET ---")
            print("1. Generate Key")
            print("2. Enkripsi")
            print("3. Deskripsi")
            sub_pilihan = input("Pilih: ")
            
            if sub_pilihan == "1":
                key = crypto.generate_fernet_key()
                print(f"Key: {key.decode()}")
            elif sub_pilihan == "2":
                plaintext = input("Masukkan teks: ")
                hasil = crypto.encrypt_fernet(plaintext)
                print(f"Hasil enkripsi: {hasil.decode()}")
            elif sub_pilihan == "3":
                ciphertext = input("Masukkan teks terenkripsi: ")
                hasil = crypto.decrypt_fernet(ciphertext)
                if hasil:
                    print(f"Hasil deskripsi: {hasil}")
        
        elif pilihan == "2":
            print("\n--- RSA ---")
            print("1. Generate Key Pair")
            print("2. Enkripsi")
            print("3. Deskripsi")
            sub_pilihan = input("Pilih: ")
            
            if sub_pilihan == "1":
                crypto.generate_rsa_keys()
                print("Key pair berhasil di-generate!")
            elif sub_pilihan == "2":
                plaintext = input("Masukkan teks: ")
                hasil = crypto.encrypt_rsa(plaintext)
                print(f"Hasil enkripsi: {hasil}")
            elif sub_pilihan == "3":
                ciphertext = input("Masukkan ciphertext (bytes): ")
                # Convert string input to bytes
                try:
                    ciphertext_bytes = eval(ciphertext)
                    hasil = crypto.decrypt_rsa(ciphertext_bytes)
                    print(f"Hasil deskripsi: {hasil}")
                except:
                    print("Input tidak valid, goblok!")
        
        elif pilihan == "3":
            print("\n--- SHA-256 ---")
            message = input("Masukkan pesan: ")
            hash_result = crypto.hash_sha256(message)
            print(f"Hash SHA-256: {hash_result}")
        
        elif pilihan == "4":
            print("\n--- HMAC ---")
            message = input("Masukkan pesan: ")
            key = input("Masukkan kunci HMAC: ")
            hmac_result = crypto.create_hmac(message, key)
            print(f"HMAC: {hmac_result}")
        
        elif pilihan == "5":
            print("\n--- PASSWORD HASH ---")
            print("1. Hash Password")
            print("2. Verifikasi Password")
            sub_pilihan = input("Pilih: ")
            
            if sub_pilihan == "1":
                password = input("Masukkan password: ")
                hashed = crypto.hash_password(password)
                print(f"Hashed password: {hashed}")
            elif sub_pilihan == "2":
                password = input("Masukkan password: ")
                hashed = input("Masukkan hash (bytes): ")
                try:
                    hashed_bytes = eval(hashed)
                    if crypto.verify_password(password, hashed_bytes):
                        print("Password cocok!")
                    else:
                        print("Password salah!")
                except:
                    print("Input hash tidak valid!")
        
        elif pilihan == "6":
            print("Keluar dari program. Jangan lupa belajar lebih banyak, bangsat!")
            sys.exit()
        
        else:
            print("Pilihan tidak valid, tolol!")

if __name__ == "__main__":
    main()

About

CryptoToolkit

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages