如何以最快的方式用Java签名XML

时间:2018-07-17 08:54:17

标签: java oracle11g

需要有关(优化)以及如何以最快的方式用证书对XML签名的一些技巧/建议。在某些数据库(Oracle)上,对文件进行签名需要30毫秒。但是在另一个数据库上,它需要1.2秒。在循环中调用此函数/方法。它对一些XML数据进行签名,并在字符串中返回签名的XML。 (Java方法公开为PL / SQL函数)。

public static String signXML(String vhodniXml) throws Exception {
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    dbFactory.setNamespaceAware(true);
    Document doc =  dbFactory.newDocumentBuilder().parse(new ByteArrayInputStream(vhodniXml.getBytes()));

    NodeList nl = doc.getElementsByTagName("fu:BusinessPremiseRequest");
    Node node = nl.item(0);
    ((Element) node).setIdAttribute("Id", true);

    Enumeration e = p12.aliases();
    String alias = (String) e.nextElement();

    Key privateKey = p12.getKey(alias, geslo.toCharArray());

    KeyStore.PrivateKeyEntry keyEntry
            = (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection(geslo.toCharArray()));

    X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

    PublicKey publicKey = cert.getPublicKey();
    final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
    // Create a Reference to the enveloped document
    Reference ref = sigFactory.newReference("#data",
            sigFactory.newDigestMethod(DigestMethod.SHA256, null),
            Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
            null,
            null);

    SignedInfo si = sigFactory.newSignedInfo(sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref));

    // Create a KeyValue containing the RSA PublicKey
    KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();
    X509IssuerSerial x509IssuerSerial = keyInfoFactory.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());

    List x509Content = new ArrayList();

    x509Content.add(cert.getSubjectX500Principal().getName());
    x509Content.add(x509IssuerSerial);

    KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
    X509Data xd = keyInfoFactory.newX509Data(x509Content);

    // Create a KeyInfo and add the KeyValue to it
    KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));

    // Create a DOMSignContext and specify the RSA PrivateKey and
    // location of the resulting XMLSignature's parent element
    DOMSignContext dsc = new DOMSignContext(
            privateKey,
            node
    );

    // Create the XMLSignature (but don't sign it yet)
    XMLSignature signature = sigFactory.newXMLSignature(si, keyInfo);

    // Marshal, generate (and sign) the enveloped signature
    signature.sign(dsc);

    ByteArrayOutputStream os = new ByteArrayOutputStream();
    Transformer trans = TransformerFactory.newInstance()
            .newTransformer();
    trans.transform(new DOMSource(doc), new StreamResult(os));

    return new String(os.toByteArray());
}

1 个答案:

答案 0 :(得分:1)

第一件事是通过将与密钥相关的对象存储在字段中来删除一些IO操作,因为读取KeyStore来获取密钥需要时间。