Kod:
#!/usr/bin/env python3
import os
import sys
import mmap
import ctypes
import time
from getpass import getpass
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.argon2 import Argon2id
from cryptography.exceptions import InvalidTag
MAX_FILE_SIZE = 1 * 1024 * 1024 * 1024 # 1 GiB
# -------------------- Güvenli Bellek --------------------
def secure_mmap(size: int) -> mmap.mmap:
"""
RAM’de swap’e yazılmayacak güvenli bir bellek bloğu oluşturur.
"""
mm = mmap.mmap(-1, size, prot=mmap.PROT_READ | mmap.PROT_WRITE)
try:
libc = ctypes.CDLL("libc.so.6")
addr = ctypes.addressof(ctypes.c_char.from_buffer(mm))
if libc.mlock(ctypes.c_void_p(addr), ctypes.c_size_t(size)) != 0:
raise RuntimeError("mlock başarısız!")
except Exception:
pass # Windows veya desteklenmeyen sistemlerde geç
return mm
def secure_zero_mmap(mm: mmap.mmap):
"""
mmap ile oluşturulmuş belleği güvenli şekilde sıfırlar ve kapatır.
"""
try:
mm.seek(0)
mm.write(bytearray(len(mm)))
except Exception:
pass
finally:
try:
mm.close()
except Exception:
pass
# -------------------- Dosya Güvenliği --------------------
def read_file_safe(path: str) -> bytes:
if not os.path.isfile(path):
print("Hata: Girdi dosyası bulunamadı!")
sys.exit(1)
size = os.path.getsize(path)
if size > MAX_FILE_SIZE:
print("Hata: Dosya boyutu çok büyük!")
sys.exit(1)
with open(path, "rb") as f:
return f.read()
def write_file_safe(path: str, data: bytes):
if os.path.exists(path):
print(f"Hata: Çıkış dosyası zaten mevcut: {path}")
sys.exit(1)
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
with os.fdopen(os.open(path, flags, 0o600), "wb") as f:
f.write(data)
# -------------------- Key Türetilmesi --------------------
def derive_key(password_mm: mmap.mmap, salt: bytes) -> mmap.mmap:
kdf = Argon2id(
salt=salt,
length=32,
iterations=16,
memory_cost=1024*1024,
lanes=2
)
key_bytes = bytearray(kdf.derive(password_mm[:])) # bytearray
key_mm = secure_mmap(len(key_bytes))
key_mm.write(key_bytes)
# key_bytes belleğini sıfırla
for i in range(len(key_bytes)):
key_bytes[i] = 0
return key_mm
# -------------------- Şifreleme --------------------
def encrypt_file(input_path: str, output_path: str, password_mm: mmap.mmap):
plaintext = bytearray(read_file_safe(input_path))
salt = os.urandom(32)
nonce = os.urandom(12)
key_mm = derive_key(password_mm, salt)
aesgcm = AESGCM(key_mm[:])
ciphertext = bytearray(aesgcm.encrypt(nonce, plaintext, None))
write_file_safe(output_path, salt + nonce + ciphertext)
# Belleği temizle
for i in range(len(plaintext)):
plaintext[i] = 0
for i in range(len(ciphertext)):
ciphertext[i] = 0
secure_zero_mmap(key_mm)
print(f"Dosya başarıyla şifrelendi: {output_path}")
# -------------------- Şifre Çözme --------------------
def decrypt_file(input_path: str, output_path: str, password_mm: mmap.mmap):
data = read_file_safe(input_path)
if len(data) < 28:
print("İşlem başarısız!")
sys.exit(1)
salt = data[:32]
nonce = data[32:44]
ciphertext = bytearray(data[44:])
key_mm = derive_key(password_mm, salt)
aesgcm = AESGCM(key_mm[:])
start = time.perf_counter()
try:
plaintext = bytearray(aesgcm.decrypt(nonce, ciphertext, None))
success = True
except InvalidTag:
success = False
plaintext = bytearray(len(ciphertext)) # dummy
end = time.perf_counter()
# Minimum süreyi sabitle (side-channel koruması)
elapsed = end - start
time.sleep(max(0, 0.5 - elapsed))
if not success:
secure_zero_mmap(key_mm)
for i in range(len(ciphertext)):
ciphertext[i] = 0
print("İşlem başarısız!")
sys.exit(1)
write_file_safe(output_path, plaintext)
# Belleği temizle
for i in range(len(plaintext)):
plaintext[i] = 0
for i in range(len(ciphertext)):
ciphertext[i] = 0
secure_zero_mmap(key_mm)
print(f"Dosya başarıyla çözüldü: {output_path}")
# -------------------- Ana Program --------------------
def main():
print("=== AES‑256‑GCM Dosya Şifreleme / Şifre Çözme ===")
print("1) Dosya Şifrele")
print("2) Dosya Şifre Çöz")
choice = input("Seçiminiz (1/2): ").strip()
input_path = input("Girdi dosya yolu: ").strip()
output_path = input("Çıktı dosya yolu: ").strip()
password_str = getpass("Şifreyi girin: ").strip()
password_bytes = password_str.encode() # UTF-8 byte dizisine çevir
password_mm = secure_mmap(len(password_bytes))
password_mm.write(password_bytes)
# Belleği temizlemek için orijinal stringi sil
del password_str, password_bytes
try:
if choice == "1":
encrypt_file(input_path, output_path, password_mm)
elif choice == "2":
decrypt_file(input_path, output_path, password_mm)
else:
print("Geçersiz seçim!")
sys.exit(1)
finally:
# Her durumda password_mm temizlenip kapatılıyor
secure_zero_mmap(password_mm)
if __name__ == "__main__":
main()
Arkadaşlar böyle bir uygulama yaptım yapay zeka yardımı ile. Uygulama iyi mi, hangi sorunları var sizce?
Son düzenleyen: Moderatör: