जैसा कि @rqLizard द्वारा सुझाया गया है , आप इसके बजाय openssl_encrypt
/ openssl_decrypt
PHP फ़ंक्शंस का उपयोग कर सकते हैं जो एईएस (द एडवांस्ड एन्क्रिप्शन स्टैंडर्ड) को लागू करने के लिए एक बेहतर विकल्प प्रदान करता है जिसे रिजंडेल एन्क्रिप्शन भी कहा जाता है।
निम्नलिखित स्कॉट की टिप्पणी के अनुसार php.net पर :
यदि आप 2015 में एन्क्रिप्ट / एन्क्रिप्ट डेटा के लिए कोड लिख रहे हैं, तो आपको उपयोग करना चाहिए openssl_encrypt()
और openssl_decrypt()
। अंतर्निहित पुस्तकालय ( libmcrypt
) को 2007 से छोड़ दिया गया है, और ओपनएसएसएल (जो लाभ उठाता है) की तुलना में कहीं अधिक खराब प्रदर्शन करता हैAES-NI
आधुनिक प्रोसेसर पर और कैश-टाइमिंग सुरक्षित है) की ।
इसके अलावा, MCRYPT_RIJNDAEL_256
यह नहीं है AES-256
, यह रिजेंडेल ब्लॉक सिफर का एक अलग संस्करण है। यदि आप चाहते AES-256
हैं mcrypt
, तो आपको MCRYPT_RIJNDAEL_128
32-बाइट कुंजी के साथ उपयोग करना होगा। ओपनएसएसएल यह अधिक स्पष्ट करता है कि आप किस मोड का उपयोग कर रहे हैं (यानी aes-128-cbc
बनामaes-256-ctr
)।
OpenSSL भी mcrypt के NULL बाइट पैडिंग के बजाय CBC मोड के साथ PKCS7 पैडिंग का उपयोग करता है। इस प्रकार, mcrypt OpenSSL की तुलना में आपके कोड को पैडिंग ऑरेकल हमलों के लिए असुरक्षित बनाने की अधिक संभावना है।
अंत में, यदि आप अपने सिफरटेक्स (एनक्रिप्ट तब मैक) को प्रमाणित नहीं कर रहे हैं, तो आप गलत कर रहे हैं।
आगे की पढाई:
कोड उदाहरण
उदाहरण 1
PHP 7.1+ के लिए GCM मोड उदाहरण में AES प्रमाणित एन्क्रिप्शन
<?php
//$key should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
//store $cipher, $iv, and $tag for decryption later
$original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
echo $original_plaintext."\n";
}
?>
उदाहरण # 2
PHP 5.6+ के लिए एईएस प्रमाणित एन्क्रिप्शन उदाहरण
<?php
//$key previously generated safely, ie: openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );
//decrypt later....
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
{
echo $original_plaintext."\n";
}
?>
उदाहरण # 3
उपरोक्त उदाहरणों के आधार पर, मैंने निम्नलिखित कोड को बदल दिया है जिसका उद्देश्य उपयोगकर्ता के सत्र आईडी को एन्क्रिप्ट करना है:
class Session {
/**
* Encrypts the session ID and returns it as a base 64 encoded string.
*
* @param $session_id
* @return string
*/
public function encrypt($session_id) {
// Get the MD5 hash salt as a key.
$key = $this->_getSalt();
// For an easy iv, MD5 the salt again.
$iv = $this->_getIv();
// Encrypt the session ID.
$encrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $session_id, MCRYPT_MODE_CBC, $iv);
// Base 64 encode the encrypted session ID.
$encryptedSessionId = base64_encode($encrypt);
// Return it.
return $encryptedSessionId;
}
/**
* Decrypts a base 64 encoded encrypted session ID back to its original form.
*
* @param $encryptedSessionId
* @return string
*/
public function decrypt($encryptedSessionId) {
// Get the MD5 hash salt as a key.
$key = $this->_getSalt();
// For an easy iv, MD5 the salt again.
$iv = $this->_getIv();
// Decode the encrypted session ID from base 64.
$decoded = base64_decode($encryptedSessionId);
// Decrypt the string.
$decryptedSessionId = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded, MCRYPT_MODE_CBC, $iv);
// Trim the whitespace from the end.
$session_id = rtrim($decryptedSessionId, "\0");
// Return it.
return $session_id;
}
public function _getIv() {
return md5($this->_getSalt());
}
public function _getSalt() {
return md5($this->drupal->drupalGetHashSalt());
}
}
में:
class Session {
const SESS_CIPHER = 'aes-128-cbc';
/**
* Encrypts the session ID and returns it as a base 64 encoded string.
*
* @param $session_id
* @return string
*/
public function encrypt($session_id) {
// Get the MD5 hash salt as a key.
$key = $this->_getSalt();
// For an easy iv, MD5 the salt again.
$iv = $this->_getIv();
// Encrypt the session ID.
$ciphertext = openssl_encrypt($session_id, self::SESS_CIPHER, $key, $options=OPENSSL_RAW_DATA, $iv);
// Base 64 encode the encrypted session ID.
$encryptedSessionId = base64_encode($ciphertext);
// Return it.
return $encryptedSessionId;
}
/**
* Decrypts a base 64 encoded encrypted session ID back to its original form.
*
* @param $encryptedSessionId
* @return string
*/
public function decrypt($encryptedSessionId) {
// Get the Drupal hash salt as a key.
$key = $this->_getSalt();
// Get the iv.
$iv = $this->_getIv();
// Decode the encrypted session ID from base 64.
$decoded = base64_decode($encryptedSessionId, TRUE);
// Decrypt the string.
$decryptedSessionId = openssl_decrypt($decoded, self::SESS_CIPHER, $key, $options=OPENSSL_RAW_DATA, $iv);
// Trim the whitespace from the end.
$session_id = rtrim($decryptedSessionId, '\0');
// Return it.
return $session_id;
}
public function _getIv() {
$ivlen = openssl_cipher_iv_length(self::SESS_CIPHER);
return substr(md5($this->_getSalt()), 0, $ivlen);
}
public function _getSalt() {
return $this->drupal->drupalGetHashSalt();
}
}
स्पष्ट करने के लिए, उपरोक्त परिवर्तन एक सही रूपांतरण नहीं है क्योंकि दो एन्क्रिप्शन एक अलग ब्लॉक आकार और एक अलग एन्क्रिप्टेड डेटा का उपयोग करते हैं। इसके अतिरिक्त, डिफ़ॉल्ट पैडिंग अलग है, MCRYPT_RIJNDAEL
केवल गैर-मानक नल पैडिंग का समर्थन करता है। @zaph
अतिरिक्त नोट (@ zaph टिप्पणियों से):
- क्रिप्ट 128 (
MCRYPT_RIJNDAEL_128
) है के बराबर एईएस , तथापि क्रिप्ट 256 ( MCRYPT_RIJNDAEL_256
) नहीं है एईएस 256 256 निर्दिष्ट 256 बिट्स के एक ब्लॉक आकार के रूप में, जबकि एईएस 128 बिट: केवल एक ब्लॉक आकार की है। तो मूल रूप से 256 बिट्स के एक ब्लॉक आकार के साथ क्रिप्ट ( MCRYPT_RIJNDAEL_256
है) गलती से विकल्पों की वजह से नाम दिया गया है mcrypt डेवलपर्स। @zaph
- 256 के ब्लॉक आकार के साथ रिजेंडेल 128-बिट्स के ब्लॉक आकार की तुलना में कम सुरक्षित हो सकता है क्योंकि बाद वाले को बहुत अधिक समीक्षाएँ और उपयोग मिले हैं। दूसरे, इंटरऑपरेबिलिटी इसमें बाधा है जबकि एईएस आमतौर पर उपलब्ध है, जहां 256-बिट्स के ब्लॉक आकार के साथ रिजेंडेल नहीं है।
रिजेंडेल के लिए अलग-अलग ब्लॉक आकार के साथ एन्क्रिप्शन अलग एन्क्रिप्टेड डेटा का उत्पादन करता है।
उदाहरण के लिए, MCRYPT_RIJNDAEL_256
(समतुल्य नहीं AES-256
) 256-बिट्स के आकार के साथ रिजिन्डेल ब्लॉक सिफर के एक भिन्न प्रकार को परिभाषित करता है और कुंजी में पारित होने के आधार पर एक कुंजी का आकार होता है, जहां aes-256-cbc
एक महत्वपूर्ण आकार के साथ 128-बिट्स के ब्लॉक आकार के साथ रिजेंडेल है 256-बिट। इसलिए वे विभिन्न ब्लॉक आकारों का उपयोग कर रहे हैं जो पूरी तरह से अलग एन्क्रिप्टेड डेटा का उत्पादन करते हैं क्योंकि mcrypt ब्लॉक आकार को निर्दिष्ट करने के लिए नंबर का उपयोग करता है, जहां OpenSSL ने कुंजी आकार को निर्दिष्ट करने के लिए संख्या का उपयोग किया था (AES में केवल एक ब्लॉक आकार 128 बिट्स है)। तो मूल रूप से एईएस 128-बिट्स के ब्लॉक आकार और 128, 192 और 256 बिट्स के प्रमुख आकारों के साथ रिजेंडेल है। इसलिए एईएस का उपयोग करना बेहतर है, जिसे ओपनएसएसएल में रिजंडेल 128 कहा जाता है।
password_hash
और उनके साथ सत्यापित करेंpassword_verify
?