Il tipico esempio di crittografia a chiave pubblica e lo scambio di messaggi tra due soggetti Alice e Bob, Alice per inviare un messaggio a Bob utilizza la chiave pubblica di Bob per cifrare il messaggio, mentre Bob per decifrare il messaggio di Alice utilizza la sua chiave privata, e viceversa Bob per inviare un messaggio ad Alice utilizza la chiave pubblica di Alice per cifrare il messaggio, mentre Alice per decifrare il messaggio di Bob utilizza la sua chiave privata.
Per generare una coppia di chiavi si utilizza l'estensione OpenSSL di PHP
Codice PHP
<?php
$config = array(
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA
);
$keys = openssl_pkey_new($config);
$passphrase = 'xyz';
openssl_pkey_export_to_file($keys, 'private.pem', $passphrase);
$details = openssl_pkey_get_details($keys);
$publickey = $details['key'];
file_put_contents('public.key', $publickey);
entrambe le chiavi hanno una lunghezza di 4096 bit ed è utilizzato l'algoritmo di cifratura RSA ($config), entrambe le chiavi sono memorizzate nella variabile $keys, in particolare è usata una 'passphrase' per cifrare la chiave privata, la quale viene memorizzata in un file private.pem, la chiave pubblica è memorizzata in un file public.key.
Adesso che abbiamo generato la coppia di chiavi pubblica e privata possiamo procedere a criptare e decriptare un messaggio, in particolare usiamo le due funzioni encrypt e decrypt disponibili nella documentazione di PHP al seguente link
php.net/manual/en/function.openssl-encrypt.php#126296
Codice PHP
<?php
function encrypt(string $plaintext, string $key, string $iv = '', string $aad = ''):
string
{
...... .
}
function decrypt(string $ciphertext, string $key, string $iv = '', string $aad = ''):
string
{
...... .
}
$msg = "Testo del messaggio...";
$key = random_bytes(32);
$iv = random_bytes(16);
/** public key */
$publickey = file_get_contents('public.key');
/** private key */
$passphrase = "xyz";
$privatekey = openssl_pkey_get_private('file://private.pem', $passphrase);
openssl_public_encrypt($key, $encryptedKey, $publickey, OPENSSL_PKCS1_OAEP_PADDING);
$ciphertext = encrypt($msg, $key, $iv);
printf($ciphertext."\n");
$result = openssl_private_decrypt($encryptedKey, $decryptedKey, $privatekey, OPENSSL_PKCS1_OAEP_PADDING);
if (false !== $result)
{
$result = decrypt($ciphertext, $key, $iv);
printf($result."\n");
}
else
{
while ($msg = openssl_error_string())
{
printf("%s\n", $msg);
}
}
$key e $iv sono rispettivamente la chiave segreta (stringa di 32 bit) e il vettore di inizializzazione (stringa di 16 bit), $publickey è la chiave pubblica che abbiamo generato in precedenza, $passphrase è la passphrase che abbiamo usato per cifrare la chiave privata, $privatekey è la chiave privata che otteniamo tramite la funzione openssl_pkey_get_private, eseguendo il codice otterremo un risultato simile a questo
rtEjTs+bCo2FMQJyWuxCzWujyCPvhJm0lHwxzACyG6P0a+WVXGg=
Testo del messaggio...
la prima stringa è il messaggio criptato, mentra la seconda stringa è il messaggio decriptato e quindi l'originale.