Ci sono diversi miglioramenti che possono essere apportati alle funzioni che hai fornito, in base alle mie conoscenze.
Minacce ovvie
Per prima cosa, e soprattutto, mantieni sicura la tua chiave privata e rendila esterna alla definizione della funzione (ad esempio, un secondo argomento). Consiglierei di spendere sforzi significativi per risolvere questo problema. Questa è la crittografia per utente o la crittografia a livello di applicazione? Se è per utente, allora perché non utilizzare un algoritmo di derivazione della chiave, come PBKDF2 ? Se è un'applicazione, quindi buona fortuna con l'archiviazione sicura, ci ho pensato prima, e sembra non banale per una tipica app web. Assicurati che non memorizzi la chiave privata insieme all'origine, né (ovviamente) nello stesso database .
Inoltre, per inciso: non usare mai la crittografia simmetrica per tutto ciò che è simile a una password. Utilizzare invece un hash unidirezionale. Suppongo, per questa risposta, che tu debba effettivamente recuperare la chiave del CD originale, invece di verificare una corrispondenza.
In secondo luogo, sono dubbioso sull'uso di MCRYPT_RAND. Sembra che potrebbe essere lo stesso PRNG di rand () , che non è l'ideale. Generare IV con MCRYPT_DEV_URANDOM è ciò che raccomanderei - / dev / random e / dev / urandom sono entrambi considerati fonti di prim'ordine di numeri casuali crittografici su sistemi basati su Unix. Nota che non generalmente vuoi usare / dev / random per un'applicazione web, perché aprirebbe un semplice vettore DoS - e / dev / urandom dovrebbe essere sufficiente al di fuori degli ambienti embedded, comunque.
Altri problemi di implementazione
Ora, con le principali vulnerabilità che posso individuare, alcuni dettagli a grana fine:
Stai mescolando le funzioni OpenSSL e mcrypt. Inoltre, openssl_encrypt non è documentato nei documenti PHP ufficiali (ho il sospetto che sia documentato per C da qualche parte, anche se ...). Potrebbe essere preferibile utilizzare mcrypt_encrypt invece, poiché è esplicitamente documentato per PHP.
Stai mixando anche CAST-256 e AES-256. Dovresti probabilmente rimanere con AES-256 per tutto il tempo, dal momento che questo è l'algoritmo standard generalmente consigliato per una strong crittografia simmetrica. Tieni presente che AES-256 è MCRYPT_RIJNDAEL_128 utilizzato con una chiave a 256 bit , e NON è uguale a Rijndael-256, che è qualcosa che non avevo mai realizzato prima (più sai!).
Non sono sicuro della modalità di crittografia preferita, ma CBC è uno che ho visto raccomandato per AES, almeno. Speriamo che qualcun altro abbia qualche input.