PHP OpenSSL è più sicuro di un semplice utilizzo di MySQL AES_ENCRYPT / DECRYPT?

3

Desidero crittografare / decodificare i dati nel mio database MySQL memorizzato sul mio server. Uso un hash salato per le mie password. Tutte le crittografie / decifrazioni si sarebbero verificate sul server. Uso gli endpoint PHP a cui i miei clienti remoti accedono. I punti finali poi accedono al database MySQL.

Ho il seguente codice PHP per cifrare / decifrare un messaggio:

<?php
    $key = "mySecretKey";
    $cipher = "aes-128-gcm";
    $ivlen = openssl_cipher_iv_length($cipher);

    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt("message to be encrypted", $cipher, $key,     $options=0, $iv, $tag);

    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, 0, $iv, $tag);

    echo "original message: ".$original_plaintext."\n";

    // $iv and $tag change each time we encrypt the data, so store these
?>

... che stavo per utilizzare per memorizzare i dati crittografati nel mio database. Tuttavia, dovrò anche memorizzare $iv e $tag con i miei dati poiché queste modifiche sono eseguite per ogni openssl_encrypt eseguito.

D'altra parte, potrei semplicemente usare le funzioni AES_ENCRYPT di MySQL. Questa opzione semplificherebbe molto il mio codice, perché posso solo aggiungere AES_ENCRYPT(data, key) al mio codice SQL.

Tuttavia, ho la sensazione che la soluzione PHP sia più sicura di AES_ENCRYPT da solo. È vero?

D'altra parte, non ne sono così sicuro. Ad esempio, se qualcuno ha ottenuto la mia chiave AES_ENCRYPT , allora potrebbero facilmente ottenere il mio PHP $key nel qual caso sarebbero anche in grado di decrittografare il openssl_encrypt -ed messge, poiché la% le informazioni di$iv$ e $tag sarebbero probabilmente così facili da ottenere se hanno in qualche modo messo le mani su $key .

O forse sto andando sulla mia soluzione PHP nel modo sbagliato. Forse $iv non dovrebbe essere generato ogni volta che crittografa un'informazione? Forse $iv dovrebbe essere finale, cioè sempre uguale, nel qual caso $tag è sempre lo stesso ...

    
posta Antinous 24.04.2018 - 12:26
fonte

2 risposte

4

Se si eseguisse la crittografia sul lato server MySQL, si dovranno inviare i dati (non crittografati) al server MySQL. Per fare ciò in modo sicuro, è necessario garantire una connessione crittografata al server MySQL per proteggere i dati in transito. A seconda della configurazione, i dati potrebbero (parzialmente) finire in un file di registro da qualche parte. Tutto questo aggiunge un livello di complessità, senza ulteriori vantaggi per la sicurezza.

Leggi anche: È "Perché dovresti evitare AES In MySQL? "True? .


Encrypt on the PHP side
Se si criptano i dati sul lato PHP, è possibile utilizzare pacchetti di facile utilizzo ( SymmetricEncryption o php-encryption mi viene in mente) e memorizza semplicemente la stringa crittografata nel tuo DB, che è molto meno complessa.
Data la tua domanda su, ad esempio, il requisito per $iv , I strongmente ti suggerisce di utilizzare una libreria standard!

Quindi, in sintesi: Sì, l'utilizzo di PHP OpenSSL è più sicuro di MySQL AES_ENCODE / DECODE.

    
risposta data 24.04.2018 - 12:40
fonte
3

Non utilizzare AES_ENCRYPT a meno che non comprenda pienamente problemi e come usarlo correttamente!

Ci sono diversi problemi significativi con AES_ENCRYPT:

Ha impostazioni predefinite scadenti

Il valore predefinito block_encryption_mode è aes-128-ecb . Chiunque comprenda cos'è ecb e lo vede qui come predefinito è probabilmente in ritardo. Basti dire che può perdere una quantità significativa di informazioni.

Raccomanda la derivazione della chiave non sicura

Dalla documentazione :

A passphrase can be used to generate an AES key by hashing the passphrase. For example:

INSERT INTO t
VALUES (1,AES_ENCRYPT('text', UNHEX(SHA2('My secret passphrase',512))));

Do not pass a password or passphrase directly to crypt_str, hash it first. Previous versions of this documentation suggested the former approach, but it is no longer recommended as the examples shown here are more secure.

Sembra che in precedenza avessero raccomandato di usare una password direttamente come chiave! Ora l'hanno migliorato in una singola iterazione di una funzione di hash veloce senza sale. Perchè questo è ancora abbastanza terribile vedi qui . Il metodo corretto sarebbe utilizzare una funzione di derivazione della chiave basata su password come PBKDF2.

Non supporta la crittografia autenticata

Le modalità supportate sono ECB, CBC, CFB1 , CFB8, CFB128, OFB. Molte di queste modalità sono malleabili in una certa misura e alcune di esse consentono di capovolgere un bit specifico nel testo cifrato per capovolgere lo stesso bit nel testo in chiaro. La tua domanda suggerisce che utilizzerai GCM che impedisce ciò verificando l'autenticità.

Anche se non volessi la crittografia autenticata, preferirei personalmente evitare di utilizzare qualcosa con impostazioni e valori predefiniti non sicuri, e come Jacco sottolinea , la crittografia in PHP è migliore se non puoi garantire che la connessione tra PHP e MySQL utilizzi TLS.

    
risposta data 24.04.2018 - 16:30
fonte

Leggi altre domande sui tag