Come crittografare e decrittografare una stringa PHP?


225

Ciò che voglio dire è:

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

Forse qualcosa del tipo:

"hello world!" + "ABCD1234" --> Encrypt --> "2a2ffa8f13220befbe30819047e23b2c" (may be, for e.g)
"2a2ffa8f13220befbe30819047e23b2c" --> Decrypt with "ABCD1234" --> "hello world!"
  • In PHP, come puoi farlo?

Tentativo di utilizzare Crypt_Blowfish, ma non ha funzionato per me.


35
@Rogue Non vuole un hash, vuole una crittografia simmetrica (come AES), semplicemente non sa come si chiama. (E ora lo fa :))
Patashu

quanto deve essere sicuro?

3
@ 夏 期 劇場, Non si 'sale' la crittografia simmetrica, si utilizza una chiave. Una chiave deve essere tenuta segreta. Un sale può essere pubblico senza nuocere alla sicurezza (purché il sale di tutti sia diverso) ed è un termine usato nelle password di hashing.
Patashu,

2
Hai bisogno di una Salt (chiave privata), una chiave pubblica e un algoritmo di crittografia come AES-256: wpy.me/blog/15-encrypt-and-decrypt-data-in-php-using-aes-256
wappy

8
@CristianFlorea L'autore di quel post sul blog usa termini che semplicemente non hanno il minimo senso nel contesto della crittografia simmetrica. Non esiste una chiave pubblica con AES, né c'è un sale. C'è una sola chiave; deve essere tenuto segreto. In alcune modalità operative esiste un IV che non deve necessariamente essere segreto, ma un IV non è un problema (a seconda della modalità, può avere requisiti abbastanza diversi) e non deve essere segreto, mentre la chiave di crittografia effettiva non può assolutamente essere pubblica. La chiave pubblica / privata si applica alla crittografia asimmetrica, ma non ha nulla a che fare con AES.
venerdì

Risposte:


410

Prima di fare qualsiasi altra cosa, cerca di capire la differenza tra crittografia e autenticazione e perché probabilmente desideri la crittografia autenticata anziché solo la crittografia .

Per implementare la crittografia autenticata, si desidera crittografare quindi MAC. L'ordine di crittografia e autenticazione è molto importante! Una delle risposte esistenti a questa domanda ha fatto questo errore; come fanno molte librerie di crittografia scritte in PHP.

Dovresti evitare di implementare la tua crittografia e invece utilizzare una libreria sicura scritta e rivista da esperti di crittografia.

Aggiornamento: PHP 7.2 ora fornisce libsodium ! Per la massima sicurezza, aggiorna i tuoi sistemi per utilizzare PHP 7.2 o versioni successive e segui solo i consigli di libsodium in questa risposta.

Utilizzare libsodium se si dispone dell'accesso PECL (o sodium_compat se si desidera libsodium senza PECL); altrimenti ...
Usa crittografia disuso / php ; non girare la tua crittografia!

Entrambe le librerie collegate sopra rendono facile e indolore implementare la crittografia autenticata nelle proprie librerie.

Se vuoi ancora scrivere e distribuire la tua libreria di crittografia, contro la saggezza convenzionale di ogni esperto di crittografia su Internet, questi sono i passi che dovresti prendere.

crittografia:

  1. Crittografare utilizzando AES in modalità CTR. È inoltre possibile utilizzare GCM (che elimina la necessità di un MAC separato). Inoltre, ChaCha20 e Salsa20 (forniti da libsodium ) sono cifre di stream e non necessitano di modalità speciali.
  2. A meno che tu non abbia scelto GCM sopra, dovresti autenticare il testo cifrato con HMAC-SHA-256 (o, per i stream stream, Poly1305 - la maggior parte delle API libsodium lo fa per te). Il MAC dovrebbe coprire il IV così come il testo cifrato!

decrittazione:

  1. A meno che non venga utilizzato Poly1305 o GCM, ricalcolare il MAC del testo cifrato e confrontarlo con il MAC inviato hash_equals(). Se fallisce, interrompere.
  2. Decifrare il messaggio.

Altre considerazioni sulla progettazione:

  1. Non comprimere mai niente. Il testo cifrato non è comprimibile; la compressione del testo in chiaro prima della crittografia può causare perdite di informazioni (ad esempio CRIME e BREACH su TLS).
  2. Assicurati di usare mb_strlen()e mb_substr(), usando la '8bit'modalità set di caratteri per evitare mbstring.func_overloadproblemi.
  3. I IV dovrebbero essere generati usando un CSPRNG ; Se stai usando mcrypt_create_iv(), NON USAREMCRYPT_RAND !
  4. A meno che non si stia utilizzando un costrutto AEAD, crittografare SEMPRE quindi MAC!
  5. bin2hex(), base64_encode()ecc. potrebbero perdere informazioni sulle chiavi di crittografia tramite i tempi della cache. Evitali se possibile.

Anche se segui i consigli forniti qui, molto può andare storto con la crittografia. Chiedi sempre a un esperto di crittografia di rivedere la tua implementazione. Se non sei abbastanza fortunato da essere amico personale di uno studente di crittografia nella tua università locale, puoi sempre provare il forum Scambio di stack di crittografia per un consiglio.

Se hai bisogno di un'analisi professionale della tua implementazione, puoi sempre assumere un rispettabile team di consulenti per la sicurezza per rivedere il tuo codice di crittografia PHP (divulgazione: il mio datore di lavoro).

Importante: quando non utilizzare la crittografia

Non crittografare le password . Si desidera hash invece, utilizzando uno di questi algoritmi di hashing delle password:

Non utilizzare mai una funzione hash per scopi generici (MD5, SHA256) per la memorizzazione delle password.

Non crittografare i parametri URL . È lo strumento sbagliato per il lavoro.

Esempio di crittografia di stringhe PHP con Libsodium

Se sei su PHP <7.2 o altrimenti non hai installato libsodium, puoi usare sodium_compat per ottenere lo stesso risultato (anche se più lentamente).

<?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;
}

Quindi per provarlo:

<?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);

Halite - Libsodium reso più facile

Uno dei progetti a cui sto lavorando è una libreria di crittografia chiamata Halite , che mira a rendere libsodium più semplice e intuitivo.

<?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);

Tutta la crittografia sottostante è gestita da libsodium.

Esempio con disinnesto / crittografia 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);

Nota : Crypto::encrypt()restituisce output con codifica esadecimale.

Gestione delle chiavi di crittografia

Se sei tentato di usare una "password", fermati subito. È necessaria una chiave di crittografia casuale a 128 bit, non una password memorabile.

È possibile memorizzare una chiave di crittografia per un uso a lungo termine in questo modo:

$storeMe = bin2hex($key);

E, su richiesta, è possibile recuperarlo in questo modo:

$key = hex2bin($storeMe);

Consiglio vivamente di archiviare una chiave generata casualmente per un uso a lungo termine anziché qualsiasi tipo di password come chiave (o per derivare la chiave).

Se stai usando la libreria di Defuse:

"Ma voglio davvero usare una password."

Questa è una cattiva idea, ma va bene, ecco come farlo in sicurezza.

Innanzitutto, genera una chiave casuale e memorizzala in una costante.

/**
 * 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");

Nota che stai aggiungendo lavoro extra e potresti semplicemente usare questa costante come chiave e risparmiarti un sacco di angoscia!

Quindi utilizzare PBKDF2 (in questo modo) per ricavare una chiave di crittografia adatta dalla password anziché crittografarla direttamente con la password.

/**
 * 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
    );
}

Non usare solo una password di 16 caratteri. La tua chiave di crittografia verrà comicamente rotta.


3
Non crittografare le password , cancellarle con hash password_hash()e controllarle password_verify().
Scott Arciszewski,

2
"Non comprimere mai niente". Vuoi dire come fanno HTTP, spdy e altri protocolli? Prima di TLS? Consigli di Absolutist molto?
Tiberiu-Ionuț Stan,

1
@ScottArciszewski Mi piace il tuo commento sulla chiave "// Fallo una volta, quindi memorizzalo in qualche modo:" .. in qualche modo, lol :)) che ne dici di memorizzare questa "chiave" (che è oggetto) come stringa semplice, codificata? Ho bisogno della chiave stessa, come stringa. Posso ottenerlo da questo oggetto in qualche modo? Grazie
Andrew

2
Grazie, ho dovuto solo modificare una riga per far funzionare i tuoi esempi di sodio:function getKeyFromPassword($password, $keysize = \Sodium\CRYPTO_SECRETBOX_KEYBYTES)
Alexey Ozerov,

1
Wow! +1 per menzionare di non crittografare i parametri URL. Mi è piaciuto molto l'articolo che hai fornito: paragonie.com/blog/2015/09/…
Lynnell Emmanuel Neri,

73

Sono in ritardo alla festa, ma cercando il modo corretto di farlo mi sono imbattuto in questa pagina che è stato uno dei principali risultati di ricerca di Google, quindi mi piacerebbe condividere la mia opinione sul problema, che ritengo sia aggiornato al momento della stesura di questo post (inizio 2017). Dal PHP 7.1.0 il mcrypt_decrypte mcrypt_encryptsta per essere deprecato, in modo da costruire il codice a prova di futuro dovrebbe usare openssl_encrypt e openssl_decrypt

Puoi fare qualcosa del tipo:

$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);

Importante : utilizza la modalità ECB , che non è sicura. Se vuoi una soluzione semplice senza seguire un corso intensivo in ingegneria crittografica, non scriverla da solo, basta usare una libreria.

È possibile utilizzare anche altri metodi di cippatura, a seconda delle esigenze di sicurezza. Per scoprire i metodi di cippatrice disponibili, consultare la funzione openssl_get_cipher_methods .


10
Grazie, sono sorpreso che questa risposta semplice e chiara non sia più votata. Preferirei non leggere una discussione di 10 pagine sull'argomento come la risposta migliore quando tutto ciò che voglio è crittografare / decrittografare una stringa semplice.
laurent,

4
Questa non è una risposta sicura. La modalità ECB non deve essere utilizzata. Se vuoi una "risposta semplice e chiara", usa semplicemente una libreria .
Scott Arciszewski,

2
@ScottArciszewski, sì, ammetto di aver parlato troppo velocemente mentre cercavo un semplice codice. Da allora ho aggiunto un IV e usando CBC nel mio codice, che è abbastanza buono per il mio uso.
laurent,

Leggi questo e ripensaci . Con la modalità CBC, un utente malintenzionato può modificare completamente il messaggio. Se il messaggio è un file, un utente malintenzionato può invertire i bit e visualizzare calc.exe. I rischi di crittografia non autenticata sono gravi.
Scott Arciszewski,

7
Tutto dipende dal caso d'uso! Ci sono casi in cui questo è perfettamente FINE. Ad esempio, voglio passare un parametro GET da una pagina all'altra, diciamo, prod_id=123ma non voglio rendere 123 leggibile per tutti, tuttavia anche se potessero leggerlo, non sarà un problema. Un utente malintenzionato in grado di sostituire il 123 con un valore personalizzato non causerà alcun danno, sarà in grado di ottenere i dettagli di qualsiasi altro prodotto, ma l'utente medio di Joe non avrà la minima idea di come ottenere dettagli per prodotto 124 per esempio. Per uno scenario come questo, è una soluzione perfetta, per la sicurezza è un no go!
Emil Borconi,

43

Cosa non fare

ATTENZIONE:
questa risposta utilizza la BCE . La BCE non è una modalità di crittografia, è solo un blocco predefinito. L'uso della BCE come dimostrato in questa risposta non crittografa la stringa in modo sicuro. Non utilizzare la BCE nel tuo codice. Vedi la risposta di Scott per una buona soluzione.

L'ho preso da solo. In realtà ho trovato una risposta su Google e ho appena modificato qualcosa. Il risultato è tuttavia completamente insicuro.

<?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
Puoi utilizzare "MCRYPT_MODE_CBC" anziché "MCRYPT_MODE_ECB" per garantire maggiore sicurezza.
Parixit,

10
Ramesh, questo è perché stai ricevendo i dati crittografati grezzi. Puoi ottenere una versione migliore dei dati crittografati usando base64, in questo modo: base64_encode(encrypt($string))- Per decrittografarlo:decrypt(base64_decode($encrypted))
mendezcode

82
ATTENZIONE: questo non è sicuro . La modalità ECB non deve essere utilizzata per le stringhe, la BCE non accetta un IV, questo non è autenticato, utilizza un vecchio codice (Blowfish) invece di AES, la chiave non è binaria ecc. Ecc. La comunità SO dovrebbe davvero smettere di utilizzare la crittografia / decrittografia che "funziona" e avvia l'upgrade delle risposte note per essere sicure. Se non lo sai per certo, non votare.
Maarten Bodewes,

3
L'ho già fatto mcrypt_encryptsostituendo il codice di esempio : php.net/manual/en/function.mcrypt-encrypt.php . Nota che rivedendolo ora probabilmente dovrebbe avere un rtrimcarattere "\0"alla fine.
Maarten Bodewes

4
La risposta corretta è usare qualcosa come disinnescare / crittografia php invece di scrivere il proprio codice mcrypt.
Scott Arciszewski,

18

Per il framework Laravel

Se si utilizza il framework Laravel, è più facile crittografare e decrittografare con funzioni interne.

$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);

Nota: assicurati di impostare una stringa casuale di 16, 24 o 32 caratteri nell'opzione chiave del file config / app.php. In caso contrario, i valori crittografati non saranno sicuri.


1
Certo, potrebbe essere facile da usare. Ma è sicuro? Come risolve i problemi in stackoverflow.com/a/30159120/781723 ? Utilizza la crittografia autenticata? Evita le vulnerabilità del canale laterale e garantisce controlli di uguaglianza a tempo costante? Utilizza una chiave veramente casuale piuttosto che una password / passphrase? Utilizza una modalità operativa adeguata? Genera IV casuali correttamente?
DW,

10

aggiornato

Versione pronta per PHP 7. Utilizza la funzione openssl_encrypt dalla libreria OpenSSL di PHP .

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
Questa è una versione migliore e molto più sicura. Grazie, funziona anche come previsto.

1
come si crea e dove si conserva la chiave di crittografia?
user2800464,

7

Nota storica: è stata scritta al momento di PHP4. Questo è ciò che chiamiamo "codice legacy" ora.

Ho lasciato questa risposta per scopi storici, ma alcuni dei metodi ora sono obsoleti, il metodo di crittografia DES non è una pratica consigliata, ecc.

Non ho aggiornato questo codice per due motivi: 1) Non lavoro più manualmente con i metodi di crittografia in PHP, e 2) questo codice ha ancora lo scopo per cui era destinato: dimostrare il concetto minimo e semplicistico di come può funzionare la crittografia in PHP.

Se trovi un tipo di fonte altrettanto semplice, "Crittografia PHP per manichini" che può far iniziare la gente con 10-20 righe di codice o meno, fammelo sapere nei commenti.

Inoltre, goditi questo episodio classico di risposta di crittografia minimalista PHP4 della prima era.


Idealmente hai - o puoi ottenere - l'accesso alla libreria mcrypt PHP, in quanto è certamente una varietà di attività molto popolari e molto utili. Ecco un riassunto dei diversi tipi di crittografia e alcuni esempi di codice: tecniche di crittografia in 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 ); 
?> 

Alcuni avvertimenti:

1) Non usare mai la crittografia reversibile o "simmetrica" ​​quando un hash unidirezionale lo farà.

2) Se i dati sono veramente sensibili, come carta di credito o numeri di previdenza sociale, fermati; hai bisogno di più di quello che ti fornirà un semplice pezzo di codice, ma piuttosto hai bisogno di una libreria di crittografia progettata per questo scopo e di una notevole quantità di tempo per ricercare i metodi necessari. Inoltre, la crittografia software è probabilmente <10% della sicurezza dei dati sensibili. È come ricablare una centrale nucleare - accetta che il compito sia pericoloso e difficile e, al di là delle tue conoscenze, in questo caso. Le sanzioni pecuniarie possono essere immense, quindi è meglio usare un servizio e spedire loro la responsabilità.

3) Qualsiasi tipo di crittografia facilmente implementabile, come elencato qui, può ragionevolmente proteggere le informazioni leggermente importanti che si desidera mantenere da occhi indiscreti o limitare l'esposizione in caso di perdite accidentali / intenzionali. Ma visto come la chiave è memorizzata in testo semplice sul server Web, se riescono a ottenere i dati possono ottenere la chiave di decrittazione.

Comunque sia, divertiti :)


9
Eww, DES. Dov'è AES?
Patashu,

2
Grazie! Ma alcuni problemi. Ricevo M�������f=�_=strani personaggi come quello criptato. Non riesco a ottenere personaggi semplici? Come: 2a2ffa8f13220befbe30819047e23b2c. Inoltre, non posso modificare la LUNGHEZZA di $key_value(fissa su 8 ???) e la LUNGHEZZA dell'output $encrypted_text? (non può essere lungo 32 o 64 o comunque ??)
夏 期 劇場

3
@ 夏 期 劇場 Il risultato della crittografia sono dati binari. Se è necessario che sia leggibile dall'uomo, utilizzare la codifica base64 o hex su di esso. "Non posso modificare la lunghezza del valore chiave?" Diversi algoritmi di crittografia simmetrica hanno requisiti diversi per il valore della chiave. 'e la LUNGHEZZA dell'output ...' La lunghezza del testo crittografato deve essere almeno lunga quanto il testo originale, altrimenti non ci sono abbastanza informazioni per ricreare il testo originale. (Questa è un'applicazione del principio di Pigeonhole.) A proposito, dovresti usare AES invece di DES. DES è facilmente frangibile e non più sicuro.
Patashu,

8
mcrypt_ecb è stato DEPRECATO a partire da PHP 5.5.0 Affidarsi a questa funzione è altamente scoraggiato. php.net/manual/en/function.mcrypt-ecb.php
Hafez Divandari

1
@BrianDHall Il motivo per cui si ottiene ancora il voto negativo è perché la modalità ECB non è sicura (usare CBC, CTR, GCM o Poly1305), DES è debole (si desidera AES, che è MCRYPT_RIJNDAEL_128), e i cifrati dovrebbero essere autenticati ( hash_hmac(), verificato con hash_equals()).
Scott Arciszewski,

7

Se non vuoi usare la libreria (che dovresti) allora usa qualcosa del genere (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);

Questo può essere un sostituto di stackoverflow.com/a/16606352/126833 ? Ho usato il primo fino a quando il mio host non è passato a PHP 7.2.
Anjanesh,

@anjanesh non sarai in grado di decrittografare i vecchi dati con questo (diversi algoritmi + questo controlla anche la firma)
Ascon

2
Nel tuo caso probabilmente questo dovrebbe fare: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);
Ascon,

Questo è Super!
Anjanesh,

2

Questi sono metodi compatti per crittografare / decrittografare le stringhe con PHP utilizzando 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));
}

Uso:

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

0

Il codice seguente funziona in php per tutte le stringhe con caratteri speciali

   // 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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.