0

我打算再次尝试在这个网站上发帖。我之前的问题被忽略或批评了,因为我猜人们认为我没有投入太多精力来试图找出问题,而只是寻找一些简单的代码来复制!

我的目标是编写可以调用的 PHP 函数来加密和解密要存储在服务器上的数据,而加密密钥存储在 USB 加密狗上。我一直在玩 Sodium,但网络上似乎没有很多关于它的信息。我也不是一个受过高等教育的程序员,因为我自学了我所知道的一切。

这是示例测试代码:

<?php

//set variables
$key="";
$passedkey="";
$name="";
$nonce="";
$ciphertext="";
$encoded="";
$encodeddata="";
$datatoencode="";
$decodeddata="";
$decodedkey="";

function encodedata($passedkey, $datatoencode){
    $decodedkey = base64_decode($passedkey);    
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    $ciphertext = sodium_crypto_secretbox($datatoencode, $nonce, $decodedkey);
    $encodeddata = base64_encode($nonce . $ciphertext);
}

function decodedata($passedkey, $datatodecode, $decodeddata){
    $decodedkey = base64_decode($passedkey);
    $nonce = mb_substr($datatodecode, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $ciphertext = mb_substr($datatodecode, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    $decodeddata = sodium_crypto_secretbox_open($ciphertext, $nonce, $decodedkey);
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collect value of input field
    $encodedata = $_POST['encodedata'];
    $passedkey = base64_decode($_POST['skey']);
    echo $encodeddata . "<br>";

    //call function to encode the data
    encodedata($passedkey, $datatoencode);

    // now decode the data
    decodedata($passedkey, $encodeddata, $decodeddata);
    echo $decodeddata;
}

?>




<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Data to encode: <input type="text" name="encodedata">
  Key: <input type="text" name="skey">
  <input type="submit">
</form>


</body>
</html>

我在服务器错误日志中收到此错误消息:

[06-Mar-2020 16:16:11 UTC] PHP Fatal error:  Uncaught SodiumException: key size should be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes in /home/.../test/keytest.php:17
Stack trace:
#0 /home/.../test/keytest.php(17): sodium_crypto_secretbox()
#1 /home/.../test/keytest.php(35): encodedata()
#2 {main}
  thrown in /home/.../test/keytest.php on line 17
[06-Mar-2020 16:16:24 UTC] PHP Fatal error:  Uncaught SodiumException: key size should be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes in /home/.../test/keytest.php:17
Stack trace:
#0 /home/.../test/keytest.php(17): sodium_crypto_secretbox()
#1 /home/.../test/keytest.php(35): encodedata()
#2 {main}
  thrown in /home/.../test/keytest.php on line 17
[06-Mar-2020 16:30:38 UTC] PHP Fatal error:  Uncaught SodiumException: key size should be SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes in /home/.../test/keytest.php:18
Stack trace:
#0 /home/.../test/keytest.php(18): sodium_crypto_secretbox()
#1 /home/.../test/keytest.php(36): encodedata()
#2 {main}
  thrown in /home/.../test/keytest.php on line 18

任何有助于调试代码的提示将不胜感激!

4

1 回答 1

2

你的变量很遥远。这段代码中有几处是关闭的,老实说,我花了几分钟才注意到你$encodedata没有设置为function encodedata(). 无论如何,我相信您的变量已经设置是我的错。请耐心等待,因为这是一个很长的解释。

我注意到的第一件事是您解码$passedkey了两次(或三次,如果两个函数都计算在内)。当您调用函数/s 时,inif($_SERVER("REQUEST_METHOD") == "POST")已经$passedkey通过解码base64_decode并放置在变量$passedkey中。在这两个函数encodedatadecodedata中,您再次对其进行了解码,因此当您尝试调用这些函数时会出错。由于参数$passedkey的值是在到达函数之前已经解码的值,所以不需要再次解码。和我一样是多余的。因此,$decodedkey = base64_decode($passedkey);不再需要,并且$decodedkey变量应更改为$passedkeyon both function

其次是你$encodedata的没有被调用。在if($_SERVER("REQUEST_METHOD") == "POST"),$encodedata的值是$_POST['encodedata'],因此input要编码的数据的值。但是,当您调用该函数时,encodedata,$encodedata无处可寻。

第三个问题是你的函数没有“返回”任何东西。您不能期望echo $encodeddata;echo $decodeddata;从函数的“内部”返回值。好吧,我不知道您是否正在使用可以使用的平台,但是您可以使用。

基本上,示例代码的问题是变量的放置错误并且没有注意值和参数。无论如何,我的建议是保存skey在 USB 加密狗中应该base64_encode()是正确的钠密钥值,否则,这将不起作用。

这是一个编辑过的代码,我不知道这是否适用于你,但它适用于我的。

<?php

//set variables
$key="";
$passedkey="";
$name="";
$nonce="";
$ciphertext="";
$encoded="";
$encodeddata="";
$datatoencode="";
$decodeddata="";
$decodedkey="";

function encodedata($passedkey, $datatoencode){
    //no need to decode $passedkey since it is already decoded before calling the function
        //you can still retain $decodedkey = base64_decode($passedkey) but should REPLACE $passedkey = base64_decode($_POST['skey']); WITH $passedkey = $_POST['skey']; below
    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
    //change $decodedkey to $passedkey
    $ciphertext = sodium_crypto_secretbox($datatoencode, $nonce, $passedkey);
    $encodeddata = base64_encode($nonce . $ciphertext);
    //return the encrypted data when the function is called
    return $encodeddata;
}

function decodedata($passedkey, $datatodecode){
    //decode the encrypted data since it is stored as base64_encode()
        //you can still retain $decodedkey = base64_decode($passedkey) but should REPLACE $passedkey = base64_decode($_POST['skey']); WITH $passedkey = $_POST['skey']; below
    $datatodecode = base64_decode($datatodecode);
    $nonce = mb_substr($datatodecode, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit');
    $ciphertext = mb_substr($datatodecode, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit');
    //change $decodedkey to $passedkey
    $decodeddata = sodium_crypto_secretbox_open($ciphertext, $nonce, $passedkey);
    //return the plaintext when the function is called
    return $decodeddata;
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // collect value of input field
    $encodedata = $_POST['encodedata'];
    $passedkey = base64_decode($_POST['skey']);

    //call function to encode the data
        //you can't fetch the value of a variable from outside of the function hence we will make the function itself a variable.
        //the returned data from the function is now the value of the variabl
    $encrypted = encodedata($passedkey, $encodedata);
    echo $encrypted.'<br />';
    

    // now decode the data
    $decypted = decodedata($passedkey, $encrypted);
    echo $decypted.'<br />';
}

?>




<html>
<body>

<form method="post" action="<?php echo $_SERVER['PHP_SELF'];?>">
  Data to encode: <input type="text" name="encodedata">
  Key: <input type="text" name="skey">
  <input type="submit">
</form>


</body>
</html>

我不知道你的意思或你到底想做什么,但这是让你给定的代码工作的方法。

于 2020-12-05T23:30:23.320 回答