首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法在PHP中不使用随机随机数的情况下使用Sodium Encrypt?

有没有办法在PHP中不使用随机随机数的情况下使用Sodium Encrypt?
EN

Stack Overflow用户
提问于 2019-11-11 04:08:34
回答 2查看 2.4K关注 0票数 1

我正在用新的库“library”做一些实验。基于https://www.zimuel.it/slides/zendcon2018/sodium#/21幻灯片。在这张幻灯片中有一个关于使用钠进行加密和解密的示例。

代码语言:javascript
复制
 $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类方法中使用了它,如下所示:

代码语言:javascript
复制
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)

代码语言:javascript
复制
 $key   = "4D6251655468576D597133743677397A24432646294A404E635266556A586E32"; // 256 bit hex

然后我得到消息:“密钥大小应该是SODIUM_CRYPTO_SECRETBOX_KEYBYTES字节”。

使用密钥:

代码语言:javascript
复制
 $key   = "E)H@McQfTjWnZr4u7w!z%C*F-JaNdRgU"; // 256 bit non hex

这个问题也解决了吗?

那么$ciphertext仍然是随机的,因为随机随机数。将随机数生成器替换为非随机随机数:(https://www.random.org/bytes/)

代码语言:javascript
复制
$nonce = "d80ac8385bb52cef7920ded5bda4de50697efc95ea53d81b" ; // 24 bytes hex

此消息显示为:“随机数大小应为SODIUM_CRYPTO_SECRETBOX_NONCEBYTES字节”。

同理:

代码语言:javascript
复制
$nonce = "249206220193104991548714284109130186236311295118249161302345616 " ; // 24 bytes decimal
$nonce = "056073032127157034374115050245203151150054323272014260311360377272100266" ; // 24 bytes octal

目前我的方法看起来是这样的:

代码语言:javascript
复制
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());
    }
}

我查看了https://download.libsodium.org/doc/secret-key_cryptography,但找不到一个解决方案来创建一个非随机(秘密)随机数来在这个加密实例中使用。有没有人有主意?在PHP中使用Sodium的人越来越多了吗?欢迎任何意见。

EN

回答 2

Stack Overflow用户

发布于 2020-05-08 11:58:33

我知道这条消息很陈旧,可能已经解决了,但我想这可能会有所帮助。

随机数是24个字符长度的。->这几乎就是答案。但是,如果您尝试使nonce不是随机的,包括密钥,那么输出将不再是单个数据的一系列无休止的随机字符。这很容易说,就像one to one一样。无论如何,密钥是32个字符的。让我们试一下这个例子。

代码语言:javascript
复制
<?php
class justEncrypt {
     private $key = 'vDIa5JdknBqfrKOu8d7UpddnBMCH1vza'; //32 characters
     private $nonce = 'Ra5LeH7ntW2rvkz3dmqI5Stx'; //24 characters

     public function sodiumStaticEncrypt(string $data) {
           $encrypted = base64_encode(
                 sodium_crypto_secretbox(
                       $data,
                       $this->nonce,
                       $this->key
                 )
           );
           return $encrypted;
    }
}

测试脚本:

代码语言:javascript
复制
<?php
$site = new justEncrypt; // I feel like I should not have done this
    echo $site->sodiumStaticEncrypt("It's better late than never!");

会有一个5Was2l9V0RgsgEm5csEbXnCaIxLkWwWiOxnHBgrej9+Ipyqn4ehn8VImFa8=的输出,这是因为你不想让它变成随机的,对吧?

检索数据相对容易。只需添加以下代码:

代码语言:javascript
复制
     public function sodiumStaticDecrypt(string $data) {
           // decode the base64 on $data first
           $decrypt = base64_decode($data);
           $decrypted = sodium_crypto_secretbox_open($data,$this->nonce,$this->key);
           return $decrypted;
     }

因此:

代码语言:javascript
复制
<?php

echo $site->sodiumStaticDecrypt('5Was2l9V0RgsgEm5csEbXnCaIxLkWwWiOxnHBgrej9+Ipyqn4ehn8VImFa8=');

然后它将返回到纯文本:It's better late than never!

无论你做什么,只要你不改变密钥和随机数,加密永远不会改变。这就像一对一的加密。只需确保没有人知道密钥和nonce,因为一切都将变得无用。不要忘记NONCE应该是24个字符长度的,不能更多,也不能更少;密钥应该是32个字符长度的,不能更多,也不能更少。

也可以使用常规的钠随机加密(保存电子邮件、用户名等)无论nonce和key每次都是随机化的。但这不是问题所在。无论如何,我建议不要让它成为静态的,因为它不是被设计成静态的。

好吧,我希望你已经解决了这个问题,我希望这对你有帮助(即使我真的认为,它不是)。

票数 2
EN

Stack Overflow用户

发布于 2020-07-02 04:12:19

在@Tesmurd101上只有一条评论。在sodiumStaticDecrypt中,以下行

代码语言:javascript
复制
$decrypted = sodium_crypto_secretbox_open($data,$this->nonce,$this->key);

应该是

代码语言:javascript
复制
$decrypted = sodium_crypto_secretbox_open($decrypt,$this->nonce,$this->key);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58792494

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档