4

私はほぼ 1 年間、仕事関連の xml に署名してきましたが、今日、自分のやり方が間違っていることに気付きました (下手な英語で申し訳ありません。それは私の母国語ではありません)。

私は xmlseclibs ライブラリを php に使用していますが、署名を次のようにしたいと考えています。

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#XXXXX">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>... </DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>... </SignatureValue>
<KeyInfo>
<KeyValue>
</KeyValue>
<X509Data>
<X509Certificate>... </X509Certificate>
</X509Data>
</KeyInfo>
</Signature>

次の例は、私がやりたいことを示すのに役立ちます。次のxmlファイルがあります。

<node1>
  <node2>
    somedata
  </node2>
</node1>

そして、署名した後、次のようになります。

<node1>
  <node2>
    somedata
  </node2>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#XXXXX">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>... </DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>... </SignatureValue>
<KeyInfo>
<KeyValue>
</KeyValue>
<X509Data>
<X509Certificate>... </X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
</node1>

これが必要な構造ですが、これを行うと、すべてのドキュメント (ノード 1 とノード 2)に署名が適用されますが、ノード 2 にのみ署名したい (これは取得中のエラーです。DigestValue のおかげで気づきました) )。

しかし、私がそれをすると、次のようになりました:

<node1>
  <node2>
    somedata
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#XXXXX">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>... </DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>... </SignatureValue>
<KeyInfo>
<KeyValue>
</KeyValue>
<X509Data>
<X509Certificate>... </X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
  </node2>
</node1>

何日も試してみましたが、署名を配置したい場所に配置できません (内部ではなく、署名されたタグのすぐ下)。

何かご意見は?

私が使用している機能は次のようなものです:

function firmarEnvio2($xmlr){
$doc = new DOMDocument();
$xml = file_get_contents($xmlr);
$doc->loadXML($xml);
$doc->preserveWhiteSpace = true;
$doc->encoding = 'ISO-8859-1';

$objDSig = new XMLSecurityDSig(FALSE); 
$objDSig->setCanonicalMethod(XMLSecurityDSig::C14N);

echo "<pre>";
$options['prefix'] = '';
$options['prefix_ns'] = '';
$options['force_uri'] = TRUE;
$options['id_name'] = 'ID';

$objDSig->addReference($doc, XMLSecurityDSig::SHA1, array(XMLSecurityDSig::TR_ENV_SIG), $options);

/*
$objDSig->addReference($doc->documentElement, XMLSecurityDSig::SHA1,
array(
'http://www.w3.org/2000/09/xmldsig#enveloped-signature',
'http://www.w3.org/2001/10/xml-exc-c14n#'
),
array('id_name' => 'Id', 'overwrite' => false));


*/

$objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));

$pass = "some string";
$pfx =   file_get_contents("someroute/certificate.pfx");
openssl_pkcs12_read($pfx, $key, $pass);

$objKey->loadKey($key["pkey"]);
$objDSig->add509Cert($key["cert"]);

$tag="x";

//the following is to compare the digest that i want with the one i always got
echo "<br><br>Digest1<br>";
print_r (base64_encode(sha1($doc->documentElement->C14N(), true)));

echo "<br><br>Digest2<br>";
print_r (base64_encode(sha1($doc->documentElement->getElementsByTagName($tag)->item(0)->C14N(), true)));

print_r ($firma);
$objDSig->sign($objKey, $doc->documentElement);


//print_r($doc);
$doc->save('test_s.xml');
return true;
}

誰もこれを行う方法を知っていますか?

4

1 に答える 1

2

最近、xmlseclibs ライブラリで同じ問題が発生しました。これが私のために働いたものです:

function signXML($xml) {

    $doc = new \DOMDocument('1.0','UTF-8');
    $doc->loadXML($xml);
    $objDSig = new XMLSecurityDSig('');
    $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
    $node = $objDSig->addObject($doc->documentElement);
    $objDSig->addReference(
        $node, 
        XMLSecurityDSig::SHA1
    );
    $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
    $privkey = $this->serverroot.'/certs/dev.key';
    $objKey->loadKey($privkey, TRUE);
    $objDSig->sign($objKey);
    $pubkey = $this->serverroot.'/certs/dev-pub.cer';
    $objDSig->add509Cert(file_get_contents($pubkey));
    $node->ownerDocument->encoding = "UTF-8";
    $node->ownerDocument->save(dirname(__FILE__).'/test.xml');

    return $node->ownerDocument->saveXML();
}

それが助けになることを願っています。

于 2016-04-21T22:46:36.420 に答える