Selam dostlar, eski bir web projemi PHP 8.3'e taşıyorum ve mcrypt eklentisi kaldırıldığı için şifreleme fonksiyonlarım çalışmıyor. Eski kodumda mcrypt_encrypt ile AES-256-CBC kullanıyordum ve veritabanındaki mevcut şifrelenmiş verileri de çözmem gerekiyor. Yeni projede OpenSSL'e geçmem gerektiğini biliyorum ama eski verileri nasıl çözeceğim konusunda kafam karıştı. Eski kodda IV olarak sabit bir string kullanıyordum (16 byte) ve anahtar 32 byte. Şimdi openssl_decrypt ile aynı verileri çözebilir miyim? Yoksa verileri kaybetmeden migrasyon yapmanın bir yolu var mı? Yardımcı olursanız sevinirim, teşekkürler.
PHP 8.3'te mcrypt kütüphanesi olmadan AES-256-CBC şifreleme nasıl yapılır?
Cevaplar (5)
09.08.2026 01:20
Merhaba, aynı sorunu ben de yaşadım. mcrypt ve OpenSSL arasındaki uyumluluk konusunda dikkatli olmalısın. Eğer eski kodunda mcrypt_encrypt ile MCRYPT_RIJNDAEL_128 kullandıysan ve IV 16 byte ise, OpenSSL'de aes-256-cbc ile birebir aynı sonucu alırsın. Ancak mcrypt'in padding'i farklı olabilir; mcrypt null padding kullanır, OpenSSL ise PKCS#7 padding kullanır. Bu yüzden eski verileri çözerken openssl_decrypt ile çözemezsin, çünkü padding uyumsuzluğu olur. Çözüm olarak, eski verileri çözmek için mcrypt'i taklit eden bir fonksiyon yazman gerek. Aşağıdaki gibi bir fonksiyon işini görür:
function mcrypt_decrypt_compat($cipher, $key, $data, $mode, $iv) {
// mcrypt null padding ekler, OpenSSL PKCS#7 kullanır.
// Bu yüzden openssl_decrypt ile dene, başarısız olursa null padding'i manuel olarak çöz.
$decrypted = openssl_decrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
// Null padding'i kaldır
$decrypted = rtrim($decrypted, "\0");
return $decrypted;
}
Bu fonksiyonu kullanarak eski verileri çözebilir, sonra yeni verileri openssl_encrypt ile PKCS#7 padding kullanarak şifreleyebilirsin. Ayrıca IV'ü sabit kullanmak yerine her veri için rastgele üretip saklamanı öneririm, güvenlik açısından.
function mcrypt_decrypt_compat($cipher, $key, $data, $mode, $iv) {
// mcrypt null padding ekler, OpenSSL PKCS#7 kullanır.
// Bu yüzden openssl_decrypt ile dene, başarısız olursa null padding'i manuel olarak çöz.
$decrypted = openssl_decrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
// Null padding'i kaldır
$decrypted = rtrim($decrypted, "\0");
return $decrypted;
}
Bu fonksiyonu kullanarak eski verileri çözebilir, sonra yeni verileri openssl_encrypt ile PKCS#7 padding kullanarak şifreleyebilirsin. Ayrıca IV'ü sabit kullanmak yerine her veri için rastgele üretip saklamanı öneririm, güvenlik açısından.
09.08.2026 01:36
pixelwizard22 yazdı:
Eski kodumda mcrypt_encrypt ile AES-256-CBC kullanıyordum ve veritabanındaki mevcut şifrelenmiş verileri de çözmem gerekiyor.
Aynen, glitchfiend73'ün dediği gibi padding sorunu en büyük sıkıntı. Ben de ek olarak şunu söyleyeyim: Eğer eski kodunda IV'ü sabit bir string olarak kullandıysan, bu güvenlik açısından zaten kötü bir uygulamaydı. Şimdi geçerken veritabanındaki her kayıt için IV'ü de saklamalısın. Yeni sistemde her şifreleme için rastgele IV üret ve IV'ü şifrelenmiş verinin yanına ekle. Örneğin:
function encryptData($data, $key) {
$iv = openssl_random_pseudo_bytes(16);
$ciphertext = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
return base64_encode($iv . $ciphertext);
}
function decryptData($data, $key) {
$data = base64_decode($data);
$iv = substr($data, 0, 16);
$ciphertext = substr($data, 16);
return openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
}
Bu şekilde hem eski verileri çözüp hem de yeni sisteme geçebilirsin. Ayrıca eski verileri çözerken yukarıdaki compat fonksiyonunu kullanmayı unutma.
09.08.2026 01:53
Beyler, ben de bu konuyu araştırmıştım. mcrypt ve OpenSSL arasındaki fark sadece padding değil, aynı zamanda anahtar uzunluğu da önemli. mcrypt'te MCRYPT_RIJNDAEL_128 aslında AES-128'dir, ama siz AES-256 diyorsanız anahtarınız 32 byte olmalı. Eğer anahtarınız 32 byte ise OpenSSL'de 'aes-256-cbc' kullanmalısınız. Ayrıca mcrypt'te IV 16 byte olmak zorunda, OpenSSL'de de aynı. Benim önerim şu: eski verileri çözmek için bir script yaz, tüm verileri çöz, sonra yeni formatla şifreleyip veritabanına geri yaz. Bu işlemi tek seferde yapmak yerine, bir migration scripti ile yapabilirsin. Ayrıca glitchfiend73'ün verdiği fonksiyonu test et, bende çalışmıştı. Kolay gelsin.
09.08.2026 02:08
Selam, bir de şu noktaya dikkat çekmek istiyorum: mcrypt_encrypt fonksiyonu, eğer veri uzunluğu blok boyutuna tam bölünmüyorsa null byte ile doldurur. OpenSSL ise PKCS#7 kullanır. Bu yüzden eski veriyi çözerken openssl_decrypt'e OPENSSL_ZERO_PADDING bayrağını eklemeniz şart. Ayrıca, eğer verinin sonunda null byte'lar varsa, rtrim ile temizlemelisiniz. Bunun dışında, anahtar ve IV'ün doğru olduğundan emin olun. Ben de bir projede bu geçişi yaptım, aşağıdaki gibi bir yardımcı sınıf yazmıştım:
class CryptoCompat {
private $key;
private $cipher = 'aes-256-cbc';
public function __construct($key) {
$this->key = $key;
}
public function decryptOld($data, $iv) {
$decrypted = openssl_decrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
return rtrim($decrypted, "\0");
}
public function encryptNew($data) {
$iv = openssl_random_pseudo_bytes(16);
$encrypted = openssl_encrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA, $iv);
return ['data' => base64_encode($encrypted), 'iv' => base64_encode($iv)];
}
}
Bu sınıfı kullanarak eski verileri çözüp yeni formatta saklayabilirsiniz. Ayrıca, veritabanı şemanızda IV sütunu eklemeyi unutmayın.
class CryptoCompat {
private $key;
private $cipher = 'aes-256-cbc';
public function __construct($key) {
$this->key = $key;
}
public function decryptOld($data, $iv) {
$decrypted = openssl_decrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
return rtrim($decrypted, "\0");
}
public function encryptNew($data) {
$iv = openssl_random_pseudo_bytes(16);
$encrypted = openssl_encrypt($data, $this->cipher, $this->key, OPENSSL_RAW_DATA, $iv);
return ['data' => base64_encode($encrypted), 'iv' => base64_encode($iv)];
}
}
Bu sınıfı kullanarak eski verileri çözüp yeni formatta saklayabilirsiniz. Ayrıca, veritabanı şemanızda IV sütunu eklemeyi unutmayın.
09.08.2026 02:38
Arkadaşlar, hepinize çok teşekkür ederim! glitchfiend73'ün verdiği compat fonksiyonu ve pixelchaser57'nin önerdiği yeni şifreleme yöntemi işe yaradı. Eski verileri sorunsuz çözdüm, ardından her kayıt için rastgele IV üretip yeni formatta şifreledim ve veritabanını güncelledim. Migration scriptini de yazdım, şu an her şey çalışıyor. Ayrıca segabender67'nin dediği gibi anahtar uzunluğuna dikkat ettim, 32 byte anahtar kullanıyorum. Bu konuda yardımcı olan herkese teşekkürler, sorun çözüldü!
Bu konuya cevap yazabilmek için retro topluluğumuza üye olmalı veya giriş yapmalısınız.
İlgili Konular & Benzer Paylaşımlar
PHP 8'de eski bir MySQL kodunu PDO'ya çevirirken karşılaştığım PDOException hatası
Kategori: Web Geliştirme
PHP 8.2 ile eski bir projeyi çalıştırırken hata: Call to undefined function mysql_connect()
Kategori: Web Geliştirme
Pico W ile kendi web sunucumu kurdum ama CSS dosyası bir türlü yüklenmiyor - neyi yanlış yapıyorum?
Kategori: Web Geliştirme