【问题标题】:Xades4j - How can I enter a hash for SHA256?Xades4j - 如何输入 SHA256 的哈希?
【发布时间】:2021-09-03 00:32:48
【问题描述】:

我需要用 XAdES-EPES、RSA-SHA256 和以下哈希对 xml 文件进行签名:Quzn98x3PMbSHwbUzaj5f5KOpiH0u8bvmwbbbNkO9Es

我签署了 XML,但它无效,因为我不知道如何输入该哈希。这是我的代码:

public class Firma{

private static final String FOLDER = "C:/ECLIPSE/PRUEBAS_Firma/";
private static final String CERT = "SOLDISP_XXXXX.p12";// "Certificado de
                                                        // dispositivo
private static final String PASS = "xxxxxx";

private static final String DOCUMENT = "C:/ECLIPSE/PRUEBAS_Firma/Ejemplo_TicketBAI_B00000034_B2022_0101_SinFirma.xml";

public static void main(String[] args) throws Exception {
    System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");

    System.out.println(">>>>>>>>> Firmando XML");
    signEpes();
}

private static void signEpes() throws Exception {
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(DOCUMENT));
    Element elem = doc.getDocumentElement();
    DOMHelper.useIdAsXmlId(elem);

    KeyingDataProvider kdp = new FileSystemKeyStoreKeyingDataProvider("pkcs12", FOLDER + CERT,
            new FirstCertificateSelector(), new DirectPasswordProvider(PASS), new DirectPasswordProvider(PASS),
            true);
    // politica
    SignaturePolicyInfoProvider policyInfoProvider = new SignaturePolicyInfoProvider() {
        @Override
        public SignaturePolicyBase getSignaturePolicy() {
            return new SignaturePolicyIdentifierProperty(

                    new ObjectIdentifier(
                            "https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf",
                            IdentifierType.URI, ""),
                    new ByteArrayInputStream(
                            "https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf"
                                    .getBytes())

            );
        }
    };

    SignerEPES signer = (SignerEPES) new XadesEpesSigningProfile(kdp, policyInfoProvider).newSigner();

    new Enveloped(signer).sign(elem);

    outputDocument(doc, "Factura_firmada.xml");
}

protected static void outputDocument(Document doc, String fileName) throws Exception {
    TransformerFactory tf = TransformerFactory.newInstance();
    File outDir = ensureOutputDir();
    FileOutputStream out = new FileOutputStream(new File(outDir, fileName));
    tf.newTransformer().transform(new DOMSource(doc), new StreamResult(out));
    out.close();
}

private static File ensureOutputDir() {
    File dir = new File(toPlatformSpecificFilePath(FOLDER));
    dir.mkdir();
    return dir;
}

}

拜托,谁能帮帮我??? 提前致谢

【问题讨论】:

    标签: xml sign xades4j xades


    【解决方案1】:

    必须从源策略页面 Stream 计算哈希。下面的代码做你想做的,改变你需要适应你的场景的任何东西。 您可以在创建时更改代码

    SignaturePolicyInfoProvider

    SignaturePolicyInfoProvider policyInfoProvider = new SignaturePolicyInfoProvider() {
                    @Override
                    public SignaturePolicyBase getSignaturePolicy() {
                        try {
                            //PolicyDocumentStream o PolicyDocumentData calculado a partir del contenido de la URL
                            URL url = new URL("https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf");
                            if ("https".equals(url.getProtocol())) {
                                HttpsURLConnection.setDefaultSSLSocketFactory(getTrustAllClientSecureContext("TLS").getSocketFactory());
                                HttpsURLConnection.setDefaultHostnameVerifier(new TrustAllHostnameVerifier());
                            }
                            URLConnection urlConn = url.openConnection();
                            urlConn.setConnectTimeout(5000);
                            urlConn.setReadTimeout(60000);
                            //Dummy "User-Agent"
                            urlConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0");
                            return new SignaturePolicyIdentifierProperty(new ObjectIdentifier("https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf", IdentifierType.URI), new BufferedInputStream(urlConn.getInputStream()))
                                    .withLocationUrl("https://www.batuz.eus/fitxategiak/batuz/ticketbai/sinadura_elektronikoaren_zehaztapenak_especificaciones_de_la_firma_electronica_v1_0.pdf");
                        } catch (Exception ex) {
                            System.out.println("ERROR: SignaturePolicyInfoProvider...");
                            ex.printStackTrace();
                        }
                        return null;
                    }
                };
    

    另外我给你用于 https 通信的辅助代码。

    public SSLContext getTrustAllClientSecureContext(String secureSocketProtocol) {
            SSLContext context = null;
            if (secureSocketProtocol == null) {
                secureSocketProtocol = "TLS";
            }
            try {
                context = SSLContext.getInstance(secureSocketProtocol);
                context.init(null, new TrustManager[]{new TrustAllTrustManager()}, null);
            } catch (Exception e) {
                System.out.println("ERROR: " + e.getMessage());
            }
            return context;
        }
    
    public class TrustAllTrustManager implements X509TrustManager {
    
        @Override
        public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
    
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
    
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
    
    public class TrustAllHostnameVerifier implements HostnameVerifier {
    
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    
    }
    

    当然,在生产中必须避免“允许所有证书”连接到 URL 的操作,而是最好将相应的证书添加到您的证书存储中。

    【讨论】:

      猜你喜欢
      • 2011-06-08
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 2016-07-09
      相关资源
      最近更新 更多