将表单数据以加密形式重定向到另一个域

3

我希望以加密形式通过URL将表单数据发送到另一个域

<form action="http://localhost:85/abc/?<?php echo $_POST['name'] ?>" method="POST">
    First name:<br>
    <input type="text" name="name" placeholder="name"> 
    <input type="submit" value="Submit">
</form>

在寻找解决方案时,我发现了不同的方法,但是它们都对我没有用。例如,我发现如果我在表单中使用GET方法,那么可以像这样发送数据

<form action="http://localhost:85/abc/?<?php echo $_GET['name'] ?>" method="GET">

这个方案可以工作,但问题是它不以加密的形式发送数据,而且我不能将表单的方法从POST更改为GET,因为表单是由名为caldera forms的插件创建的。

我只能更改其表单操作。

根据其他解决方案,我尝试使用以下操作:

<form action="http://localhost:85/abc/?<?php echo $_REQUEST['name'] ?>" method="POST">

但对我来说这也没有起作用。您有什么其他建议吗?目前我是通过创建一个小表单而不是插件在本地主机上进行测试。

你尝试过对名称进行“加密”吗?我真的不明白你想要实现什么... - Cagy79
这是我的表单操作 http://localhost:85/abc/?<?php echo $_GET['name'] ?>。所以我只想用url发送名称字段。比如,如果在表单中输入了名称 Rishabh,那么重定向的url将会是这样的 http://localhost:85/abc/?Rishabh (但名称是加密的)。我已经展示了我在解决这个问题方面的搜索进展,除此之外,我还尝试使用隐藏字段,但对我也没有帮助。暂时不考虑加密,如果我在表单中使用 POST 方法,我甚至无法以非加密形式发送数据。 - Rishabh
4个回答

1

修改后的答案:

如果您加密了参数,无论您将其作为GET还是POST参数传递,都是无关紧要的,尽管我建议通过POST传递所有安全相关信息,而不是将其作为查询字符串的一部分发送(即URL中问号后的部分,例如http://localhost:85/abc/?Rishabh中的Rishabh),因为查询字符串将在浏览器历史记录和Web服务器日志中显示,如此处所述。

无论如何,这里至少有两个选项:

选项1:使用HTTPS/SSL

如果您使用 SSL 安全通信("https://" 而不是 "http://"),所有数据,甚至包括查询字符串,都将被加密并发送到服务器,因此无需手动加密参数。仍然有办法拦截数据(中间人攻击或伪造的 SSL 证书),但这是一种非常安全的数据传输方式。 在您的服务器上需要 SSL 证书(可以是自签名或由所谓的 "CA 权威" 购买)。如果您正在使用 Linux 和 Apache,这里有一篇文章解释它这篇文章 解释了 Windows 和 Apache 的操作。

选项二:手动处理加密和解密

发送方:

function doEncrypt($encrypt)
{
    $crypt_key= '%{is}§a/G00d+kEy.F0r#3ncRypT!0n';

    $iv= mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
    $crypted= mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $crypt_key, $encrypt, MCRYPT_MODE_ECB, $iv);
    $encode= base64_encode($crypted);       
    return $encode;
}
$name= 'Rishabh';
$encoded= doEncrypt($name);
?>
<form action="http://localhost:85/abc/?<?php echo $encoded; ?>" method="GET">

接收器(位于你的 abc 目录内):
function doDecrypt($decrypt)
{
    $crypt_key='%{is}§a/G00d+kEy.F0r#3ncRypT!0n';
    $decoded= base64_decode($decrypt);
    $iv= mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
    $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $crypt_key, $decoded, MCRYPT_MODE_ECB, $iv);

    return str_replace("\\0", '', $decrypted);
}
$name= doDecrypt($_REQUEST['QUERY_STRING']);

这里有一个使用上述函数的工作示例:phpFiddle
通过curl传输表单数据的更多信息可以在此处找到,使用PHP的mcrypt扩展可以安全地进行编码和解码。
您的代码还需要另外一条注释和解释:
<form action="http://localhost:85/abc/?<?php echo $_POST['name'] ?>" method="POST">

将以前作为表单提交的一部分已发布的变量name输出,该参数将作为表单请求的GET-/查询字符串的一部分发送,表单内的所有其他元素都将作为表单提交的一部分发送。
<form action="http://localhost:85/abc/?<?php echo $_GET['name'] ?>" method="GET">

将作为GET/查询字符串参数传递的变量name输出,它将再次成为表单请求的查询字符串的一部分。所有其他表单元素都将作为查询字符串而不是表单提交的一部分发送。
<form action="http://localhost:85/abc/?<?php echo $_REQUEST['name'] ?>" method="POST">

将输出一个名为name的参数,该参数可以通过表单提交或作为查询字符串的一部分进行提交,它还将成为表单请求查询字符串的一部分。所有其他表单元素将作为POST /表单数据的一部分发送,与示例1中相同。

谢谢你的回答,听起来很有趣。我会尽快测试并向你汇报。 - Rishabh
嗨SaschaM78,我正在测试你的代码,但有些困惑。你能告诉我如何在encrypt方法中放置值吗?就像这一行$arrPost['payload']= yourEncodeMethod($yourValue);,我应该以什么格式放置表单字段的值来替换$yourValue - Rishabh
好的,我想通了。 - Rishabh
@Rishabh 我更新了我的答案,给出了一个可用的例子来解释我之前所说的,并且添加了一些关于你之前尝试过的内容的注释,请看看是否有意义。 - SaschaM78
谢谢提到问题并点赞!现在你应该接受自己的答案作为已采纳,以标记问题已解决。还要感谢你的分享! - SaschaM78
显示剩余2条评论

0

你不能先在JavaScript上触发一个事件来加密你的数据吗?或者你可以直接提交到另一个PHP文件,然后从那里加密并发送。


我对JS的知识不是很扎实,但我会尽力去搜索相关资料。至于你第二个解决方案,你说只需将表单提交到另一个php文件再进行加密。好的,我可以找到一种方法来加密表单数据,但是如何在不执行任何操作的情况下将加密后的数据发送到另一个域名呢?我不希望用户必须点击重定向,因为他们已经点击了提交表单按钮一次。所以有没有一种自动加密后重定向的方式呢? - Rishabh
这都在后端处理。 - Eldon Hipolito
如果您可以使用GET,您可以使用header("Location:url?param=blabla")来实现它,或者如果您确实需要POST,您可以参考此链接在PHP脚本中POST - Eldon Hipolito

0

0

我找到了解决我的问题的方法,并与大家分享。这个解决方案分为以下4个步骤。

第一步: 对于加密和解密,我在我的functions.php文件中使用以下函数。

function Encryptstr($password, $data)
{

    $salt = substr(md5(mt_rand(), true), 8);

    $key = md5($password . $salt, true);
    $iv  = md5($key . $password . $salt, true);

    $ct = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);

    return base64_encode('Salted__' . $salt . $ct);
}
function Decryptstr($password, $data)
{

    $data = base64_decode($data);
    $salt = substr($data, 8, 8);
    $ct   = substr($data, 16);

    $key = md5($password . $salt, true);
    $iv  = md5($key . $password . $salt, true);

    $pt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ct, MCRYPT_MODE_CBC, $iv);

    return $pt;
}

我被告知无法直接在表单的action路径上执行加密函数,因此我正在使用另一种方法。我将表单重定向到一个页面,在该页面上对表单字段进行加密。

步骤2:
首先构建一个简单的表单,如下所示,在表单的操作中,我已经给出了我将执行加密的页面路径。

<form action="http://localhost:85/xyz/" method="POST">  //In action I am giving path to the page in which I will perform encryption     
    <input type="text" name="fname" placeholder="First Name">
    <input type="submit" value="Login">
</form>

步骤三:在表单重定向到此页面后,我将表单字段的数据存储在一个变量中,并按以下方式进行加密。

$name = $_POST['fname']; //fname is the name of the form control (Text Box)
// Performing encryption on it like this
$encrypt = Encryptstr('myPass123', $name); // Here "myPass123" is the key that will be use to encrypt and decrypt and "Encryptstr" Is function that I have put in functions.php as shown above.

在加密表单数据并将其存储在变量($encrypt)中后,我创建了另一个表单,其中包含隐藏字段。但是,在此表单中,我使用的是GET方法而不是POST

<form action="http://localhost:85/abc/" method="GET">
    First name:<br>
    <input type="hidden" name="fname" value="<?php echo $encrypt; ?>">
    <input type="submit" value="Login">
</form>

在表单的隐藏字段的值字段中,我使用了 $encrypt 变量,其中存储了之前加密的表单数据。我将其放在 value 选项中,这样我们就不需要再次输入值。 点击提交按钮后,表单将向我指定的页面发送数据(在表单的 action 中指定)。
因此,这些数据将通过 URL 传输,类似于这样:
http://localhost:85/abc/?fname=sdfhf3jh4jhdfjsdffsf

正如您所看到的,如果我没有进行加密,fname字段将被加密,否则输出结果将会是这样的。

http://localhost:85/abc/?fname=Entered_value_by_user

步骤4: 因此,在上一个步骤中,我只需要从 URL 中提取数据,为此我使用了 GET 方法,就像这样。 这是加密数据重定向的页面。

if(isset($_GET['fname']))    //Getting the value of fname field from url via GET method
{
    $entry = $_GET['fname'];  // Storing value in a variable
    //Decripting value using Decryptstr function where 'myPass123' is the key that we used to encrypt and same key needed to decrypt
    echo 'Result: '.Decryptstr('myPass123', $entry); 
}

参考:http://heiswayi.github.io/php-encryption-decryption-and-password-hashing.html

注意:这种方法非常有效,但我不知道它提供了什么级别的安全性。我有两个加密选项,第一个是使用 ECB,第二个是使用 CBC。所以我在谷歌上搜索了一下,想找出哪个更安全。于是我找到了一篇好文章详细描述了 ECB vs CBC。阅读完文章后,我发现cbc更安全。这就是为什么我使用CBC


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接