我完全绝望了。我前段时间尝试使用vba找到答案,但没有得到解决方案。
我回到负载尝试从命令行使用 cURL,但它也不起作用。在这种情况下,我将向您展示使用 CURL 执行的整个过程,根据我能够记录的内容,它应该可以工作。但是有些事情让我无法理解,因为我无法让财政部 Web 服务接收我的文件
出口证书 (.pfx)
为了使用证书,首先你必须从我的浏览器中导出它。为此,您可以执行以下操作:
- 铬设置
- 管理证书...
- 导出私钥
- 个人信息交换:PKCS #12 (.PFX)
- 在认证路径中包含所有证书(如果可能)
- 导出所有扩展属性
- 给它密码:12345
- 将文件命名为:Certificate.pfx
- 个人信息交换:PKCS #12 (.PFX)
- 导出私钥
- 管理证书...
完成此操作后,我将获得 .pfx 格式的证书
将 .pfx 证书转换为 .pem (OpenSSL)
此格式对 cURL 无效。因此,必须先将其转换为 .pem。为此,他们到处谈论 OpenSSL。我在 2017 年 5 月 25 日下载了 1.0.21 版本(从命令行访问)我转换证书:
--Importo certificado PEM (sin key)
C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in C:\VariasSII\Certificados\Certificado.pfx -out C:\VariasSII\Certificados\Certificado-CL.pem -clcerts -nokeys
--Importo KEY
C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in C:\VariasSII\Certificados\Certificado.pfx -out C:\VariasSII\Certificados\Certificado-KEY.pem -nocerts
--Importo CA (Esto en muchas partes no se usa. Lo tengo, y puedo ponerlo o no, aunque en cualquiera de los casos no me sirve para que funcione el envío
C:\OpenSSL-Win64\bin\openssl.exe pkcs12 -in C:\VariasSII\Certificados\Certificado.pfx -out C:\VariasSII\Certificados\Certificado-CA.pem -cacerts -nokeys
发送(使用 cURL)
最后,通过这条指令,您应该能够将 XML 文件发送到财政部:
curl --data C:\VariasSII\TEST.xml --output C:\VariasSII\respuesta.xml --cert C:\VariasSII\Certificados\Certificado-CL.pem --key C:\VariasSII\Certificados\Certificado-KEY.pem https://www7.aeat.es/wlpl/SSII-FACT/ws/fe/SiiFactFEV1SOAP
卷曲响应
对此请求的响应如下:
<?xml version="1.0" encoding="UTF-8"?><env:Envelope
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><env:Body><env:Fault>
<faultcode>env:Client</faultcode><faultstring>Codigo[1304].No se permite
contenido en el prólogo. (1,1)</faultstring><detail><callstack>XML no válido o mal formado
WSExcepcion [faultcode=null, detailMap=null, version=0, faultstring=No se permite contenido en el prólogo. (1,1), faultactor=null, faultSubCode=null, reasonText=null, detail=null, nameSpaceUriDetail=null]
at es.aeat.adws.jdit.imp.ws.WSFilterSrvImpl.verificarFirma(WSFilterSrvImpl.java:810)
at es.aeat.adws.jdit.imp.ws.WSFilterSrvImpl.doFilter(WSFilterSrvImpl.java:246)
at es.aeat.adws.jdit.api.ws.WSFilter.doFilter(WSFilter.java:24)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at es.aeat.adht.jdit.imp.infra.JDitFilterSrvImpl.filtroIni(JDitFilterSrvImpl.java:178)
at es.aeat.adht.jdit.imp.infra.JDitFilterSrvImpl.doFilter(JDitFilterSrvImpl.java:86)
at es.aeat.adht.jdit.imp.infra.JDitFilterSrvImpl.doFilter(JDitFilterSrvImpl.java:63)
at es.aeat.adht.jdit.api.filter.JDitFilter.doFilter(JDitFilter.java:24)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:207)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:1021)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1143)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:82)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:934)
at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost$2.run(DynamicVirtualHost.java:262)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink$TaskWrapper.run(HttpDispatcherLink.java:958)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.wrapHandlerAndExecute(HttpDispatcherLink.java:357)
at com.ibm.ws.http.dispatcher.internal.channel.HttpDispatcherLink.ready(HttpDispatcherLink.java:317)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:471)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.handleNewRequest(HttpInboundLink.java:405)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.processRequest(HttpInboundLink.java:285)
at com.ibm.ws.http.channel.internal.inbound.HttpInboundLink.ready(HttpInboundLink.java:256)
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:174)
at com.ibm.ws.tcpchannel.internal.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:83)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.requestComplete(WorkQueueManager.java:504)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:574)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager.workerRun(WorkQueueManager.java:929)
at com.ibm.ws.tcpchannel.internal.WorkQueueManager$Worker.run(WorkQueueManager.java:1018)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1153)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.lang.Thread.run(Thread.java:785)
Caused by: es.aeat.adws.jdit.api.xml.XmlExcepcion: No se permite contenido en el prólogo. (1,1)
at es.aeat.adws.jdit.imp.xml.DomUtilsImpl.isToDoc(DomUtilsImpl.java:85)
at es.aeat.adws.jdit.imp.xml.DomUtilsImpl.isToDoc(DomUtilsImpl.java:51)
at es.aeat.adws.jdit.imp.ws.WSFilterSrvImpl.verificarFirma(WSFilterSrvImpl.java:781)
... 31 more
Caused by: org.xml.sax.SAXParseException: No se permite contenido en el prólogo.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
at org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at es.aeat.adws.jdit.imp.xml.DomUtilsImpl.isToDoc(DomUtilsImpl.java:81)
... 33 more
根据错误,似乎错误在 XML 文件中,但我向您保证它不是。该文件可以从税务机关的启用环境完美发送,没有问题,也可以使用外部应用程序(SoapUI)发送
最后的考虑
在某些网页中,我看到他们导出了证书的 CA 以便稍后在 cURL 中使用它(我之前添加了允许提取 CA 的指令)。但是,在大多数咨询站点中,他们不使用此 CA。
在信息层面,使用所述 CA 会生成以下警告:
curl.exe [...] --cacert C:\VariasSII\Certificados\Certificado-CA.pem
curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
我确信问题出在证书上。但是考虑到 certificate.pfx 工作正常(我已经用 SoapUI 对其进行了测试,并且我已经将它导出到另一台计算机上,能够在该计算机上毫无问题地使用该证书)......我会认为使用 OpenSSL 时在 .pem 中转换 .pfx 时出现问题?我在网上找到的 OpenSSL 和 cURL 中的步骤,并检查了所有可能的来源。它适用于人们。但我不会从这里继续前进。
希望有人可以对这个问题有所了解。
我修改了答案,因为您的问题似乎不在于证书,而在于 cURL 参数。
如何从 cURL 拨打电话
逐个部分:
--cert ./ALEXANDRU_CATALIN_bundle.pem
设置证书--header "Content-Type: text/xml;charset=UTF-8"
指示发送的内容类型--header "SOAPAction: SuministroLRFacturasEmitidas"
表示我们要调用的webservice命令--data @datos_xml.txt
指定带有数据的文件,重要的是显然@
文件路径前面的那个是一个非常重要的细节,因为它告诉 cURL 它应该从文件中读取内容
datos_xml.txt
:回复:
如何获得有效的 PEM 捆绑证书
我告诉你获得有效证书的步骤,但前两个注意事项:
开始了..
这些是要执行的命令
openssl
:使用这些命令,您一方面提取证书,另一方面提取私钥,示例:
内容
archivo_mycert.pem
:内容
archivo_mykey.pem
:接下来,您必须做的是创建第三个文件,我们将调用它
archivo_bundle.pem
,并在该文件中粘贴证书和密钥的内容,留下如下内容:完成,现在您将使用该文件
archivo_bundle.pem
作为 cURL 或 SoapClient 调用中的参数。最后,让我告诉你,在http://www.aeatsiidesarrolladores.es/ ,我写了一本关于 SII 实施的技术电子书。它包含 PHP 中的代码示例和一个与 SII 具有整个通信电路的迷你应用程序,只需将其上传到服务器并留下 PFX 格式的证书即可运行。你可能有兴趣看看!运气!:-)