Frage

Ich versuche zu digital ein XML-Dokument signieren Java verwenden. Ich habe eine Implementierung bekam mit einigen Referenzen Arbeits ich verschiedene Implementierungen in der javax.xml.crypto.dsig Paket.

Allerdings ist meine aktuelle Implementierung ist wie viele der Beispiele ich habe betrachtet - es ist ziemlich ausführlich und beinhaltet die Verwendung von nicht weniger als 23 verschiedenen API-Klassen aus den java.xml.crypto.dsig, javax.xml.transform und java.security Paketen, unter anderem. Es fühlt sich an wie ich Fabrik Fabrik Fabrik Land eingegeben haben, und es dauerte ich mehr Stunden, um herauszufinden, was los war.

Meine Frage ist, ist es ein einfacher Weg, dies zu tun? Wenn ich öffentliche / private Schlüsseldateien haben und ich möchte eine <Signature/> in ein XML-Dokument hinzuzufügen, gibt es eine Bibliothek aus dort, dass ich nur etwas nennen wie läßt:

OutputStream signFile(InputStream xmlFile, File privateKey)

... ohne all die XMLSignatureFactory / CanonicalizationMethod / DOMSignContext Verrücktheit?

Ich bin nicht sehr bewandert in der Kryptographie und der Java-API zur Verfügung gestellt scheint ziemlich entmutigend für Entwickler wie ich versuchen, mit digitaler Signatur vertraut zu machen. Wenn all dies ist notwendig, oder es gibt derzeit keine freundlichere API gibt, das ist in Ordnung, und ich bin bereit, das als Antwort zu akzeptieren. Ich möchte nur wissen, ob ich unnötig den harten Weg hier nehmen bin.

War es hilfreich?

Lösung

schaute ich auf alle Optionen zum Signieren von XML-Dateien und beschlossen, mit einem Nicht-Standard-Ansatz zu gehen. Die Standards waren alle viel zu ausführlich. Außerdem brauchte ich nicht die Kompatibilität mit den Standards --- ich brauchte nur Unterschriften auf einem Block von XML.

Wahrscheinlich der einfachste Weg, um „Zeichen“ ein Block von XML ist GPG mit abgetrennter Unterschrift zu verwenden.

Andere Tipps

Haben Blick auf Apache XML-Sicherheits . So verwenden Sie das Paket zu erzeugen und eine Signatur zu überprüfen, Check-out die Proben in src_samples/org/apache/xml/security/samples/signature/ .

Gebäude von der Apache Santuario CreateSignature Beispiel das kürzeste, was ich tun konnte, ist dies. Ohne die main() und den begleitenden output(), es ist 20 Zeilen

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);
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top