【问题标题】:WSSE - XML SOAP security and key encryption and storing (EncryptedData/EncryptedKey)WSSE - XML SOAP 安全和密钥加密和存储 (EncryptedData/EncryptedKey)
【发布时间】:2019-01-29 09:35:54
【问题描述】:

最近几天我一直在寻找有关此的文档..

我需要通过 SOAP 发送带有 WSSE 安全标头的 XML,但不知道如何加密和存储加密的密钥

这是一个例子

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
            <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-1B758D26C51BFCD86614340101135741">
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <wsse:SecurityTokenReference>
                        <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">MIIDODCCAiCgAwIBAgIGAU0FlCVCMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxCYW5rIENvbm5lY3QxFTATBgNVBAsTDEJhbmsgQ29ubmVjdDEdMBsGA1UEAxMUQmFuayBDb25uZWN0IElBLXRlc3QwHhcNMTUwNDI5MTQyODI0WhcNMTgwNDI5MTQyODI0WjAcMRowGAYDVQQDExFiYW5rIGNvbm5lY3QtdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAI23KdtaRKPTFTe/A1PnsF9dpSlTiXurKmio0OCgTP9wClHwync3JsInRwGTooA20P9zWobUnEFbEiAgRVYCxuYoldRE6NLhSC854/YTjMBeevH1TNa38lpavGiI4UwFhg70U9/JuYs21hoFyzVfaWlVfOkAMm1U/n4wHq6FZW461S5PY4A/UI1Mr8WgeIHU9GqMBtFvjynzq3SLenOPgdmKtyJ3V8EOU+DlgwKmDbxMVMtYNDZtoQvOWnuvlJ6ICDcqcW7OUkmwCKodjxxPvrdaPxyZDhT7h4FgRtrAOS8qR6L7x9D4ZIoxOMPudGvr99OSb4KVtaAEt/R7hKxG3OsCAwEAAaNCMEAwHwYDVR0jBBgwFoAU680YSkZnx1IaJAmI49LlTGiia0wwHQYDVR0OBBYEFMaWOY7Vf/iB3WVA96j5kRtbF8prMA0GCSqGSIb3DQEBCwUAA4IBAQAJ+bssSFWE6KsYT7HSDKag4Eot7yNGMY4Don/MilDnOREdu20QUS131DKrSkpBQiCXbyRUQjUoun4yue0EG+rlG3QUIlNNdJ4KZJB+dTYdLUV7XTYJNPimKAmoZ+PFNvT1eGgWcMT+MbTfpk0mw0V8IprYGa8UPchd6vtSVwpbTcPc/F4bgUTlm/V+FG4bQS61gF0koj0DEZjzat7CBHpozRgfRlXgwu26vnhWGc99uKH4GAKN4JpqPi/6Yz+7iQNJUC3yeezgBxFrIXuLpkBZSP4zunf9VxsICnxkFUXOTuYBdcbhPNzqMknD5ijFcFRZITwdv7x3uJGLkM7iUfBp</wsse:KeyIdentifier>
                    </wsse:SecurityTokenReference>
                </ds:KeyInfo>
                <xenc:CipherData>
                    <xenc:CipherValue>af9+FhA91ytLwjeRvTYJsRCkhjHmAQGwqYwMBoNZBn7BZhF/a6EUpM9ByarVhx1SRCpjW5fb8tBVuJO1ZkjfTUZ5EAh/oDLbkmwPdSAAVzmAURHwCq3XQgMZV3lAczlLnPamxjjZBCGqxvAmBo1CvFFPC4AcBedqY92mP8XGyVHpS7JYKOxqXK2vUA1by7371x+Mu0aoS2zJPyPLa1IPwOYgR9qicmWz1RNPiEVA8ZBCN0NRyg7FLJxdUcE81z+1SjButBo2j3qcwkNcecHzZAnweY+LSWp3H5JA3WNzUHUuvFHEaPzT5jd7fUI16xo8NLK8/Rd8Eq/zDD+T3baeVQ==</xenc:CipherValue>
                </xenc:CipherData>
                <xenc:ReferenceList>
                    <xenc:DataReference URI="#ED-1B758D26C51BFCD86614340101135852"/>
                </xenc:ReferenceList>
            </xenc:EncryptedKey>
        </wsse:Security>
        <technicalAddress xmlns="http://example.com/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"/>
        <activationHeader xmlns="http://example.com/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
            <organisationIdentification>
                <mainRegistrationNumber>8079</mainRegistrationNumber>
                <isoCountryCode>DK</isoCountryCode>
            </organisationIdentification>
            <functionIdentification>112233445566778899</functionIdentification>
            <erpInformation/>
            <endToEndMessageId>d28b6a7dad414014a59029ef1a7e84d4</endToEndMessageId>
            <createDateTime>2015-06-11T10:08:33.258+02:00</createDateTime>
        </activationHeader>
    </soap:Header>
    <soap:Body>
        <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-1B758D26C51BFCD86614340101135852" Type="http://www.w3.org/2001/04/xmlenc#Content">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
                    <wsse:Reference URI="#EK-1B758D26C51BFCD86614340101135741"/>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
                <xenc:CipherValue>dTSVuEJ90OYguQOsOz2ZtcE2mybwuvVl19pp7/e5yuvNygx3w5v+prpEvbjYLauiIAB3lrVDK2astJeYJGnDbaVJVeU0YqH5ItYVn7Wz36jJM52KB+UNbYo8EdTKYjsZuADzH+tAoA+pwYxGBXMEQctNI+C711HgP2hbpHNYOG7nAMOIrP/0B3FCy+st+9CbYlwAEENreTYunEEA41hciFnWCsIx0el7OeuiA6V51fAmvrF19RPNKwaptvbvmVdKj//RQ/0U1kRny16mDnFfX92bI3HBQm4XJA0nEfSvio7EUAAdhe77GMfu7+JELqXNowPGPLlvrbCFYnQhxGRITHtTIEbtJA6MKtBzHgjtw5pt7oWxKgGUnaJTfOPOSv43RLFGggkT/+gTjnZOagu8hhXp0x5HXJuZzw90aIS3jAfSPDc2ivct4WhWk0wcuQyC2rAh4I7gtiR+LqJJGqvucw4S+NR95FunKHKEW4yasKW1oU31/rRbp4Bmwo6BPsQlxnaSHPtk68IVkYDBslz1A5gOP+M/Iam2WI02y6sE/7aAH1ruN3pZlVuYFc3JDNHOPOvevP110d60lroknGdc9vxcFfj48OCKw/8Ed6tiXtAvk0Qu9Qt4ZyLUoPKIWEqjdLjwVadTDJQFAxRptNgiCos7s0czadUu7FNCRxfndjDxhA7trvys44ufEyK++YzZIgNu3r4dywNI22Nm+JZtLj+rX8ARE6FTPlxGBD0SSdXsfCfY2N1ytBBHQRnPsVaHK1p7KOhwQVbqEupcGyvaRolnymOzDLGFdS06OGYFrYXdgIbuqYtZP8QerXtUl0sWNAvvqHSPCQcpKecpMEecar+FUVwLEA+H1wzOprCMbRR+EgIboeDqQ7GxXqugkuFyvnlLDgxnaWhEhQb/5kAcQmnyUZ57MhDcUJqqQ4Cdmwrcxho1P+YqWY9yn0E86F+hl5976a/gH5KBobB84OWmgcX42eAmqpJf+8c8SuBv+7NctbQOk21aYlFEpkwSme/kG1/edtyoHQH/hF0RB1cT8g+u9S9AK2rs3s2G+Ap0U5oyY8pqJalGdZSBudE0sU4mhOV8trtx0FrN9A7pNkTcGPH25nCtyIz6rzR+DP8Mtgw5385s5ivVlDb+z74Wbh6iu7ZkVAogNTpUYU/1BxDXWJqFMkFmfziNxQ5AQqm1vGlBzXifoQkUFX1riutNphmu0Hs+7KMmMLvtW2cXmQDpkHFKVheeN4w7pBCEZ8KhZ0VTOwRZcdvrNcpYfXM13/QdTHQmCqqwgS/VvlUFz7PDn0/OKo6moUic8W6b1iEvd3kfc7QkunxoOUoJr4RwJ+PqCzN6PxQivAFA2tmDPc8qEa1PAdxTeNFoR/6dNQRojouuJq3C1LrbmGf6lQPvKi3KeKHXyjmDr7Tve+al2tcWJVr+1qEM3/XuthoiZbuTDxYUjZ2nf2fhHrmNcfvrfNxSNHVdQPp2R9Rf3eGxlRJsmRpef66VbYhOpmiH4xmq45EWiyBZmYm+tZtjsP51EDMIvdFbVRSGO/hMqURrDSsJXJeot27Iup2s0P2n/6a9k0c4SVvf/WXNN5x9JNvjU97bQNDQRfonJmo9pRYYHl1tSqNIYBK7KsMH+qr1vmiJuhrXUuL/RtOKvE9KXQ8kGoC9oF5rFn21z40ElxG5XRTASg==</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
    </soap:Body>
</soap:Envelope>

首先,我以前从未使用过 SOAP,所以我做错事的可能性很大 :)

在这里找到了一些东西,但我需要更多详细信息https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#aes256-cbc

ivkey 是如何存储在标头中的 CipherValue 中的?

向 web 服务发送 XML 请求时出现此错误

23-08-2018 12:50:02   General exception:Padding is invalid and cannot be removed.
23-08-2018 12:50:02   Stack trace:    at System.Security.Cryptography.CapiSymmetricAlgorithm.DepadBlock(Byte[] block, Int32 offset, Int32 count)
   at System.Security.Cryptography.CapiSymmetricAlgorithm.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at System.Security.Cryptography.Xml.EncryptedXml.DecryptData(EncryptedData encryptedData, SymmetricAlgorithm symmetricAlgorithm)
   at SomeClassCore.XmlSecurity.Decryptor.DecryptData(Byte[] symmetricKey)
   at SomeClassCore.SecurityServiceImpl.UnwrapRequest(ServiceRequest serviceRequest)
   at BD.BCA.MessageHandler.MessageHandler.ProcessRequest(HttpContext context)

已经搜索了更多.. 也许iv 必须是存储数据的一部分。但它仍然不起作用?和上面一样的错误

class Encryption {
    const AES256_CBC = 'AES-256-CBC';

    public function data_encrypt(string $data, string $cipher): Array{
        switch($cipher){
            case self::AES256_CBC:
                $key_length     = 32;
                $block_length   = 16;
                break;
        }

        $iv     = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
        $key    = openssl_random_pseudo_bytes($key_length);

        $encrypted_data = $iv.openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv);

        return [
            'data'  => base64_encode($this->pkcs7_padding($encrypted_data, $block_length)),
            'key'   => $key
        ];
    }

    public function key_encrypt(string $key): string{
        $public_cert = openssl_pkey_get_public('contents of public cert');
        openssl_public_encrypt($key, $data, $public_cert, OPENSSL_PKCS1_OAEP_PADDING);
        openssl_free_key($public_cert);

        return base64_encode($data);
    }

    private function pkcs7_padding(string $data, int $block_length): string{
        $pad = $block_length - (strlen($data) % $block_length);

        return $data.str_repeat(chr($pad), $pad);
    }
}

$Enc = new Encryption;
$data_encrypted = $Enc->data_encrypt('The message I want to encrypt', Encryption::AES256_CBC);

//  This base64 encoded string goes to <EncryptedData>
$data_encrypted['data'];

//  This base64 encoded string goes to <EncryptedKey> in the header
$Enc->key_encrypt($data_encrypted['key']);

更新

已与网络服务的维护者联系,OAEP padding 用于 RSA 加密,PKCS7 padding 用于 AES 芯片..

正如我所见,这也是我所做的?

【问题讨论】:

  • 简单建议;你确定你需要使用 OPENSSL_PKCS1_OAEP_PADDING 吗?也许 API 使用的是 PKCS5 或 PKCS7?此外,该 API 似乎存在 Padding Oracle 漏洞。
  • @jurgen,你的意思是:另外,这个 API 好像有 Padding Oracle 漏洞?
  • 我认为 jurgen 是对的。此错误消息:“Padding is invalid and cannot be removed”表示 API 易受攻击。详情请见owasp.org/index.php/Testing_for_Padding_Oracle_(OTG-CRYPST-002)
  • @t.m.adam,我会通知提供商 :) 但是您有解决方案吗?或者您现在有没有解决方案?我不是Java开发人员,所以我很难说..第一次非对称解密或第二次对称解密会失败吗? :)
  • 对不起,我不知道。让我研究一下这个问题,如果我发现有用的东西,我一定会发布答案或评论。

标签: php xml encryption soap


【解决方案1】:

您的错误表明 API 未能解密 openssl AES-256-CBC 数据。

我认为原因是因为在您的班级中,您通过pkcs7_padding() 函数路由加密。我相信默认情况下,只要您不在openssl_encrypt() 函数中指定OPENSSL_ZERO_PADDING,填充是pkcs7。所有 AES 加密的块大小为 128 位或 16 字节。

所以本质上你是在填充你已经填充的加密。所以基本上我只是从你的班级中删除了你的pkcs7_padding()

我确实测试了您的公钥加密。我能够使用来自2048b certificate 的 2048b rsa 密钥并使用 PEM 格式的证书生成加密的公钥。我不知道它是否正确填充。但是OPENSSL_PKCS1_OAEP_PADDING 可能是正确的。

我的猜测是,如果 API 进入 AES 部分,RSA 加密就会起作用。

至于如何将数据组装到 XML 中,我不知道。
但似乎合理的是,密码值中的&lt;xenc:EncryptedKey&gt; 标记将是 RSA 加密密钥,而&lt;xenc:EncryptedData&gt; 标记的密码值将是 AES 加密数据。您只需要弄清楚 API 是如何获取 IV 的。

阅读您的 API 文档,了解他们期望如何交付 IV。如果这对您不起作用,我也会继续寻找。

我稍后会对此进行研究。但是要知道尝试不手动填充加密。希望能帮助到你。

要考虑的另一件事是,在您的案例示例中,您不需要使用 IV。在您的 AES 加密中,您将为每次加密生成一个新密钥,然后通过您的证书获得的 RSA 公钥加密 AES 密钥。

如果您使用相同的 AES 密钥,我会看到需要实现 IV,但在这种情况下我不需要。无论如何...我们需要知道 API 是否需要 IV,如果需要,预计如何发送?

class Encryption {

    const AES256_CBC = 'AES-256-CBC';

    public function __construct(){



    }

    public function data_encrypt($data, $cipher){

        switch($cipher){
            case self::AES256_CBC:
                $key_length     = 32;
                $block_length   = 16;
                break;
        }

        $iv     = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher));
        $key    = openssl_random_pseudo_bytes($key_length);

        $encrypted_data = $iv . openssl_encrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv);

        return [
            'data'  => base64_encode($encrypted_data),
            'key'   => $key //Does this need to be encoded? 
        ];
    }

    //***Important***
    //Make sure you certificate is 1.) a x.509 certificate resource, 2.)A file path that leads to a PEM encoded certificate, or 3.) a PEM formatted key.
    public function key_encrypt($text){

        $keyResource = openssl_pkey_get_public(file_get_contents('path/to/myCert.pem')); //This returns a resource or FALSE.

        if(!$keyResource){
          echo 'Something wrong with certificate.';
        }

        openssl_public_encrypt($text, $cipherText, $keyResource, OPENSSL_PKCS1_OAEP_PADDING);
        openssl_free_key($keyResource); 
        return base64_encode($cipherText);

    }


}

$Enc = new Encryption;

$cipherText = $Enc->data_encrypt('The message I want to encrypt', Encryption::AES256_CBC);

//  This base64 encoded string goes to <EncryptedData>
echo 'AES Data: ' . $cipherText['data'] . '<br><br>';
echo 'AES Key: ' . $cipherText['key'] . '<br><br>';

//  This base64 encoded string goes to <EncryptedKey> in the header
$key = $Enc->key_encrypt($cipherText['key']);

echo 'RSA OAEP Padded Key: ' . $key;

【讨论】:

    【解决方案2】:

    *经过测试和工作的代码 * 我建议您将所涉及的不同部分分开。问题的最可能原因是执行顺序(即您应该在加密之前进行填充)。我也很惊讶没有签名,但在你的情况下可能不需要。但是,我准备了建议的代码供您测试,并添加了解密/解码功能以使测试更容易。祝你好运。

    <?php
    
    class Encryption {
    
        const AES256_CBC = 'AES-256-CBC';
        const IV_BYTES = 16;
    
        protected $binary_security_token = null;
        protected $private_key = null;
        protected $public_key = null;
    
        public function data_encrypt(string $data, string $password): Array {
    
            $key            = hash('sha256', $password, true);
            $iv             = openssl_random_pseudo_bytes(self::IV_BYTES);
    
            $padding        = 16 - (strlen($data) % 16);
            $data          .= str_repeat(chr($padding), $padding);
    
            $encrypted_data = openssl_encrypt($data, self::AES256_CBC, $key, OPENSSL_RAW_DATA, $iv);
            $encoded_data   = base64_encode($iv . $encrypted_data);
    
            return [
                'data'  => $encoded_data,
                'key'   => $key
            ];
        }
    
        public function data_decrypt(string $data, string $password): Array {
    
            $decoded_data   = base64_decode($data);
            $key            = hash('sha256', $password, true);
            $iv             = substr($decoded_data, 0, self::IV_BYTES);
            $encrypted_data = substr($decoded_data, self::IV_BYTES);
    
            $decrypted_data = openssl_decrypt($encrypted_data, self::AES256_CBC, $key, OPENSSL_RAW_DATA, $iv);
            $padding        = ord($decrypted_data[strlen($decrypted_data) - 1]); 
    
            return [
                'data' => substr($decrypted_data, 0, -$padding)
            ];
        }
    
        public function key_encrypt(string $key): ?string {
    
            $encoded_data = null;
    
            if ($this->public_key && openssl_public_encrypt($key, $data, $this->public_key, OPENSSL_PKCS1_OAEP_PADDING)) {
                $encoded_data = base64_encode($data);
            }
            // openssl_free_key($this->public_key);
    
            return $encoded_data;
        }
    
        public function key_decrypt(string $data): ?string {
    
            $decrypted_data = null;
    
            $decoded_data = base64_decode($data, true);
            if ($this->private_key && openssl_private_decrypt($decoded_data, $decrypted, $this->private_key, OPENSSL_PKCS1_OAEP_PADDING)) {
                $decrypted_data = $decrypted;
            }
            // openssl_free_key($decrypted);
    
            return $decrypted_data;
        }
    
        public function generate_keys(): void {
    
            $config = [ "private_key_bits" => 2048, "private_key_type" => OPENSSL_KEYTYPE_RSA ];
            $resource = openssl_pkey_new($config);
    
            if (openssl_pkey_export($resource, $this->private_key)) {
                echo "private_key:\n" . $this->private_key . "\n";
                $private_key_file = "private_key.pem";
                file_put_contents("private_key.pem" , $this->private_key);
            }
    
            $this->public_key = openssl_pkey_get_details($resource);
            $this->public_key = $this->public_key["key"];
            $this->binary_security_token = preg_replace("#-.+-|[\r\n]| #", "", $this->public_key);
            echo "public_key:\n" . $this->public_key . "\n";
            file_put_contents("public_key.pem", $this->public_key);
        }
    
        public function load_keys(): void {
    
            $private_key_path = realpath(dirname(__FILE__) . "/private_key.pem");
            if (!$private_key_path) {
                $this->generate_keys();
                return;
            }
            $private_key_contents = file_get_contents($private_key_path);
            if (!$private_key_contents) {
                $this->generate_keys();
                return;
            }
            $public_key_path = realpath(dirname(__FILE__) . "/public_key.pem");
            if (!$public_key_path) {
                $this->generate_keys();
                return;
            }
            $public_key_contents = file_get_contents($public_key_path);
            if (!$public_key_contents) {
                $this->generate_keys();
                return;
            }
    
            // Signature to see that data is not manipulated, could be performed on an encrypted body. The spec says you only make a signature for what you can see.
            // Is it important to "hide data", "detect manipulated data" or both ...
            $this->binary_security_token = preg_replace("#-.+-|[\r\n]| #", "", $public_key_contents); // BinarySecurityToken for securityToken in Security header
            // ValueType: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
            // EncodingType: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
    
            if (openssl_pkey_export($private_key_contents, $this->private_key)) {
                echo "private_key:\n" . $this->private_key . "\n";
            }
    
            $public_resource = openssl_pkey_get_public($public_key_contents);
            if ($public_resource) {
                $this->public_key = openssl_pkey_get_details($public_resource);
                $this->public_key = $this->public_key["key"];
                echo "public_key:\n" . $this->public_key . "\n";
            }
        }
    }
    
    $enc = new Encryption();
    
    $encrypted = $enc->data_encrypt("The message I want to encrypt", "password");
    
    // This base64 encoded string goes to <EncryptedData>
    // $encrypted['data']
    
    // Test that data_encrypt / data_decrypt works (from a terminal)
    echo "encrypted data:\n" . $encrypted["data"] . "\n";
    $decrypted = $enc->data_decrypt($encrypted["data"], "password");
    echo "decrypted data:\n" . $decrypted["data"] . "\n";
    
    // This base64 encoded string goes to <EncryptedKey> in the header
    // $enc->key_encrypt($encrypted['key']);
    if (version_compare(phpversion(), "7.1.0", ">=")) {
        $enc->load_keys();
        $pwd_hash_pre = bin2hex($encrypted["key"]);
        echo "hex key:" . $pwd_hash_pre . "\n";
        $encrypted_key = $enc->key_encrypt($encrypted["key"]);
        echo "\nencrypted and base64encoded key:" . $encrypted_key . "\n";
        $decrypted_key = $enc->key_decrypt($encrypted_key);
        $pwd_hash_post = bin2hex($decrypted_key);
        echo "\ndecrypted and decoded key:" . $pwd_hash_post . "\n";
        $equal_hashes = $pwd_hash_pre === $pwd_hash_post ? 'true' : 'false';
        echo "password hashes equal:" . $equal_hashes . "\n";
    }
    

    【讨论】:

      猜你喜欢
      • 2014-10-18
      • 2015-07-04
      • 2011-01-03
      • 1970-01-01
      • 2011-10-14
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      相关资源
      最近更新 更多