gpt4 book ai didi

php - WSSE - XML SOAP 安全和 key 加密和存储 (EncryptedData/EncryptedKey)

转载 作者:IT王子 更新时间:2023-10-29 00:13:14 31 4
gpt4 key购买 nike

最近几天我一直在寻找关于这个的文档..

我需要使用 WSSE 安全 header 通过 SOAP 发送 XML,但不知道如何加密和存储加密 key

举个例子

<?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是如何存储在header的CipherValue中的?

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

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']);

更新

已与 web 服务的维护者联系,OAEP 填充 用于 RSA 加密,PKCS7 填充 用于 AES chipher..

据我所知,这也是我所做的?

最佳答案

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

<?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";
}

关于php - WSSE - XML SOAP 安全和 key 加密和存储 (EncryptedData/EncryptedKey),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51978460/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com