I am doing some experimentation with the new library "Libsodium". Based on the https://www.zimuel.it/slides/zendcon2018/sodium#/21 slide. In this slide there is an example show about encryption and decryption with sodium.
$msg = 'This is a super secret message!';
// Generating an encryption key and a nonce
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES); // 256 bit
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 24 bytes
// Encrypt
$ciphertext = sodium_crypto_secretbox($msg, $nonce, $key);
// Decrypt
$plaintext = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);
echo $plaintext === $msg ? 'Success' : 'Error';
I used this in a PHP class method like this:
public function sodium_encrypt($p_sPlaintext)
{
try{
if(!empty($p_sPlaintext) && is_string($p_sPlaintext)){
// Generating an encryption key and a nonce
$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES); // 256 bit
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 24 bytes
// Encrypt Note: the encryption is always authenticated, you need to store also nonce + ciphertext
$eCiphertext = sodium_crypto_secretbox($p_sPlaintext, $nonce, $key);
$eCryptotext = $nonce.$eCiphertext;
if(!empty($eCiphertext)){
return($eCiphertext);
} else{
throw new Exception('clse004'); // Error trigger
}
} else{
throw new Exception('clse005'); // Error trigger
}
} catch (Exception $e){
echo("<br>Errormessage, code: ".$e->getMessage());
}
}
and it works like it should be, no problems there. BUT..... :-) there is always an 'but'.
If I use this method to encrypt, for example, an e-mail address and store this in the database as the users login credentials, then they are an unique encryption of his credentials. The next time the user enters his credentials and I encrypt these, then I wound find him in the DB becaurse of the random generating of the $key and the $nonce.
If I generate my own, not random, key: (https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx)
$key = "4D6251655468576D597133743677397A24432646294A404E635266556A586E32"; // 256 bit hex
Then I get the message: "key size should be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes".
With the key:
$key = "E)H@McQfTjWnZr4u7w!z%C*F-JaNdRgU"; // 256 bit non hex
is that problem solved too.
Then the $ciphertext is still random becaurse of the random nonce. Replacing the randomizer with a non random nonce like: (https://www.random.org/bytes/)
$nonce = "d80ac8385bb52cef7920ded5bda4de50697efc95ea53d81b" ; // 24 bytes hex
this message is shown: "nonce size should be SODIUM_CRYPTO_SECRETBOX_NONCEBYTES bytes".
The same with:
$nonce = "249206220193104991548714284109130186236311295118249161302345616 " ; // 24 bytes decimal
$nonce = "056073032127157034374115050245203151150054323272014260311360377272100266" ; // 24 bytes octal
For the time being my current methode looks like:
public function sodium_encrypt($p_sPlaintext)
{
try{
if(!empty($p_sPlaintext) && is_string($p_sPlaintext)){
// Generating an encryption key and a nonce
$key = "E)H@McQfTjWnZr4u7w!z%C*F-JaNdRgU"; // 256 bit
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); // 24 bytes
// Encrypt Note: the encryption is always authenticated, you need to store also nonce + ciphertext
$eCiphertext = sodium_crypto_secretbox($p_sPlaintext, $nonce, $key);
//$eCryptoText = $nonce.$eCiphertext;
echo $eCiphertext;
if(!empty($eCiphertext)){
return($eCiphertext);
} else{
throw new Exception('clse004'); // Error trigger
}
exit();
} else{
throw new Exception('clse005'); // Error trigger
}
} catch (Exception $e){
echo("<br>Errormessage, code: ".$e->getMessage());
}
}
I looked at https://download.libsodium.org/doc/secret-key_cryptography but cant find a solution to create a non random (secret)nonce to use in this instance of encryption. Does anyone have ideas? Are more people working with Sodium in PHP? Any input is welcome.