@RqLizard দ্বারা প্রস্তাবিত হিসাবে , আপনি পরিবর্তে openssl_encrypt
/ openssl_decrypt
পিএইচপি ফাংশন ব্যবহার করতে পারেন যা এইএস (অ্যাডভান্সড এনক্রিপশন স্ট্যান্ডার্ড) বাস্তবায়নের জন্য আরও ভাল বিকল্প সরবরাহ করে যা রিজান্ডেল এনক্রিপশন হিসাবে পরিচিত।
পিএইচপিএনএমে নিম্নলিখিত স্কটের মন্তব্য অনুসারে :
যদি আপনি 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
)।
ওপেনএসএসএল এমক্রিপ্টের নুল বাইট প্যাডিংয়ের পরিবর্তে সিবিসি মোডের সাথে পিকেসিএস 7 প্যাডিংও ব্যবহার করে। সুতরাং, এমক্রিপ্ট আপনার কোড ওপেনএসএসএল-এর তুলনায় প্যাডিং ওরাকল আক্রমণগুলিতে ঝুঁকিপূর্ণ হওয়ার সম্ভাবনা বেশি।
অবশেষে, আপনি যদি নিজের সিফেরটেক্সটগুলি (এনক্রিপ্ট তারপর ম্যাক) প্রমাণীকরণ করেন না, আপনি এটি ভুল করছেন।
আরও পড়া:
কোড উদাহরণ
উদাহরণ # 1
পিইচপি 7.1+ এর জন্য জিসিএম মোডে এইএস প্রমাণীকৃত এনক্রিপশন
<?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
পিএইচপি 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
অতিরিক্ত নোট (@ জাফের মন্তব্য থেকে):
- Rijndael 128 (
MCRYPT_RIJNDAEL_128
) হল সমতূল্য হবে AES তবে Rijndael 256 ( MCRYPT_RIJNDAEL_256
) নয় AES-256 256 নির্দিষ্ট করে 256-বিট একটি ব্লক আকার, যেহেতু হবে AES 128-বিট: শুধুমাত্র এক ব্লক আকার হয়েছে। সুতরাং মূলত 256-বিট ( MCRYPT_RIJNDAEL_256
) এর একটি ব্লক আকারের রিজান্ডেলকে এমক্রিপ ডেভেলপারদের পছন্দগুলির কারণে ভুল করে নামকরণ করা হয়েছে । @zaph
- 258 -র একটি ব্লকের আকারের রিজান্ডেল 128-বিটের ব্লকের আকারের চেয়ে কম সুরক্ষিত হতে পারে কারণ পরেরটির অনেক বেশি পর্যালোচনা এবং ব্যবহার রয়েছে। দ্বিতীয়ত, আন্তঃব্যবহার্যতা এতে বাধা দেয় যখন এইএস সাধারণত পাওয়া যায়, যেখানে 256-বিটের ব্লকের আকারের রিজান্ডেল নেই not
রিজান্ডেলের জন্য বিভিন্ন ব্লক আকারের সাথে এনক্রিপশন বিভিন্ন এনক্রিপ্টড ডেটা তৈরি করে।
উদাহরণস্বরূপ, MCRYPT_RIJNDAEL_256
(সমতুল্য নয় AES-256
) 256-বিট আকারের রিজান্ডেল ব্লক সাইফারের আলাদা বৈকল্পিক এবং কী পাস করা উপর ভিত্তি করে একটি কী আকারকে সংজ্ঞায়িত করে, যেখানে aes-256-cbc
কি-র আকারের 128-বিটের একটি ব্লক আকারের সাথে রিজান্ডেল রয়েছে 256-বিট। সুতরাং তারা বিভিন্ন ব্লক আকার ব্যবহার করছে যা পুরোপুরি আলাদা এনক্রিপ্ট করা ডেটা তৈরি করে এমক্রিপ্ট ব্লকের আকার নির্দিষ্ট করতে নম্বরটি ব্যবহার করে, যেখানে ওপেনএসএসএল কী আকারটি নির্দিষ্ট করার জন্য নম্বরটি ব্যবহার করেছে (এইএসের কেবল একটি ব্লকের আকার 128-বিট রয়েছে)। সুতরাং মূলত এইএস হ'ল রিজান্ডেল 128-বিট এবং 128, 192 এবং 256 বিটের কী আকারের ব্লক আকারের। সুতরাং ওপেনএসএসএলে রিজান্ডেল 128 নামে পরিচিত এটিএস ব্যবহার করা আরও ভাল।
password_hash
এবং তাদের সাথে যাচাই করা হচ্ছে নাpassword_verify
?