我已经签署了 XML,但我不知道如何在签名中包含 KeyValue 元素。拥有一些文档会节省很多时间。
下面的代码(如果您感兴趣的话)是我迄今为止使用 xmlseclibs 所做的事情:
<?php
require('xmlseclibs.php');
Run Code Online (Sandbox Code Playgroud)
XML字符串
$getToken = '<getToken>
<item>
<Semilla>Random string</Semilla>
</item>
</getToken>';
Run Code Online (Sandbox Code Playgroud)
创建 XML 对象(用于签名)
$getToken_DOMDocument = new DOMDocument();
$getToken_DOMDocument -> loadXml($getToken);
Run Code Online (Sandbox Code Playgroud)
使用 xmlseclibs 创建签名对象
$getToken_XMLSecurityDSig = new XMLSecurityDSig();
$getToken_XMLSecurityDSig -> setCanonicalMethod(XMLSecurityDSig::C14N);
Run Code Online (Sandbox Code Playgroud)
尝试关闭 ds: 前缀,但不起作用
$options['prefix'] = '';
$options['prefix_ns'] = '';
$options['force_uri'] = TRUE;
$options['id_name'] = 'ID';
$getToken_XMLSecurityDSig -> addReference($getToken_DOMDocument, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'), $options);
Run Code Online (Sandbox Code Playgroud)
访问必要的关键数据
$XMLSecurityKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type'=>'private'));
$XMLSecurityKey -> loadKey('../../DTE/certificado/firma/certificado.pem', TRUE);
/* if key has Passphrase, set it using $objKey -> …Run Code Online (Sandbox Code Playgroud) 在本例中,有两个 PHP 文件,stdin.php(子进程组件)和proc_open.php(父进程组件),它们都存储在域的 public_html 的同一文件夹中。还有Program X,它将数据传输到 stdin.php 中。
stdin.php(该组件有效)
这是一个不应通过浏览器执行的进程,因为它的目的是接收来自程序 X 的输入,并将其全部备份到一个文件(名为 stdin_backup)中。这个过程是有效的,因为每次程序 X 通过管道输入时,该过程都会完全备份它。如果在未传递输入的情况下执行此进程(例如从浏览器执行它的情况),则该进程将创建一个带有文本“ERROR”的文件(名为 stdin_error)。
下面省略了部分代码,因为该过程有效(如上所述)。显示的代码只是为了说明:
#!/usr/bin/php -q
<?php
// Get the input
$fh_stdin = fopen('php://stdin', 'rb');
if (is_resource($fh_stdin)) {
// ... Code that backs up STDIN in a file ...
} else {
// ... Code that logs "ERROR" in a file ...
}
?>
Run Code Online (Sandbox Code Playgroud)
proc_open.php(该组件不起作用)
它是一个必须通过浏览器执行的进程,并且旨在将输入传递到 stdin.php,就像程序 X 所做的那样。这个过程失败了,因为每次执行时,都没有stdin.php被执行的信号:没有stdin_error文件,没有stdin_backup文件,甚至没有PHP error_log文件。
代码:
// Execute a PHP process and …Run Code Online (Sandbox Code Playgroud) 如果我想用envoloped签名签署下一个XML代码:
<root>
<element>
<child>text node</child>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
然后,签名XML代码在签名的XML代码中进行,方式如下所示:
<root>
<element>
<child>text node</child>
</element><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>
Notice: no line break nor single character is added outside Signature element since that would invalidate the signature.
Run Code Online (Sandbox Code Playgroud)
XML包含的签名代码包括<Transform Algorithm>,其指定代码必须遭受的修改,严格地说,无论是在签名还是验证过程中都进行.<Transform Algorithm>是下一个:
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
Run Code Online (Sandbox Code Playgroud)
在W3C网站(官方文档)中,将上面的表达式与下面的表达式进行比较.在这两种情况下都必须产生相同的输出.
<XPath xmlns:dsig="&dsig;">
count(ancestor-or-self::dsig:Signature |
here()/ancestor::dsig:Signature[1]) >
count(ancestor-or-self::dsig:Signature)</XPath>
Run Code Online (Sandbox Code Playgroud)
参考:http://www.w3.org/TR/xmldsig-core/#sec-EnvelopedSignature
变形之前:
案例1(签署):
<root>
<element>
<child>text node</child>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
案例2(签字):
<root>
<element>
<child>text node</child>
</element><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">...</Signature>
</root>
Run Code Online (Sandbox Code Playgroud)
变换后:
<root>
<element>
<child>text node</child>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
在这两种情况下都会生成相同的输出,这使我们可以验证签名数据是否可信.
我仍然遇到服务器问题,说我的签名无效,有人可以确认我是否正确地进行了转换?
非常感谢
问候
目前,我正在使用cPanel管理邮箱。我在cPanel中配置了邮箱,以将电子邮件通过管道传递到PHP脚本。我仅出于此目的使用cPanel,所以我想摆脱所有这些装备。
我需要的是:
这些PHP扩展依赖于预先存在的电子邮件服务器和帐户,因此仅靠这些是不够的。
从我一直在研究的内容来看,显然我需要通过CLI或CGI在PHP命令行中进行操作,不确定是哪一个。
我在使用LAMP CentOS的VPS中工作,也许有一个开源PHP应用程序或库可以在这里实现,仅用于特定任务。
使用方案验证XML DOMDocument时:
$ result = $ Document - > schemaValidate('../../ DTE/document/scheme.xsd');
我收到一条警告信息:
警告:DOMDocument :: schemaValidate():元素'foo':不期望此元素.预期是({url} foo,{url} bar)之一.
'foo'和'{url} foo'有什么区别以及如何修复此警告?