Php 带base64编码和序列化的mcrypt 2路加密问题 更新(解决方案)
由于这篇文章似乎得到了相当多的关注,我想让您知道,解决方案最终是在Php 带base64编码和序列化的mcrypt 2路加密问题 更新(解决方案),php,forms,encryption,mcrypt,Php,Forms,Encryption,Mcrypt,由于这篇文章似乎得到了相当多的关注,我想让您知道,解决方案最终是在声明中提供一个适当的enctype(内容类型)参数。必须将该值设置为multipart/form data,以防止使用默认enctypeapplication/x-www-form-urlencoded进行编码。以下是w3.org网站上的一个小摘录: 内容类型 “application/x-www-form-urlencoded”是 发送大型邮件效率低下 二进制数据或文本的数量 包含非ASCII字符的。这个 内容类型“多部分/表单
声明中提供一个适当的enctype
(内容类型)参数。必须将该值设置为multipart/form data
,以防止使用默认enctypeapplication/x-www-form-urlencoded
进行编码。以下是w3.org网站上的一个小摘录:
内容类型
“application/x-www-form-urlencoded”是
发送大型邮件效率低下
二进制数据或文本的数量
包含非ASCII字符的。这个
内容类型“多部分/表单数据”
应用于提交表单
包含文件、非ASCII数据、,
和二进制数据
以下是正确的声明格式:
<FORM method="POST" action="/path/to/file/" name="encryptedForm" enctype="multipart/form-data">
稍后,我使用以下命令调用设置隐藏表单元素的值:
base64_encode(serialize(self::$encrypted))
本质上,隐藏字段包含一个所有表单字段的数组,这些表单字段使用其加密值进行加密。这样我就知道哪些字段需要在后端解密。表单提交后,将使用以下代码在后端解析此字段:
// load the mapping entry
$encrypted_fields = $input->post('encrypted', '');
if (empty($encrypted_fields)) {
throw new AppException('The encrypted form field was empty.');
}
// decompress array of encrypted fields
$encrypted_fields = @unserialize(base64_decode($encrypted_fields));
if ($encrypted_fields === false) {
throw new AppException('The encrypted form field was not valid.');
}
// get the mapping of encrypted keys to key
$data = array();
foreach ($_POST as $key => $val) {
// if the key is encrypted, add to data array decrypted
if (in_array($key, $encrypted_fields)) {
$decrypted = self::encryption($key, false);
$data[$decrypted] = $val;
unset($_POST[$key]);
} else {
$data[$key] = $val;
}
}
// merge $_POST array with decrypted key array
$_POST += $data;
我解密加密表单字段密钥的尝试失败。它只是在
$\u POST
数组中创建一个新的乱码键。我的猜测是base64\u编码
或序列化
正在从$encrypted\u数据
中剥离字符是否有人可以验证这是否是罪魁祸首,以及是否有其他方法可以对表单密钥进行编码?因此,我获取了您的代码,并对其进行了一些修改,以便删除post请求的元素,您的函数似乎工作正常。如果您使用我发布的代码并使用它创建脚本,它应该在cli中运行,您将看到它正确地加密/解密字段。这就意味着post请求对加密/序列化/编码的数据有多大的影响。如果使用框架,我会更深入地研究它如何处理post数组,因为它可能会改变键/值,导致它们不匹配。你发布的代码看起来不错
/**
* Two way encryption function to encrypt/decrypt keys with
* the DES encryption algorithm.
*/
public static function encryption($text, $encrypt = true)
{
$encrypted_data = '';
$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
if (mcrypt_generic_init($td, substr(self::$randomizer, 16, 8), $iv) != -1) {
if ($encrypt) {
// attempt to sanitize encryption for use as a form element name
$encrypted_data = mcrypt_generic($td, $text);
$encrypted_data = base64_encode($encrypted_data);
$encrypted_data = 'i' . strtr($encrypted_data, '+/=', '-_.');
self::$encrypted[] = $encrypted_data;
} else {
// reverse form element name sanitization and decrypt
$text = substr($text, 1);
$text = strtr($text, '-_.', '+/=');
$text = base64_decode($text);
$encrypted_data = mdecrypt_generic($td, $text);
}
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
return $encrypted_data;
}
<?php
/**
* Two way encryption function to encrypt/decrypt keys with
* the DES encryption algorithm.
*/
function encryption($text, $encrypt = true, &$encryptedFields = array())
{
$encrypted_data = '';
$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
if (mcrypt_generic_init($td, substr('sdf234d45)()*5gf512/?>:LPIJ*&U%&^%NBVFYUT^5hfhgvkjtIUUYRYT', 16, 8), $iv) != -1) {
if ($encrypt) {
// attempt to sanitize encryption for use as a form element name
$encrypted_data = mcrypt_generic($td, $text);
$encrypted_data = base64_encode($encrypted_data);
$encrypted_data = 'i' . strtr($encrypted_data, '+/=', '-_.');
//self::$encrypted[] = $encrypted_data;
$encryptedFields[] = $encrypted_data;
} else {
// reverse form element name sanitization and decrypt
$text = substr($text, 1);
$text = strtr($text, '-_.', '+/=');
$text = base64_decode($text);
$encrypted_data = mdecrypt_generic($td, $text);
}
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
return $encrypted_data;
}
$encryptedFields = array();
// encrypt some form fields
encryption('firstname', true, $encryptedFields);
encryption('lastname', true, $encryptedFields);
encryption('email_fields', true, $encryptedFields);
echo "Encrypted field names:\n";
print_r($encryptedFields);
// create a usable string of the encrypted form fields
$hiddenFieldStr = base64_encode(serialize($encryptedFields));
echo "\n\nFull string for hidden field: \n";
echo $hiddenFieldStr . "\n\n";
$encPostFields = unserialize(base64_decode($hiddenFieldStr));
echo "\n\nDecrypted field names:\n";
foreach($encPostFields as $field)
{
echo encryption($field, false)."\n";
}
?>
因此,我接受了您的代码,并对其进行了一些修改,这样我就可以删除post请求中的元素,并且您的功能似乎运行良好。如果您使用我发布的代码并使用它创建脚本,它应该在cli中运行,您将看到它正确地加密/解密字段。这就意味着post请求对加密/序列化/编码的数据有多大的影响。如果使用框架,我会更深入地研究它如何处理post数组,因为它可能会改变键/值,导致它们不匹配。你发布的代码看起来不错
<?php
/**
* Two way encryption function to encrypt/decrypt keys with
* the DES encryption algorithm.
*/
function encryption($text, $encrypt = true, &$encryptedFields = array())
{
$encrypted_data = '';
$td = mcrypt_module_open('des', '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
if (mcrypt_generic_init($td, substr('sdf234d45)()*5gf512/?>:LPIJ*&U%&^%NBVFYUT^5hfhgvkjtIUUYRYT', 16, 8), $iv) != -1) {
if ($encrypt) {
// attempt to sanitize encryption for use as a form element name
$encrypted_data = mcrypt_generic($td, $text);
$encrypted_data = base64_encode($encrypted_data);
$encrypted_data = 'i' . strtr($encrypted_data, '+/=', '-_.');
//self::$encrypted[] = $encrypted_data;
$encryptedFields[] = $encrypted_data;
} else {
// reverse form element name sanitization and decrypt
$text = substr($text, 1);
$text = strtr($text, '-_.', '+/=');
$text = base64_decode($text);
$encrypted_data = mdecrypt_generic($td, $text);
}
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
return $encrypted_data;
}
$encryptedFields = array();
// encrypt some form fields
encryption('firstname', true, $encryptedFields);
encryption('lastname', true, $encryptedFields);
encryption('email_fields', true, $encryptedFields);
echo "Encrypted field names:\n";
print_r($encryptedFields);
// create a usable string of the encrypted form fields
$hiddenFieldStr = base64_encode(serialize($encryptedFields));
echo "\n\nFull string for hidden field: \n";
echo $hiddenFieldStr . "\n\n";
$encPostFields = unserialize(base64_decode($hiddenFieldStr));
echo "\n\nDecrypted field names:\n";
foreach($encPostFields as $field)
{
echo encryption($field, false)."\n";
}
?>
@cballou我也遇到了同样的问题-您是否找到了导致此问题的post数组(如下)的原因?@adam-修复方法是确保您的表单具有enctype=“multipart/form data”,因为这可以确保字符不会被编码和替换。谢谢cballou。我发布时使用了curl,但没有使用base64_编码-基本上是相同的修复!如果您感兴趣,我在@cballou使用此加密方法公开了我的垃圾邮件预防类SPF30。我也遇到了同样的问题-您是否找到导致它的post数组(如下)的原因?@adam-修复方法是确保您的表单具有enctype=“multipart/form data”因为这确保了字符不会被编码和替换。谢谢。我发布时使用了curl,但没有使用base64_编码-基本上是相同的修复!如果您感兴趣,我将使用此加密方法公开我的垃圾邮件预防类SPF30。值得注意的是,我的加密机制在尝试从表单解密发布的数据时不起作用,因为默认情况下,发布的数据将被编码。您必须设置
,因为这样可以确保不会对字符进行编码和替换。值得注意的是,在尝试从表单中解密发布的数据时,我的加密机制不起作用,因为默认情况下,发布的数据将被编码。您必须设置
,因为这样可以确保字符不会被编码和替换。