我在尝试 数字签名的XML文件 使用Java。我已经有了一个实施工作与一些引用我发现使用的各种实现在 javax.xml.crypto.dsig 包。

但是,我目前的执行就像是 很多 我已经看过了-这是相当详细,涉及使用不少于23个不同的API类 java.xml.crypto.dsig, javax.xml.transform, , java.security 包,等等。这感觉就像我进入了 工厂厂厂 土地,和我花了几个小时只是要找出什么事情。

我的问题是, 是有一个更简单的方式做到这一点? 如果我已经得到了公共/私人钥匙文件和我想添加一个 <Signature/> XML文件,是否有一个图书馆在那里,只是让我的叫是这样的:

OutputStream signFile(InputStream xmlFile, File privateKey)

...没有所有的XMLSignatureFactory/CanonicalizationMethod/DOMSignContext疯狂?

我不是非常精密,并Java-提供API似乎相当令人望而却步开发像自己的努力变得熟悉数字签名。如果所有这一切都是必要的或在目前没有友好API,这很好我很愿意接受这样一个答案。我只是想知道如果我是不必要地采取艰难的道路在这里。

有帮助吗?

解决方案

我看着所有的选项签署XML文件,并决定采用非标准的做法。这些标准都太冗长。另外,我并不需要与标准的兼容性---我的XML块上只需要签名。

大概为“登入”的XML块是使用GPG与分离的签名的最简单的方法。

其他提示

看看 Apache XML安全.使用该软件包的生成和核实签名结账的样本 src_samples/org/apache/xml/security/samples/signature/.

从Apache圣所CreateSignature例如大厦,最短的事我能想出是这样的。如果没有main()和与之配套的output(),它的20行

import java.io.*;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.io.IOUtils;
import org.apache.xml.security.Init;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.ElementProxy;
import org.w3c.dom.Document;

public class CreateSignature {

    private static final String PRIVATE_KEY_ALIAS = "test-alias";
    private static final String PRIVATE_KEY_PASS = "test";
    private static final String KEY_STORE_PASS = "test";
    private static final String KEY_STORE_TYPE = "JKS";

    public static void main(String... unused) throws Exception {
        final InputStream fileInputStream = new FileInputStream("test.xml");
        try {
            output(signFile(fileInputStream, new File("keystore.jks")), "signed-test.xml");
        }
        finally {
            IOUtils.closeQuietly(fileInputStream);
        }
    }

    public static ByteArrayOutputStream signFile(InputStream xmlFile, File privateKeyFile) throws Exception {
        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);
        Init.init();
        ElementProxy.setDefaultPrefix(Constants.SignatureSpecNS, "");
        final KeyStore keyStore = loadKeyStore(privateKeyFile);
        final XMLSignature sig = new XMLSignature(doc, null, XMLSignature.ALGO_ID_SIGNATURE_RSA);
        final Transforms transforms = new Transforms(doc);
        transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
        sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
        final Key privateKey = keyStore.getKey(PRIVATE_KEY_ALIAS, PRIVATE_KEY_PASS.toCharArray());
        final X509Certificate cert = (X509Certificate)keyStore.getCertificate(PRIVATE_KEY_ALIAS);
        sig.addKeyInfo(cert);
        sig.addKeyInfo(cert.getPublicKey());
        sig.sign(privateKey);
        doc.getDocumentElement().appendChild(sig.getElement());
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        outputStream.write(Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS).canonicalizeSubtree(doc));
        return outputStream;
    }

    private static KeyStore loadKeyStore(File privateKeyFile) throws Exception {
        final InputStream fileInputStream = new FileInputStream(privateKeyFile);
        try {
            final KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE);
            keyStore.load(fileInputStream, KEY_STORE_PASS.toCharArray());
            return keyStore;
        }
        finally {
            IOUtils.closeQuietly(fileInputStream);
        }
    }

    private static void output(ByteArrayOutputStream signedOutputStream, String fileName) throws IOException {
        final OutputStream fileOutputStream = new FileOutputStream(fileName);
        try {
            fileOutputStream.write(signedOutputStream.toByteArray());
            fileOutputStream.flush();
        }
        finally {
            IOUtils.closeQuietly(fileOutputStream);
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top