【问题标题】:PHP: SHA-256 force in UTF-8PHP:UTF-8 中的 SHA-256 强制
【发布时间】:2019-07-08 20:35:01
【问题描述】:

这是我使用 PHP 的问题:对于与 Postfinance 的电子支付集成,我需要使用所有字段的 SHA-256 哈希验证发送和接收的数据,每个字段之间都有一个密钥。

如何确定输入字符串在散列之前是 UTF-8 格式?

命令utf8_encode() 用于输入字符串,如果我用mb_check_encoding() 进行检查,就可以了。我有很好的响应,如果我使用 mb_detect_encoding(),响应是“ASCII”。

$pf_post = array();

$pf_post['AMOUNT'] = 100;
$pf_post['CURRENCY'] = "CHF";
$pf_post['ORDERID'] = 101;
$pf_post['TITLE'] = "Paiement";

$pf_key = "mytestkey";

foreach (array_keys($pf_post) as $lakey)
{
    $pf_string .= strtoupper($lakey) . "=" . strval($pf_post[$lakey]) . $pf_key;
}

$pf_string = utf8_encode($pf_string);
$pf_sign = hash('sha256',$pf_string);

if (mb_check_encoding($pf_string, 'UTF-8')) {
    $debug .= "STRING => Détection UTF8 OK !<br>";
}
else {
    $debug .= "STRING => Détection UTF8 !!! ERREUR !!!<br>";
}

if (mb_check_encoding($pf_sign, 'UTF-8')) {
    $debug .= "HASH => Détection UTF8 OK !<br>";
}
else {
    $debug .= "HASH => Détection UTF8 !!! ERREUR !!!<br>";
}

$debug .= "String Format: " . mb_detect_encoding($pf_string) .
          ", Hash Format: " . mb_detect_encoding($pf_sign) . "<br>";

这是调试:

STRING => Détection UTF8 OK !
HASH => Détection UTF8 OK !
String Format : ASCII, Hash Format : ASCII

如果我在字段中只使用数字,那没关系……如果我使用字母,那不是每次都可以……如果使用带重音的字母……任何时候都是错误的!

在 HTML 标头中,我有:

<meta charset="utf-8"/>

我该如何解决这个问题?

【问题讨论】:

  • 嗨!你试过这个吗? stackoverflow.com/a/1037368/1461181
  • “命令 utf8_encode() 用于输入字符串” - 为什么,它已经不是 UTF-8 了?我们在这里谈论的是表单数据,对吧?您的页面已经采用 UTF-8 格式,那么您是如何设法让表单数据一开始就以 UTF-8 格式发送not
  • 或者您只是在谈论这里的$pf_post 数据?如果那不是 UTF-8,则意味着您没有将脚本文件本身保存为 UTF-8 - 所以 that 将是您需要更正的东西,而不是在运行时弄乱编码。 ..
  • utf8_encode() == 你的输入字符串确定是only ISO-8859-1 类型吗?
  • 感谢您的帮助!!!

标签: php utf-8 sha256


【解决方案1】:

您不应将值编码为 UTF-8 两次。我建议仅在确实必要时进行编码。示例:

if (!mb_check_encoding($pf_string, 'UTF-8')) {
    $pf_string = mb_convert_encoding($pf_string, 'UTF-8');
}

【讨论】:

    【解决方案2】:

    这里有一些例子:

    $str = "éóùùééééè"; // Will output 'éóùùééééè'
    $strr = utf8_encode($str); // Will output 'éóùùééééè'
    

    如果应用到 UTF-8 字符串,utf8_encode() 将返回一个乱码的 UTF-8 输出,如示例所示。

    为确保您使用的是 UTF-8,请在每个脚本的顶部使用 mb_internal_encoding('UTF-8'),您可以使用此 forceutf8 class

    <?php
        // Tell PHP that we're using UTF-8 strings until the end of the script
        mb_internal_encoding('UTF-8');
    
        include('Encoding.php'); // The class from GitHub
    
        // Same strings
        $str = 'éóùùééééè';
        $str1 = 'éóùùééééè'; //garbled UTF8 of éóùùééééè
    
        // Force input to UTF-8
        use \ForceUTF8\Encoding;
        echo Encoding::fixUTF8($str).'</br>'; // Will output éóùùééééè
        echo Encoding::fixUTF8($str1).'</br>'; // Will output éóùùééééè
    
        $str3 = Encoding::fixUTF8($str);
        $str4 = Encoding::fixUTF8($str1);
    
    
        // Then hash
        $hash1 = hash('sha256', $str3);
        $hash1 = hash('sha256', $str4);
    
        echo $hash1; // Will output 45b8151559a5136d58f85ebf51c24f26c47e51f4a89fe2962c8626e99ad64786
        echo $hash2; // Will output 45b8151559a5136d58f85ebf51c24f26c47e51f4a89fe2962c8626e99ad64786
    
        // mb_detect_encoding will always output ASCII
        echo  mb_detect_encoding($hash1). '</br>'; // Will output ASCII
        echo  mb_detect_encoding($hash1); //// Will output ASCII
    

    在浏览器级别,您需要:

    <meta charset="UTF-8">
    

    【讨论】:

    • 感谢您提供这个非常完整的演示!
    猜你喜欢
    • 2012-08-09
    • 2016-04-29
    • 2012-07-07
    • 1970-01-01
    • 2021-01-22
    • 2013-06-03
    • 2014-08-19
    • 2018-07-14
    • 2021-04-28
    相关资源
    最近更新 更多