आप PHP स्ट्रिंग को एन्क्रिप्ट और डिक्रिप्ट कैसे करते हैं?


225

मेरा कहने का तात्पर्य है:

Original String + Salt or Key --> Encrypted String
Encrypted String + Salt or Key --> Decrypted (Original String)

शायद कुछ इस तरह:

"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"
  • PHP में, आप यह कैसे कर सकते हैं?

उपयोग करने का प्रयास किया Crypt_Blowfish, लेकिन यह मेरे लिए काम नहीं किया।


35
@ रॉग वह एक हैश नहीं चाहता है, वह सममित एन्क्रिप्शन (जैसे एईएस) चाहता है, वह सिर्फ यह नहीं जानता कि इसे क्या कहा जाता है। (और अब वह करता है :))
पटाशू

कितना सुरक्षित होना चाहिए?

3
@ @ '劇場, आप' नमक 'सममित एन्क्रिप्शन नहीं करते हैं, आप एक कुंजी का उपयोग करते हैं। एक कुंजी को गुप्त रखा जाना चाहिए। सुरक्षा को नुकसान पहुंचाए बिना एक नमक सार्वजनिक हो सकता है (जब तक कि हर किसी का नमक अलग हो), और यह हैशिंग पासवर्ड में इस्तेमाल होने वाला शब्द है।
पाटशू

2
आपको एक साल्ट (निजी कुंजी), एक सार्वजनिक कुंजी एक एन्क्रिप्शन एल्गोरिथ्म जैसे AES-256: wpy.me/blog/15-encrypt-and-decrypt-data-in-php-use-aes-256
wappy

8
@CristianFlorea उस ब्लॉग पोस्ट के लेखक उन शब्दों का उपयोग करते हैं जो केवल सममित एन्क्रिप्शन के संदर्भ में थोड़ी सी समझदारी नहीं करते हैं। एईएस के साथ कोई सार्वजनिक कुंजी नहीं है, न ही नमक है। एक ही कुंजी है; इसे गुप्त रखना चाहिए। ऑपरेशन के कुछ तरीकों में एक IV है जिसे गुप्त होने की आवश्यकता नहीं है, लेकिन एक IV नमक नहीं है (मोड के आधार पर, इसकी काफी अलग आवश्यकताएं हो सकती हैं) और गुप्त नहीं होने की आवश्यकता है, जबकि वास्तविक एन्क्रिप्शन कुंजी बिल्कुल सार्वजनिक नहीं हो सकती है। सार्वजनिक / निजी कुंजी असममित क्रिप्टो पर लागू होती है, लेकिन एईएस से कोई लेना-देना नहीं है।
cpast

जवाबों:


410

इससे पहले कि आप आगे कुछ भी करें, एन्क्रिप्शन और प्रमाणीकरण के बीच के अंतर को समझने की कोशिश करें , और आप केवल एन्क्रिप्शन के बजाय प्रमाणित एन्क्रिप्शन क्यों चाहते हैं ।

प्रमाणित एन्क्रिप्शन को लागू करने के लिए, आप तब MAC एन्क्रिप्ट करना चाहते हैं। एन्क्रिप्शन और प्रमाणीकरण का क्रम बहुत महत्वपूर्ण है! इस प्रश्न के मौजूदा उत्तरों में से एक ने यह गलती की; के रूप में कई क्रिप्टोग्राफी पुस्तकालयों PHP में लिखा है।

आपको अपनी स्वयं की क्रिप्टोग्राफी को लागू करने से बचना चाहिए , और इसके बजाय क्रिप्टोग्राफी विशेषज्ञों द्वारा लिखित और समीक्षा की गई सुरक्षित लाइब्रेरी का उपयोग करना चाहिए ।

अद्यतन: PHP 7.2 अब libsodium प्रदान करता है ! सर्वोत्तम सुरक्षा के लिए, PHP 7.2 या उच्चतर का उपयोग करने के लिए अपने सिस्टम को अपडेट करें और केवल इस उत्तर में libsodium सलाह का पालन करें।

यदि आपके पास पीईसीएल पहुंच है (या सोडियम_कंपेट यदि आप पीईसीएल के बिना लिबासोडियम चाहते हैं) तो लिबासोडियम का उपयोग करें ; अन्यथा ...
डिफ्यूज़ / php-एन्क्रिप्शन का उपयोग करें ; अपनी खुद की क्रिप्टोग्राफी रोल न करें!

ऊपर लिंक किए गए दोनों पुस्तकालय आपके स्वयं के पुस्तकालयों में प्रमाणीकृत एन्क्रिप्शन को लागू करने के लिए आसान और दर्द रहित बनाते हैं।

यदि आप अभी भी अपनी क्रिप्टोग्राफी लाइब्रेरी लिखना और तैनात करना चाहते हैं, तो इंटरनेट पर हर क्रिप्टोग्राफी विशेषज्ञ के पारंपरिक ज्ञान के खिलाफ, ये कदम आपको उठाने होंगे।

एन्क्रिप्शन:

  1. CTR मोड में AES का उपयोग करके एन्क्रिप्ट करें। आप GCM का उपयोग भी कर सकते हैं (जो एक अलग मैक की आवश्यकता को हटा देता है)। इसके अतिरिक्त, ChaCha20 और Salsa20 ( libsodium द्वारा प्रदान किया गया ) ) धारा सिफर कर रहे हैं और विशेष मोड जरूरत नहीं है।
  2. जब तक आपने GCM को ऊपर नहीं चुना, तब तक आपको HMAC-SHA-256 (या, स्ट्रीम सिफर, Poly1305 के लिए - अधिकतर libsodium API आपके लिए ऐसा करते हैं) के साथ सिफरटेक्स्ट को प्रमाणित करना चाहिए। मैक को IV और साथ ही सिफरटेक्स को कवर करना चाहिए!

डिक्रिप्शन:

  1. जब तक Poly1305 या GCM का उपयोग नहीं किया जाता है, तब तक साइफरटेक्स्ट के मैक को पुनर्गणना करते हैं और मैक के साथ इसकी तुलना करते हैं। hash_equals() । यदि यह विफल रहता है, तो गर्भपात करें।
  2. संदेश को डिक्रिप्ट करें।

अन्य डिजाइन विचार:

  1. किसी भी चीज को कभी भी कंप्रेस न करें। सिफरटेक्स्ट कंप्रेसिबल नहीं है; एन्क्रिप्शन से पहले प्लेनटेक्स्ट को संपीड़ित करने से सूचना लीक हो सकती है (जैसे टीएलएस पर CRIME और BREACH)।
  2. सुनिश्चित करें कि आप उपयोग करते हैं mb_strlen()और mb_substr(), मुद्दों '8bit'को रोकने के लिए वर्ण सेट मोड का उपयोग कर रहे mbstring.func_overloadहैं।
  3. IVs को CSPRNG का उपयोग करके उत्पन्न किया जाना चाहिए ; यदि आप उपयोग कर रहे हैं mcrypt_create_iv(), तो उपयोग न करेंMCRYPT_RAND !
  4. जब तक आप एक AEAD निर्माण का उपयोग कर रहे हैं, तब हमेशा के लिए एन्क्रिप्ट करें MAC!
  5. bin2hex(), base64_encode()आदि कैश समय के माध्यम से अपने एन्क्रिप्शन कुंजी के बारे में जानकारी लीक कर सकते हैं। हो सके तो इनसे बचें।

यहां तक ​​कि अगर आप यहां दी गई सलाह का पालन करते हैं, तो क्रिप्टोग्राफी के साथ बहुत कुछ गलत हो सकता है। हमेशा एक क्रिप्टोग्राफी विशेषज्ञ आपके कार्यान्वयन की समीक्षा करें। यदि आप अपने स्थानीय विश्वविद्यालय में क्रिप्टोग्राफी के छात्र के साथ व्यक्तिगत दोस्त बनने के लिए भाग्यशाली नहीं हैं, तो आप सलाह के लिए क्रिप्टोग्राफी स्टैक एक्सचेंज फोरम की कोशिश कर सकते हैं ।

यदि आपको अपने कार्यान्वयन के पेशेवर विश्लेषण की आवश्यकता है, तो आप हमेशा अपने PHP क्रिप्टोग्राफी कोड (प्रकटीकरण: मेरे नियोक्ता) की समीक्षा करने के लिए सुरक्षा सलाहकारों की एक प्रतिष्ठित टीम को नियुक्त कर सकते हैं ।

महत्वपूर्ण: जब एन्क्रिप्शन का उपयोग न करें

पासवर्ड एन्क्रिप्ट न करें । आपइन पासवर्ड-हैशिंग एल्गोरिदम में से एक का उपयोग करते हुए, उन्हें हैश करना चाहते हैं:

पासवर्ड भंडारण के लिए कभी भी सामान्य-उद्देश्य वाले हैश फ़ंक्शन (MD5, SHA256) का उपयोग न करें।

URL पैरामीटर्स को एन्क्रिप्ट न करेंयह काम का गलत साधन है।

Libsodium के साथ PHP स्ट्रिंग एन्क्रिप्शन का उदाहरण

यदि आप PHP <7.2 पर हैं या अन्यथा लिबासोडियम स्थापित नहीं है, तो आप उसी परिणाम को पूरा करने के लिए Sodium_compat का उपयोग कर सकते हैं (यद्यपि धीमी गति से)।

<?php
declare(strict_types=1);

/**
 * Encrypt a message
 * 
 * @param string $message - message to encrypt
 * @param string $key - encryption key
 * @return string
 * @throws RangeException
 */
function safeEncrypt(string $message, string $key): string
{
    if (mb_strlen($key, '8bit') !== SODIUM_CRYPTO_SECRETBOX_KEYBYTES) {
        throw new RangeException('Key is not the correct size (must be 32 bytes).');
    }
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);

    $cipher = base64_encode(
        $nonce.
        sodium_crypto_secretbox(
            $message,
            $nonce,
            $key
        )
    );
    sodium_memzero($message);
    sodium_memzero($key);
    return $cipher;
}

/**
 * Decrypt a message
 * 
 * @param string $encrypted - message encrypted with safeEncrypt()
 * @param string $key - encryption key
 * @return string
 * @throws Exception
 */
function safeDecrypt(string $encrypted, string $key): string
{   
    $decoded = base64_decode($encrypted);
    $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');

    $plain = sodium_crypto_secretbox_open(
        $ciphertext,
        $nonce,
        $key
    );
    if (!is_string($plain)) {
        throw new Exception('Invalid MAC');
    }
    sodium_memzero($ciphertext);
    sodium_memzero($key);
    return $plain;
}

फिर इसका परीक्षण करने के लिए:

<?php
// This refers to the previous code block.
require "safeCrypto.php"; 

// Do this once then store it somehow:
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
$message = 'We are all living in a yellow submarine';

$ciphertext = safeEncrypt($message, $key);
$plaintext = safeDecrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);

हैलाइट - लिबसोडियम मेड ईज़ीयर

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

<?php
use \ParagonIE\Halite\KeyFactory;
use \ParagonIE\Halite\Symmetric\Crypto as SymmetricCrypto;

// Generate a new random symmetric-key encryption key. You're going to want to store this:
$key = new KeyFactory::generateEncryptionKey();
// To save your encryption key:
KeyFactory::save($key, '/path/to/secret.key');
// To load it again:
$loadedkey = KeyFactory::loadEncryptionKey('/path/to/secret.key');

$message = 'We are all living in a yellow submarine';
$ciphertext = SymmetricCrypto::encrypt($message, $key);
$plaintext = SymmetricCrypto::decrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);

अंतर्निहित क्रिप्टोग्राफी के सभी को libsodium द्वारा नियंत्रित किया जाता है।

डिफ्यूज / php-एन्क्रिप्शन के साथ उदाहरण

<?php
/**
 * This requires https://github.com/defuse/php-encryption
 * php composer.phar require defuse/php-encryption
 */

use Defuse\Crypto\Crypto;
use Defuse\Crypto\Key;

require "vendor/autoload.php";

// Do this once then store it somehow:
$key = Key::createNewRandomKey();

$message = 'We are all living in a yellow submarine';

$ciphertext = Crypto::encrypt($message, $key);
$plaintext = Crypto::decrypt($ciphertext, $key);

var_dump($ciphertext);
var_dump($plaintext);

नोट : Crypto::encrypt()हेक्स-एन्कोडेड आउटपुट देता है।

एन्क्रिप्शन कुंजी प्रबंधन

यदि आप "पासवर्ड" का उपयोग करने के लिए ललचा रहे हैं, तो अभी रुकें। आपको एक यादृच्छिक 128-बिट एन्क्रिप्शन कुंजी की आवश्यकता है, न कि मानव यादगार पासवर्ड।

आप लंबे समय तक उपयोग के लिए एन्क्रिप्शन कुंजी स्टोर कर सकते हैं जैसे:

$storeMe = bin2hex($key);

और, मांग पर, आप इसे पुनः प्राप्त कर सकते हैं:

$key = hex2bin($storeMe);

मैं दृढ़ता से सलाह देता हूं कि किसी भी प्रकार के पासवर्ड की कुंजी (या कुंजी को प्राप्त करने के लिए) के बजाय दीर्घकालिक उपयोग के लिए एक यादृच्छिक रूप से उत्पन्न कुंजी को संग्रहीत करें।

यदि आप Defuse के पुस्तकालय का उपयोग कर रहे हैं:

"लेकिन मैं वास्तव में एक पासवर्ड का उपयोग करना चाहता हूं ।"

यह एक बुरा विचार है, लेकिन ठीक है, यहां इसे सुरक्षित तरीके से कैसे किया जाए।

सबसे पहले, एक यादृच्छिक कुंजी उत्पन्न करें और इसे एक स्थिर में संग्रहीत करें।

/**
 * Replace this with your own salt! 
 * Use bin2hex() then add \x before every 2 hex characters, like so:
 */
define('MY_PBKDF2_SALT', "\x2d\xb7\x68\x1a\x28\x15\xbe\x06\x33\xa0\x7e\x0e\x8f\x79\xd5\xdf");

ध्यान दें कि आप अतिरिक्त काम जोड़ रहे हैं और कुंजी के रूप में इस स्थिरांक का उपयोग कर सकते हैं और अपने आप को बहुत सारे दिल का दर्द बचा सकते हैं!

फिर सीधे अपने पासवर्ड से एन्क्रिप्ट करने के बजाय अपने पासवर्ड से उपयुक्त एन्क्रिप्शन कुंजी प्राप्त करने के लिए PBKDF2 (जैसे कि) का उपयोग करें।

/**
 * Get an AES key from a static password and a secret salt
 * 
 * @param string $password Your weak password here
 * @param int $keysize Number of bytes in encryption key
 */
function getKeyFromPassword($password, $keysize = 16)
{
    return hash_pbkdf2(
        'sha256',
        $password,
        MY_PBKDF2_SALT,
        100000, // Number of iterations
        $keysize,
        true
    );
}

केवल 16-वर्ण पासवर्ड का उपयोग न करें। आपकी एन्क्रिप्शन कुंजी हास्य रूप से टूट जाएगी।


3
पासवर्ड एन्क्रिप्ट न करें , उनके साथ हैश करें password_hash()और उनके साथ जांचें password_verify()
स्कॉट आर्किसेवस्की

2
"कभी भी कुछ भी संपीड़ित न करें।" आप HTTP, स्पडी और अन्य प्रोटोकॉल की तरह मतलब है? टीएलएस से पहले? निरपेक्षवादी सलाह?
टिबेरिउ-आयनो स्टैन

1
@ScottArciszewski मुझे कुंजी के बारे में आपकी टिप्पणी पसंद है "// क्या यह एक बार इसे किसी भी तरह से स्टोर करें:" .. किसी तरह, योग्य :)) अच्छी तरह से इस 'कुंजी' (जो वस्तु है) को सादे स्ट्रिंग, हार्डकोड के रूप में संग्रहीत करने के बारे में कैसे? मुझे एक स्ट्रिंग के रूप में कुंजी की आवश्यकता है। क्या मैं इसे किसी भी तरह से इस वस्तु से प्राप्त कर सकता हूं? धन्यवाद
एंड्रयू

2
Thx, मुझे आपके सोडियम उदाहरणों को काम करने के लिए सिर्फ एक पंक्ति को संशोधित करना था:function getKeyFromPassword($password, $keysize = \Sodium\CRYPTO_SECRETBOX_KEYBYTES)
अलेक्सई ओज़ेरोव

1
वाह! URL पैरामीटर को एन्क्रिप्ट नहीं करने का उल्लेख करने के लिए +1। मुझे वास्तव में आपके द्वारा प्रदान किया गया लेख पसंद आया: paragonie.com/blog/2015/09/…
Lynnell Emmanuel Neri

73

मुझे पार्टी के लिए देर हो रही है, लेकिन इसे करने का सही तरीका खोज रहा हूं, जो इस पृष्ठ पर आया, यह शीर्ष Google खोज रिटर्न में से एक था, इसलिए मैं समस्या पर अपना विचार साझा करना चाहूंगा, जिसे मैं इसे मानता हूं इस पोस्ट को लिखने के समय तक की तारीख (2017 की शुरुआत)। PHP 7.1.0 से mcrypt_decryptऔर mcrypt_encryptपदावनत होने जा रहा है, इसलिए भविष्य के प्रूफ कोड का निर्माण ओपनस्ले_एन्क्रिप्ट और ओप्सनल_डेकक्रिप्ट का उपयोग करना चाहिए

आप कुछ ऐसा कर सकते हैं:

$string_to_encrypt="Test";
$password="password";
$encrypted_string=openssl_encrypt($string_to_encrypt,"AES-128-ECB",$password);
$decrypted_string=openssl_decrypt($encrypted_string,"AES-128-ECB",$password);

महत्वपूर्ण : यह ईसीबी मोड का उपयोग करता है , जो सुरक्षित नहीं है। यदि आप क्रिप्टोग्राफी इंजीनियरिंग में क्रैश कोर्स किए बिना एक सरल समाधान चाहते हैं, तो इसे स्वयं न लिखें, बस एक पुस्तकालय का उपयोग करें।

आप अपनी सुरक्षा की जरूरत के आधार पर किसी भी अन्य chipper विधियों का उपयोग कर सकते हैं। उपलब्ध टिपर विधियों का पता लगाने के लिए कृपया खुलता है seesl_get_cipher_methods फ़ंक्शन।


10
धन्यवाद, मुझे आश्चर्य है कि यह सरल और स्पष्ट उत्तर अधिक उत्कीर्ण नहीं है। मैं इस विषय पर एक 10 पृष्ठों की चर्चा नहीं पढ़ सकता, जैसे शीर्ष उत्तर जब मैं चाहता हूं कि एक सरल स्ट्रिंग एन्क्रिप्ट / डिक्रिप्ट हो।
लॉरेंट

4
यह एक सुरक्षित उत्तर नहीं है। ईसीबी मोड का उपयोग नहीं किया जाना चाहिए। यदि आप "सरल और स्पष्ट उत्तर" चाहते हैं, तो बस एक पुस्तकालय का उपयोग करें
स्कॉट आर्किसेवस्की

2
@ScottArciszewski, हाँ, मैं मानता हूँ कि मैंने कुछ सरल कोड की तलाश करते हुए बहुत तेज़ी से बात की है। मैंने तब से एक IV जोड़ा और CBC का उपयोग अपने कोड में किया, जो मेरे उपयोग के लिए काफी अच्छा है।
laurent

इसे पढ़ें और पुनर्विचार करें । सीबीसी मोड के साथ, एक हमलावर पूरी तरह से संदेश को बदल सकता है। यदि संदेश एक फ़ाइल है, तो एक हमलावर बिट्स और पॉप calc.exe फ्लिप कर सकता है। अप्रमाणित एन्क्रिप्शन के जोखिम गंभीर हैं।
स्कॉट आर्किसेवस्की

7
यह सब उपयोग के मामले पर निर्भर करता है! ऐसे मामले हैं जब यह पूरी तरह से ठीक है। उदाहरण के लिए, मैं पेज से पेज पर एक जीईटी पैरामीटर पास करना चाहता हूं, मान लीजिए, prod_id=123लेकिन मैं हर किसी के लिए 123 पठनीय नहीं बनाना चाहता हूं, हालांकि अगर वे इसे पढ़ सकते हैं, तो भी यह समस्या नहीं होगी। एक हमलावर को कस्टम मूल्य में 123 को बदलने में सक्षम होने के कारण कोई नुकसान नहीं होगा, वह / वह केवल किसी अन्य उत्पाद का विवरण प्राप्त करने में सक्षम होगा, लेकिन जो औसत उपयोगकर्ता के पास विवरण प्राप्त करने के बारे में कोई सुराग नहीं होगा उदाहरण के लिए उत्पाद 124। इस तरह के परिदृश्य के लिए, यह एक सही समाधान है, सुरक्षा के लिए यह एक नहीं है!
एमिल बोरकोनी

43

क्या नहीं कर सकते है

चेतावनी:
यह उत्तर ईसीबी का उपयोग करता है । ईसीबी एक एन्क्रिप्शन मोड नहीं है, यह केवल एक बिल्डिंग ब्लॉक है। इस उत्तर में प्रदर्शित ईसीबी का उपयोग वास्तव में स्ट्रिंग को सुरक्षित रूप से एन्क्रिप्ट नहीं करता है। अपने कोड में ईसीबी का उपयोग न करें। अच्छे समाधान के लिए स्कॉट का जवाब देखें ।

मैंने इसे अपने ऊपर पा लिया। वास्तव में मुझे Google पर कुछ उत्तर मिले और कुछ संशोधित किए गए।हालांकि परिणाम पूरी तरह असुरक्षित है।

<?php
define("ENCRYPTION_KEY", "!@#$%^&*");
$string = "This is the original data string!";

echo $encrypted = encrypt($string, ENCRYPTION_KEY);
echo "<br />";
echo $decrypted = decrypt($encrypted, ENCRYPTION_KEY);

/**
 * Returns an encrypted & utf8-encoded
 */
function encrypt($pure_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, utf8_encode($pure_string), MCRYPT_MODE_ECB, $iv);
    return $encrypted_string;
}

/**
 * Returns decrypted original string
 */
function decrypt($encrypted_string, $encryption_key) {
    $iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    $decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $encryption_key, $encrypted_string, MCRYPT_MODE_ECB, $iv);
    return $decrypted_string;
}
?>

8
आप अधिक सुरक्षा सुनिश्चित करने के लिए "MCRYPT_MODE_ECB" के बजाय "MCRYPT_MODE_CBC" का उपयोग कर सकते हैं।
Parixit

10
रमेश, इसका कारण यह है कि आप कच्चे एन्क्रिप्टेड डेटा प्राप्त कर रहे हैं। आप इस तरह से base64 का उपयोग करके एन्क्रिप्टेड डेटा का एक अच्छा संस्करण प्राप्त कर सकते हैं: base64_encode(encrypt($string))- इसे डिक्रिप्ट करने के लिए:decrypt(base64_decode($encrypted))
mendezcode

82
चेतावनी: यह असुरक्षित है । ईसीबी मोड का उपयोग स्ट्रिंग्स के लिए नहीं किया जाना चाहिए, ईसीबी एक आईवी नहीं लेता है, यह प्रमाणित नहीं है, यह एईएस के बजाय एक पुराने सिफर (ब्लोफिश) का उपयोग करता है, कुंजी द्विआधारी आदि नहीं है । एसओ समुदाय को वास्तव में एन्क्रिप्शन को रोकना चाहिए। / डिक्रिप्शन जो सिर्फ "काम" करता है और उन उत्तरों को उभारना शुरू करता है जो सुरक्षित होने के लिए जाने जाते हैं। अगर आपको पता नहीं है कि यकीन है, तो वोट न करें।
मार्टन बॉड्यूज 23

3
मैंने इस तरह का पहले से ही mcrypt_encryptप्रतिस्थापित कोड का नमूना कोड : php.net/manual/en/function.mcrypt-encrypt.php किया था । ध्यान दें कि अब इसकी समीक्षा करना संभवत: अंत में rtrimचरित्र के लिए होना चाहिए "\0"
Maarten Bodewes

4
सही उत्तर यह है कि अपने स्वयं के mcrypt कोड लिखने के बजाय डिफ्यूज़ / php-एन्क्रिप्शन जैसी किसी चीज़ का उपयोग करें ।
स्कॉट आर्किसेवस्की

18

लारवेल फ्रेमवर्क के लिए

यदि आप लारवेल फ्रेमवर्क का उपयोग कर रहे हैं तो आंतरिक कार्यों के साथ एन्क्रिप्ट और डिक्रिप्ट करना अधिक आसान है।

$string = 'Some text to be encrypted';
$encrypted = \Illuminate\Support\Facades\Crypt::encrypt($string);
$decrypted_string = \Illuminate\Support\Facades\Crypt::decrypt($encrypted);

var_dump($string);
var_dump($encrypted);
var_dump($decrypted_string);

नोट: config / app.php फ़ाइल के प्रमुख विकल्प में 16, 24 या 32 वर्ण का यादृच्छिक स्ट्रिंग सेट करना सुनिश्चित करें। अन्यथा, एन्क्रिप्ट किए गए मान सुरक्षित नहीं होंगे।


1
यकीन है, यह प्रयोग करने में आसान हो सकता है। लेकिन क्या यह सुरक्षित है? यह कैसे stackoverflow.com/a/30159120/781723 में मुद्दों को संबोधित करता है ? क्या यह प्रमाणित एन्क्रिप्शन का उपयोग करता है? क्या यह साइड चैनल भेद्यता से बचता है और निरंतर समय की समानता की जांच सुनिश्चित करता है क्या यह पासवर्ड / पासफ़्रेज़ के बजाय वास्तव में यादृच्छिक कुंजी का उपयोग करता है? क्या यह ऑपरेशन के एक उपयुक्त मोड का उपयोग करता है? क्या यह यादृच्छिक IV का ठीक से उत्पादन करता है?
डीडब्ल्यू

10

अपडेट किया गया

PHP 7 तैयार संस्करण। यह PHP OpenSSL लाइब्रेरी से Opensl_encrypt फ़ंक्शन का उपयोग करता है ।

class Openssl_EncryptDecrypt {
    function encrypt ($pure_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext_raw = openssl_encrypt($pure_string, $cipher, $encryption_key, $options, $iv);
        $hmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        return $iv.$hmac.$ciphertext_raw;
    }
    function decrypt ($encrypted_string, $encryption_key) {
        $cipher     = 'AES-256-CBC';
        $options    = OPENSSL_RAW_DATA;
        $hash_algo  = 'sha256';
        $sha2len    = 32;
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = substr($encrypted_string, 0, $ivlen);
        $hmac = substr($encrypted_string, $ivlen, $sha2len);
        $ciphertext_raw = substr($encrypted_string, $ivlen+$sha2len);
        $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $encryption_key, $options, $iv);
        $calcmac = hash_hmac($hash_algo, $ciphertext_raw, $encryption_key, true);
        if(function_exists('hash_equals')) {
            if (hash_equals($hmac, $calcmac)) return $original_plaintext;
        } else {
            if ($this->hash_equals_custom($hmac, $calcmac)) return $original_plaintext;
        }
    }
    /**
     * (Optional)
     * hash_equals() function polyfilling.
     * PHP 5.6+ timing attack safe comparison
     */
    function hash_equals_custom($knownString, $userString) {
        if (function_exists('mb_strlen')) {
            $kLen = mb_strlen($knownString, '8bit');
            $uLen = mb_strlen($userString, '8bit');
        } else {
            $kLen = strlen($knownString);
            $uLen = strlen($userString);
        }
        if ($kLen !== $uLen) {
            return false;
        }
        $result = 0;
        for ($i = 0; $i < $kLen; $i++) {
            $result |= (ord($knownString[$i]) ^ ord($userString[$i]));
        }
        return 0 === $result;
    }
}

define('ENCRYPTION_KEY', '__^%&Q@$&*!@#$%^&*^__');
$string = "This is the original string!";

$OpensslEncryption = new Openssl_EncryptDecrypt;
$encrypted = $OpensslEncryption->encrypt($string, ENCRYPTION_KEY);
$decrypted = $OpensslEncryption->decrypt($encrypted, ENCRYPTION_KEY);

1
यह बेहतर और ज्यादा सुरक्षित संस्करण है। धन्यवाद, यह अपेक्षा के अनुरूप भी काम करता है।

1
आप कैसे बनाते हैं और आप एन्क्रिप्शन कुंजी कहाँ रखते हैं?
user2800464

7

ऐतिहासिक नोट: यह PHP4 के समय लिखा गया था। इसे अब हम "विरासत कोड" कहते हैं।

मैंने इस उत्तर को ऐतिहासिक उद्देश्यों के लिए छोड़ दिया है - लेकिन कुछ तरीकों को अब हटा दिया गया है, डेस एन्क्रिप्शन विधि एक अनुशंसित अभ्यास नहीं है, आदि।

मैंने इस कोड को दो कारणों से अपडेट नहीं किया है: 1) मैं अब PHP में हाथ से एन्क्रिप्शन विधियों के साथ काम नहीं करता हूं, और 2) यह कोड अभी भी उस उद्देश्य को पूरा करता है जो इसके लिए उद्देश्य था: एन्क्रिप्शन कैसे काम कर सकता है, इसकी न्यूनतम, सरल अवधारणा को प्रदर्शित करने के लिए: PHP में।

यदि आप एक समान रूप से सरल, "dummies के लिए PHP एन्क्रिप्शन" स्रोत का पता लगा सकते हैं जो लोगों को कोड के 10-20 लाइनों या उससे कम में शुरू कर सकता है, तो मुझे टिप्पणियों में बताएं।

इसके अलावा, कृपया शुरुआती दौर के PHP4 न्यूनतर एन्क्रिप्शन उत्तर के इस क्लासिक एपिसोड का आनंद लें।


आदर्श रूप से आपके पास - या मिल सकती है - mcrypt PHP लाइब्रेरी की पहुंच, इसके निश्चित रूप से लोकप्रिय और बहुत उपयोगी कार्यों के रूप में। यहां विभिन्न प्रकार के एन्क्रिप्शन और कुछ उदाहरण कोड का एक रन डाउन है: PHP में एन्क्रिप्शन तकनीक

//Listing 3: Encrypting Data Using the mcrypt_ecb Function 

<?php 
echo("<h3> Symmetric Encryption </h3>"); 
$key_value = "KEYVALUE"; 
$plain_text = "PLAINTEXT"; 
$encrypted_text = mcrypt_ecb(MCRYPT_DES, $key_value, $plain_text, MCRYPT_ENCRYPT); 
echo ("<p><b> Text after encryption : </b>"); 
echo ( $encrypted_text ); 
$decrypted_text = mcrypt_ecb(MCRYPT_DES, $key_value, $encrypted_text, MCRYPT_DECRYPT); 
echo ("<p><b> Text after decryption : </b>"); 
echo ( $decrypted_text ); 
?> 

कुछ चेतावनियाँ:

1) जब एक-तरफ़ा हैश करेगा तो कभी भी प्रतिवर्ती या "सममित" एन्क्रिप्शन का उपयोग न करें।

2) यदि डेटा वास्तव में संवेदनशील है, जैसे क्रेडिट कार्ड या सामाजिक सुरक्षा नंबर, बंद करो; आपको किसी भी साधारण से अधिक कोड की आवश्यकता होगी, बल्कि आपको इस उद्देश्य के लिए डिज़ाइन की गई एक क्रिप्टो लाइब्रेरी और आवश्यक तरीकों का अनुसंधान करने के लिए पर्याप्त समय चाहिए। इसके अलावा, सॉफ्टवेयर क्रिप्टो संभवतः संवेदनशील डेटा की सुरक्षा का 10% है। यह एक परमाणु ऊर्जा स्टेशन को फिर से शुरू करने जैसा है - स्वीकार करें कि यदि यह मामला खतरनाक और कठिन है और आपके ज्ञान से परे है। वित्तीय दंड बहुत अधिक हो सकता है, इसलिए एक सेवा का उपयोग करना बेहतर है और उनके लिए ज़िम्मेदारी है।

3) किसी भी प्रकार का आसानी से लागू होने वाला एन्क्रिप्शन, जैसा कि यहां सूचीबद्ध है, हल्के ढंग से महत्वपूर्ण जानकारी की रक्षा कर सकता है जो आप आकस्मिक आँखों से रखना चाहते हैं या आकस्मिक / जानबूझकर रिसाव के मामले में जोखिम को सीमित करते हैं। लेकिन यह देखते हुए कि वेब सर्वर पर सादे पाठ में कुंजी कैसे संग्रहीत की जाती है, यदि वे डेटा प्राप्त कर सकते हैं तो वे डिक्रिप्शन कुंजी प्राप्त कर सकते हैं।

हो सकता है कि जैसा भी हो, मज़े करें :)


9
Eww, डेस। एईएस कहां है?
पताशु

2
धन्यवाद! लेकिन कुछ मुद्दे। मुझे M�������f=�_=एन्क्रिप्टेड के रूप में अजीब चरित्र मिल रहे हैं । क्या मुझे साधारण पात्र नहीं मिल सकते? जैसा: 2a2ffa8f13220befbe30819047e23b2c। इसके अलावा, मैं $key_value(8 ??? तय) और उत्पादन की लंबाई को बदल नहीं सकता $encrypted_text? (यह 32 या 64 लंबा या जो भी लंबा नहीं हो सकता है ??)
期 劇場

3
@ @ Data encryption एन्क्रिप्शन का परिणाम द्विआधारी डेटा है। यदि आपको मानव पठनीय होने की आवश्यकता है, तो उस पर base64 या हेक्स एन्कोडिंग का उपयोग करें। 'क्या मैं महत्वपूर्ण मूल्य की लंबाई नहीं बदल सकता?' अलग-अलग सममित एन्क्रिप्शन एल्गोरिदम में महत्वपूर्ण मूल्य के लिए अलग-अलग आवश्यकताएं हैं। 'और आउटपुट की लंबाई ...' एन्क्रिप्टेड पाठ की लंबाई मूल पाठ के रूप में कम से कम लंबे समय के रूप में होना चाहिए, या मूल पाठ को फिर से बनाने के लिए पर्याप्त जानकारी नहीं है। (यह कबूतर सिद्धांत का एक अनुप्रयोग है।) BTW, आपको डेस के बजाय एईएस का उपयोग करना चाहिए। डेस आसानी से टूटने योग्य है और अब सुरक्षित नहीं है।
पताशु

8
mcrypt_ecb को PHP 5.5.0 के रूप में परिभाषित किया गया है क्योंकि इस फ़ंक्शन पर निर्भर होना बहुत हतोत्साहित करता है। php.net/manual/en/function.mcrypt-ecb.php
Hafez

1
@BrianDHall इसका कारण यह है कि वोट अभी भी नीचे है क्योंकि ECB मोड सुरक्षित नहीं है (CBC, CTR, GCM, या Poly1305 का उपयोग करें), DES कमजोर है (आप एईएस चाहते हैं, जो है MCRYPT_RIJNDAEL_128), और सिफरटेक्स को प्रमाणित ( hash_hmac(), सत्यापित ) किया जाना चाहिए के साथ hash_equals())।
स्कॉट आर्किसेवस्की

7

यदि आप लाइब्रेरी (जो आपको चाहिए) का उपयोग नहीं करना चाहते हैं तो कुछ इस तरह से उपयोग करें (PHP 7):

function sign($message, $key) {
    return hash_hmac('sha256', $message, $key) . $message;
}

function verify($bundle, $key) {
    return hash_equals(
      hash_hmac('sha256', mb_substr($bundle, 64, null, '8bit'), $key),
      mb_substr($bundle, 0, 64, '8bit')
    );
}

function getKey($password, $keysize = 16) {
    return hash_pbkdf2('sha256',$password,'some_token',100000,$keysize,true);
}

function encrypt($message, $password) {
    $iv = random_bytes(16);
    $key = getKey($password);
    $result = sign(openssl_encrypt($message,'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv), $key);
    return bin2hex($iv).bin2hex($result);
}

function decrypt($hash, $password) {
    $iv = hex2bin(substr($hash, 0, 32));
    $data = hex2bin(substr($hash, 32));
    $key = getKey($password);
    if (!verify($data, $key)) {
      return null;
    }
    return openssl_decrypt(mb_substr($data, 64, null, '8bit'),'aes-256-ctr',$key,OPENSSL_RAW_DATA,$iv);
}

$string_to_encrypt='John Smith';
$password='password';
$encrypted_string=encrypt($string_to_encrypt, $password);
$decrypted_string=decrypt($encrypted_string, $password);

क्या यह stackoverflow.com/a/16606352/126833 पर प्रतिस्थापन हो सकता है ? मैंने पूर्व का उपयोग किया है जब तक कि मेरा होस्ट PHP 7.2 में अपग्रेड न हो जाए।
अंजनेश

@ananesh आप इस एक के साथ पुराने डेटा को डिक्रिप्ट नहीं कर पाएंगे (विभिन्न एल्गोरिदम + यह एक भी हस्ताक्षर की जांच करता है)
एस्कॉन

2
आपके मामले में शायद ऐसा करना चाहिए:define("ENCRYPTION_KEY", "123456*"); $string = "This is the original data string!"; $encrypted = openssl_encrypt($string, 'BF-ECB', ENCRYPTION_KEY); $decrypted = openssl_decrypt($encrypted,'BF-ECB',ENCRYPTION_KEY);
एस्कॉन

यह सुपर है!
अंजनेश

2

ये PHP का उपयोग करके स्ट्रिंग को एन्क्रिप्ट / डिक्रिप्ट करने के लिए कॉम्पैक्ट तरीके हैं AES256 CBC :

function encryptString($plaintext, $password, $encoding = null) {
    $iv = openssl_random_pseudo_bytes(16);
    $ciphertext = openssl_encrypt($plaintext, "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, $iv);
    $hmac = hash_hmac('sha256', $ciphertext.$iv, hash('sha256', $password, true), true);
    return $encoding == "hex" ? bin2hex($iv.$hmac.$ciphertext) : ($encoding == "base64" ? base64_encode($iv.$hmac.$ciphertext) : $iv.$hmac.$ciphertext);
}

function decryptString($ciphertext, $password, $encoding = null) {
    $ciphertext = $encoding == "hex" ? hex2bin($ciphertext) : ($encoding == "base64" ? base64_decode($ciphertext) : $ciphertext);
    if (!hash_equals(hash_hmac('sha256', substr($ciphertext, 48).substr($ciphertext, 0, 16), hash('sha256', $password, true), true), substr($ciphertext, 16, 32))) return null;
    return openssl_decrypt(substr($ciphertext, 48), "AES-256-CBC", hash('sha256', $password, true), OPENSSL_RAW_DATA, substr($ciphertext, 0, 16));
}

उपयोग:

$enc = encryptString("mysecretText", "myPassword");
$dec = decryptString($enc, "myPassword");

0

विशेष चरित्र के साथ सभी स्ट्रिंग के लिए पीएचपी में कोड काम के नीचे

   // Encrypt text --

    $token = "9611222007552";

      $cipher_method = 'aes-128-ctr';
      $enc_key = openssl_digest(php_uname(), 'SHA256', TRUE);  
      $enc_iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher_method));  
      $crypted_token = openssl_encrypt($token, $cipher_method, $enc_key, 0, $enc_iv) . "::" . bin2hex($enc_iv);
    echo    $crypted_token;
    //unset($token, $cipher_method, $enc_key, $enc_iv);

    // Decrypt text  -- 

    list($crypted_token, $enc_iv) = explode("::", $crypted_token);  
      $cipher_method = 'aes-128-ctr';
      $enc_key = openssl_digest(php_uname(), 'SHA256', TRUE);
      $token = openssl_decrypt($crypted_token, $cipher_method, $enc_key, 0, hex2bin($enc_iv));
    echo   $token;
    //unset($crypted_token, $cipher_method, $enc_key, $enc_iv);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.