mcrypt को हटा दिया गया है, विकल्प क्या है?


103

Mcrypt-extension को पदावनत किया गया है जिसे PHP 7.2 में यहां पोस्ट की गई टिप्पणी के अनुसार हटा दिया जाएगा । इसलिए मैं पासवर्ड एन्क्रिप्ट करने का एक वैकल्पिक तरीका ढूंढ रहा हूं।

अभी मैं जैसे कुछ उपयोग कर रहा हूं

mcrypt_encrypt(MCRYPT_RIJNDAEL_128, md5($key, true), $string, MCRYPT_MODE_CBC, $iv)

मुझे पासवर्ड एन्क्रिप्ट करने के लिए सबसे अच्छे / सबसे मज़बूत तरीके के लिए आपकी राय चाहिए, एन्क्रिप्टेड पासवर्ड को PHP 7.xx द्वारा समर्थित होना चाहिए और इसे डिक्रिप् टेबल भी होना चाहिए क्योंकि मेरे ग्राहक नया पासवर्ड जेनरेट किए बिना अपने पासवर्ड को 'रिकवर' करने का विकल्प चाहते हैं। एक।


9
आपको पासवर्ड एन्क्रिप्ट / डिक्रिप्ट करने की आवश्यकता क्यों है? क्यों नहीं बस उनके साथ हैश password_hashऔर उनके साथ सत्यापित करें password_verify?
आतंक न करें

3
"एन्क्रिप्ट किया गया पासवर्ड भी डिक्रिप्टेबल होना चाहिए" - क्यों? बहुत सुरक्षित नहीं है। कोई खास वजह?
फंक फोर्टी निनेर

24
"क्योंकि मेरे ग्राहक नया पासवर्ड बनाए बिना अपने पासवर्ड को 'रिकवर' करने का विकल्प चाहते हैं।" - यह सुरक्षित नहीं है और उन्हें इसके बजाय अपने पासवर्ड रीसेट करने का विकल्प दिया जाना चाहिए।
फंक फोर्टी निनेर

4
पासवर्ड एन्क्रिप्ट न करें , जब हमलावर को डीबी मिलता है तो उसे एन्क्रिप्शन कुंजी भी मिलेगी। लगभग 100ms की अवधि के लिए एक यादृच्छिक नमक के साथ एक HMAC पर मिलाएं और हैश के साथ नमक को बचाएं। पासवर्ड_हश, PBKDF2, Bcrypt और इसी तरह के कार्यों का उपयोग करें। बिंदु यह है कि हमलावर बल द्वारा पासवर्ड खोजने में बहुत समय बिताए।
ज़ाफ

2
Php मैनुअल से -> इस फ़ंक्शन को PHP 7.1.0 के रूप में परिभाषित किया गया है। इस कार्य पर भरोसा करना बहुत हतोत्साहित करता है। वैकल्पिक सोडियम है -> php.net/manual/en/book.sodium.php
MarcoZen

जवाबों:


47

पासवर्ड हैश करने के लिए यह सबसे अच्छा अभ्यास है, इसलिए वे डिक्रिप्टेबल नहीं हैं। यह हमलावरों के लिए चीजों को थोड़ा और कठिन बनाता है जो आपके डेटाबेस या फ़ाइलों तक पहुंच प्राप्त कर सकते हैं।

यदि आपको अपना डेटा एन्क्रिप्ट करना है और इसे डिक्रिप्ट करना है, तो एन्क्रिप्शन / डिक्रिप्शन को सुरक्षित करने के लिए एक गाइड https://paragonie.com/white-paper/2015-secure-php-data-enc एन्क्रिप्शन पर उपलब्ध है । उस लिंक को संक्षेप में प्रस्तुत करने के लिए:

  • Libsodium का उपयोग करें - एक PHP एक्सटेंशन
  • यदि आप लिबसोडियम का उपयोग नहीं कर सकते हैं, तो डिफ्यूज़ / php-एन्क्रिप्शन - स्ट्रेट PHP कोड का उपयोग करें
  • यदि आप Libsodium या डिफ्यूज़ / php-एन्क्रिप्शन का उपयोग नहीं कर सकते हैं, तो OpenSSL का उपयोग करें - बहुत सारे सर्वर में यह पहले से इंस्टॉल हो जाएगा। यदि नहीं, तो इसे --with -ssl [= DIR] के साथ संकलित किया जा सकता है

1
पहले खुलने का प्रयास करना चाहिए क्योंकि यह बहुत आम है, जहां लिबासोडियम नहीं है। रॉ php का उपयोग तब तक नहीं किया जाना चाहिए जब तक कि सभी देशी एक्सटेंशन बाहर न हों यदि प्रश्न
JSON

भले ही ओप्सल बहुत आम है, ऐसा लगता है कि php 7 अपनी मूल क्रिप्टोग्राफी सुरक्षा के
shadi

1
ध्यान दें कि एक पुस्तकालय है जिसे Sodium-compat( github.com/paragonie/sodium_compat ) कहा जाता है जो PHP> = 5.2.4 में काम करता है
RaelB

30

जैसा कि @rqLizard द्वारा सुझाया गया है , आप इसके बजाय openssl_encrypt/ openssl_decryptPHP फ़ंक्शंस का उपयोग कर सकते हैं जो एईएस (द एडवांस्ड एन्क्रिप्शन स्टैंडर्ड) को लागू करने के लिए एक बेहतर विकल्प प्रदान करता है जिसे रिजंडेल एन्क्रिप्शन भी कहा जाता है।

निम्नलिखित स्कॉट की टिप्पणी के अनुसार php.net पर :

यदि आप 2015 में एन्क्रिप्ट / एन्क्रिप्ट डेटा के लिए कोड लिख रहे हैं, तो आपको उपयोग करना चाहिए openssl_encrypt()और openssl_decrypt()। अंतर्निहित पुस्तकालय ( libmcrypt) को 2007 से छोड़ दिया गया है, और ओपनएसएसएल (जो लाभ उठाता है) की तुलना में कहीं अधिक खराब प्रदर्शन करता हैAES-NI आधुनिक प्रोसेसर पर और कैश-टाइमिंग सुरक्षित है) की ।

इसके अलावा, MCRYPT_RIJNDAEL_256यह नहीं है AES-256, यह रिजेंडेल ब्लॉक सिफर का एक अलग संस्करण है। यदि आप चाहते AES-256हैं mcrypt, तो आपको MCRYPT_RIJNDAEL_12832-बाइट कुंजी के साथ उपयोग करना होगा। ओपनएसएसएल यह अधिक स्पष्ट करता है कि आप किस मोड का उपयोग कर रहे हैं (यानी 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 कहा जाता है।


1
सामान्य रूप से 256-बिट्स के ब्लॉक आकार के साथ रिजेंडेल का उपयोग करना mcrypt डेवलपर्स की पसंद के कारण एक गलती है। आगे 256 के ब्लॉक आकार के साथ रिजेंडेल कम सुरक्षित हो सकता है, क्योंकि 128-बिट्स के ब्लॉक आकार के साथ क्योंकि बाद में बहुत अधिक समीक्षा और उपयोग हुआ है। इसके अतिरिक्त इंटरऑपरेबिलिटी इसमें बाधा है, जबकि एईएस आमतौर पर उपलब्ध होता है, जिसमें 256-बिट्स का ब्लॉक आकार नहीं होता है।
ज़ाफ़

क्यों करते हो $session_id = rtrim($decryptedSessionId, "\0");? क्या openssl_decryptअंत में कुछ अवांछित पात्रों को वापस करना संभव है ? क्या होगा यदि एन्क्रिप्ट किया गया चर 0 (यानी encrypt("abc0")?
hlscalon

@ राजकोषीय "\0"नहीं "0"बल्कि NULL वर्ण है, जिसका ASCII कोड 0x00 (हेक्साडेसिमल 0) है।
kiamlaluno

11

रिजेंडेल का शुद्ध-PHP कार्यान्वयन संगीतकार पैकेज के रूप में उपलब्ध phpseclib के साथ मौजूद है और PHP 7.3 (मेरे द्वारा परीक्षण) पर काम करता है।

Phpseclib डॉक्स पर एक पृष्ठ है, जो मूल चर (सिफर, मोड, कुंजी आकार, बिट आकार) इनपुट करने के बाद नमूना कोड उत्पन्न करता है । यह रिज़ंडेल, ईसीबी, 256, 256 के लिए निम्न आउटपुट देता है:

mycrypt वाला एक कोड

$decoded = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, ENCRYPT_KEY, $term, MCRYPT_MODE_ECB);

पुस्तकालय के साथ इस तरह काम करता है

$rijndael = new \phpseclib\Crypt\Rijndael(\phpseclib\Crypt\Rijndael::MODE_ECB);
$rijndael->setKey(ENCRYPT_KEY);
$rijndael->setKeyLength(256);
$rijndael->disablePadding();
$rijndael->setBlockLength(256);

$decoded = $rijndael->decrypt($term);

* $termथाbase64_decoded


11

जैसा कि यहां अन्य उत्तरों से विस्तृत है, मैंने पाया सबसे अच्छा समाधान ओपनएसएसएल का उपयोग कर रहा है। यह PHP में बनाया गया है और आपको किसी बाहरी पुस्तकालय की आवश्यकता नहीं है। यहाँ सरल उदाहरण हैं:

एन्क्रिप्ट करने के लिए:

function encrypt($key, $payload) {
  $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
  $encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
  return base64_encode($encrypted . '::' . $iv);
}

डिक्रिप्ट करने के लिए:

function decrypt($key, $garble) {
    list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
    return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
}

संदर्भ लिंक: https://www.shift8web.ca/2017/04/how-to-encrypt-and-execute-your-php-code-with-mcrypt/


बहुत सारे अच्छे कर्म आपको मित्र! केवल एक चीज: यदि पासवर्ड, उदाहरण के लिए, पुराने कोड के साथ एन्क्रिप्ट किया गया था, तो नया डिक्रिप्ट कोड इसे सत्यापित नहीं कर पाएगा। इस नए कोड के साथ इसे फिर से सहेजना और एन्क्रिप्ट करना होगा।
लुमिस

एक सरल माइग्रेशन स्क्रिप्ट उस समस्या को हल करेगी। डिक्रिप्ट करने के लिए पुराने तरीके का उपयोग करें फिर एन्क्रिप्ट और स्टोर करने का नया तरीका। विकल्प उपयोगकर्ता की तालिका में एक ध्वज जोड़ रहा है और पासवर्ड परिवर्तन की आवश्यकता वाले सभी उपयोगकर्ता खातों पर एक मजबूर पासवर्ड रीसेट में स्क्रिप्टिंग कर रहा है।
सेसिल मेरेल उर्फ ​​एप्रनफायरफायर

8

आप phpseclib pollyfill पैकेज का उपयोग कर सकते हैं । आप rijndael 256 के साथ एन्क्रिप्ट / डिक्रिप्ट के लिए खुले ssl या libsodium का उपयोग नहीं कर सकते। एक और मुद्दा, आपको किसी भी कोड को बदलने की आवश्यकता नहीं है।


2
यह सुपर सहायक धन्यवाद था। Php-mcrypt एक्सटेंशन को हटाना पड़ा, और फिर यह एक आकर्षण की तरह काम करता है।
DannyB

मैं mcrypt_compatदौड़कर स्थापित हुआ composer require phpseclib/mcrypt_compatलेकिन मुझे अभी भी लगता है कि PHP Fatal error: Uncaught Error: Call to undefined function mcrypt_get_key_size() in /app/kohana/classes/Kohana/Encrypt.php:124मैं php 7.2.26और कोहना फ्रैमवर्क का उपयोग कर रहा हूं । क्या संगीतकार के साथ इसे स्थापित करने के बाद प्रदर्शन करने के लिए कोई और कदम है?
एम-

समझ गया। आपको require APPPATH . '/vendor/autoload.php';नीचे तक जोड़ना है bootstrap.php
एम-

3

आपको ओवरएसएसएलएल का उपयोग करना चाहिए mcrypt क्योंकि यह सक्रिय रूप से विकसित और बनाए रखा गया है। यह बेहतर सुरक्षा, स्थिरता और पोर्टेबिलिटी प्रदान करता है। दूसरे यह एईएस एन्क्रिप्शन / डिक्रिप्शन बहुत तेजी से करता है। यह डिफ़ॉल्ट रूप से PKCS7 पैडिंग का उपयोग करता है, लेकिन OPENSSL_ZERO_PADDINGयदि आपको इसकी आवश्यकता है तो आप निर्दिष्ट कर सकते हैं । 32-बाइट बाइनरी कुंजी के साथ उपयोग करने के लिए, आप निर्दिष्ट कर सकते हैं aes-256-cbcजो कि तुलना में बहुत स्पष्ट है MCRYPT_RIJNDAEL_128

यहाँ Mcrypt का उपयोग कर कोड उदाहरण है:

McCS में PKCS7 पैडिंग के साथ लिखा गया गैर-सूचीबद्ध AES-256-CBC एन्क्रिप्शन लाइब्रेरी।

/**
 * This library is unsafe because it does not MAC after encrypting
 */
class UnsafeMcryptAES
{
    const CIPHER = MCRYPT_RIJNDAEL_128;

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = mcrypt_get_iv_size(self::CIPHER);
        $iv = mcrypt_create_iv($ivsize, MCRYPT_DEV_URANDOM);

        // Add PKCS7 Padding
        $block = mcrypt_get_block_size(self::CIPHER);
        $pad = $block - (mb_strlen($message, '8bit') % $block, '8bit');
        $message .= str_repeat(chr($pad), $pad);

        $ciphertext = mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128,
            $key,
            $message,
            MCRYPT_MODE_CBC,
            $iv
        );

        return $iv . $ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = mcrypt_get_iv_size(self::CIPHER);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        $plaintext = mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            $key,
            $ciphertext,
            MCRYPT_MODE_CBC,
            $iv
        );

        $len = mb_strlen($plaintext, '8bit');
        $pad = ord($plaintext[$len - 1]);
        if ($pad <= 0 || $pad > $block) {
            // Padding error!
            return false;
        }
        return mb_substr($plaintext, 0, $len - $pad, '8bit');
    }
}

और यहाँ OpenSSL का उपयोग करके लिखा गया संस्करण है:

/**
 * This library is unsafe because it does not MAC after encrypting
 */
class UnsafeOpensslAES
{
    const METHOD = 'aes-256-cbc';

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = openssl_random_pseudo_bytes($ivsize);

        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );

        return $iv . $ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        return openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}

स्रोत: यदि आप अपने PHP कोड में शब्द MCRYPT टाइप कर रहे हैं, तो आप इसे गलत कर रहे हैं


2

मैं PHP 7.2.x पर इसका उपयोग कर रहा हूं, यह मेरे लिए ठीक काम कर रहा है:

public function make_hash($userStr){
        try{
            /** 
             * Used and tested on PHP 7.2x, Salt has been removed manually, it is now added by PHP 
             */
             return password_hash($userStr, PASSWORD_BCRYPT);
            }catch(Exception $exc){
                $this->tempVar = $exc->getMessage();
                return false;
            }
        }

और फिर निम्न फ़ंक्शन के साथ हैश प्रमाणित करें:

public function varify_user($userStr,$hash){
        try{
            if (password_verify($userStr, $hash)) {
                 return true;
                }
            else {
                return false;
                }
            }catch(Exception $exc){
                $this->tempVar = $exc->getMessage();
                return false;
            }
        }

उदाहरण:

  //create hash from user string

 $user_password = $obj->make_hash2($user_key);

और इस हैश को प्रमाणित करने के लिए निम्नलिखित कोड का उपयोग करें:

if($obj->varify_user($key, $user_key)){
      //this is correct, you can proceed with  
    }

बस इतना ही।


1

जैसा कि बताया गया है, आपको अपने उपयोगकर्ताओं के पासवर्ड को एक प्रारूप में संग्रहीत नहीं करना चाहिए जो कि डिक्रिप्टेबल हो। प्रतिवर्ती एन्क्रिप्शन अपने उपयोगकर्ताओं के पासवर्ड का पता लगाने के लिए हैकर्स के लिए एक आसान मार्ग प्रदान करता है, जो आपके उपयोगकर्ताओं के खातों को अन्य साइटों पर डालने का जोखिम रखता है, उन्हें वहीं पासवर्ड का उपयोग करना चाहिए।

PHP यादृच्छिक-नमकीन, वन-वे हैश एन्क्रिप्शन - password_hash()और के लिए शक्तिशाली कार्यों की एक जोड़ी प्रदान करता है password_verify()। क्योंकि हैश स्वचालित रूप से यादृच्छिक-नमकीन है, पासवर्ड को रिवर्स-इंजीनियर करने के लिए पासवर्ड हैश की precompiled तालिकाओं का उपयोग करने के लिए हैकर्स के लिए कोई रास्ता नहीं है। PASSWORD_DEFAULTPHP के विकल्प और भविष्य के संस्करणों को अपने कोड को अपडेट किए बिना पासवर्ड हैश उत्पन्न करने के लिए स्वचालित रूप से मजबूत एल्गोरिदम का उपयोग करेंगे।


1

आपको openssl_encrypt()फ़ंक्शन का उपयोग करना चाहिए ।


क्या php 7 में खुलने वाले एन्क्रिप्ट को "हार्दिक" कहा गया है?
theCrazyProfurer

13
ओपी का उपयोग क्यों करना चाहिए? कुछ विवरण और पृष्ठभूमि दें
मार्टिन

0

मैं अपनी क्रिप्टो वस्तु का अनुवाद करने में सक्षम था

  • पुराने डेटा को डिक्रिप्ट करने के लिए mcrypt के साथ php की कॉपी प्राप्त करें। मैं http://php.net/get/php-7.1.12.tar.gz/from/a/mirror पर गया , इसे संकलित किया, फिर एक्सट्रीम / mcrypt एक्सटेंशन (कॉन्फ़िगर; मेक; इनस्टॉल;) जोड़ा। मुझे लगता है कि मुझे php.ini पर एक्स्टेंशन = mcrypt.so लाइन भी जोड़ना था। सभी अनएन्क्रिप्टेड डेटा के साथ डेटा के मध्यवर्ती संस्करण बनाने के लिए स्क्रिप्ट की एक श्रृंखला।

  • Opensl के लिए एक सार्वजनिक और निजी कुंजी बनाएँ

    openssl genrsa -des3 -out pkey.pem 2048
    (set a password)
    openssl rsa -in pkey.pem -out pkey-pub.pem -outform PEM -pubout
  • एन्क्रिप्ट करने के लिए (सार्वजनिक कुंजी का उपयोग करके) Opensl_seal का उपयोग करें। मैंने जो कुछ पढ़ा है, उससे RSA कुंजी का उपयोग करके खुलता है .sl_encrypt कुंजी लंबाई की तुलना में 11 बाइट्स तक सीमित है (देखें http://php.net/manual/en/function.openssl-public-encrypt.php थॉमस हॉर्स्टन की टिप्पणी)

    $pubKey = openssl_get_publickey(file_get_contents('./pkey-pub.pem'));
    openssl_seal($pwd, $sealed, $ekeys, [ $pubKey ]);
    $encryptedPassword = base64_encode($sealed);
    $key = base64_encode($ekeys[0]);

आप शायद कच्चे बाइनरी को स्टोर कर सकते हैं।

  • डिक्रिप्ट (निजी कुंजी का उपयोग करके)

    $passphrase="passphrase here";
    $privKey = openssl_get_privatekey(file_get_contents('./pkey.pem'), $passphrase);
    // I base64_decode() from my db columns
    openssl_open($encryptedPassword, $plain, $key, $privKey);
    echo "<h3>Password=$plain</h3>";

पुनश्च आप खाली स्ट्रिंग को एन्क्रिप्ट नहीं कर सकते ("")

PPS यह एक पासवर्ड डेटाबेस के लिए है जो उपयोगकर्ता सत्यापन के लिए नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.