首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在PHP函数中使用Sodium库

在PHP函数中使用Sodium库
EN

Stack Overflow用户
提问于 2020-03-07 00:50:47
回答 1查看 252关注 0票数 0

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

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

以下是示例测试代码:

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

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

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

任何帮助调试代码的技巧都将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2020-12-06 07:30:23

你的变量太离谱了。这段代码中有一些东西是错误的,老实说,我花了几分钟才注意到您的$encodedata没有设置为function encodedata()。不管怎样,我相信你的变量已经设置好了,这是我的错。请容忍我,因为这是一个相当长的解释。

我注意到的第一件事是您对$passedkey解码了两次(或者三次,如果两个函数都算数的话)。在if($_SERVER("REQUEST_METHOD") == "POST")中调用函数时,已经通过base64_decode$passedkey进行了解码,并将其放在变量$passedkey中。在encodedatadecodedata这两个函数中,您再次对其进行了解码,因此在尝试调用这两个函数时会出现错误。由于参数$passedkey的值是函数到达之前已经解码的值,所以不需要重新解码,跟我一样是多余的,所以不再需要$decodedkey = base64_decode($passedkey);了,$decodedkey变量应该在两个function上都改成$passedkey

第二,你的$encodedata没有被调用。在if($_SERVER("REQUEST_METHOD") == "POST")中,$encodedata的值是$_POST['encodedata'],因此也就是要编码的input数据的值。然而,当您调用函数encodedata时,却找不到$encodedata

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

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

这是一段经过编辑的代码,我不知道这是否能在你那端起作用,但在我的那端确实能。

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60568399

复制
相关文章

相似问题

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