Есть ли способ использовать Sodium Encrypt без случайного одноразового номера в PHP? - PullRequest
0 голосов
/ 10 ноября 2019

Я немного экспериментирую с новой библиотекой "Libsodium". Основано на слайде https://www.zimuel.it/slides/zendcon2018/sodium#/21. На этом слайде показан пример шоу о шифровании и дешифровании с помощью натрия.

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

Я использовал это в методе класса PHP следующим образом:

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());
    }
}

, и он работает так, как долженбыть, никаких проблем нет. НО ..... :-) всегда есть «но».

Если я использую этот метод для шифрования, например, адреса электронной почты и сохранения его в базе данных в качестве учетных данных для входа пользователей, то они являются уникальным шифрованием его учетных данных. В следующий раз, когда пользователь вводит свои учетные данные и я их шифрую, я нахожу его в БД из-за случайного генерирования $ key и $ nonce.

Если я генерирую свои собственные, а не случайные,ключ: (https://www.allkeysgenerator.com/Random/Security-Encryption-Key-Generator.aspx)

 $key   = "4D6251655468576D597133743677397A24432646294A404E635266556A586E32"; // 256 bit hex

Затем я получаю сообщение: «размер ключа должен быть SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes».

С ключом:

 $key   = "E)H@McQfTjWnZr4u7w!z%C*F-JaNdRgU"; // 256 bit non hex

isэта проблема тоже решена.

Тогда $ ciphertext все еще является случайным из-за случайного одноразового номера. Замена рандомизатора неслучайным одноразовым номером, например: (https://www.random.org/bytes/)

$nonce = "d80ac8385bb52cef7920ded5bda4de50697efc95ea53d81b" ; // 24 bytes hex

это сообщениепоказано: «размер nonce должен быть SODIUM_CRYPTO_SECRETBOX_NONCEBYTES bytes».

То же самое с:

$nonce = "249206220193104991548714284109130186236311295118249161302345616 " ; // 24 bytes decimal
$nonce = "056073032127157034374115050245203151150054323272014260311360377272100266" ; // 24 bytes octal

В настоящее время мой текущий метод выглядит следующим образом:

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Посмотрел https://download.libsodium.org/doc/secret-key_cryptography, но не могу найти решение для создания неслучайного (секретного) одноразового номера для использования в этом случае шифрования. У кого-нибудь есть идеи? Больше людей работает с Sodium в PHP? Любой ввод приветствуется.

...