문제

나는 노력하고있다 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 Craziness없이?

나는 암호화에 능숙하지 않으며 Java 제공 API는 디지털 서명에 익숙해 지려고하는 나와 같은 개발자에게는 다소 어려워 보입니다. 이 모든 것이 필요하거나 현재 더 친근한 API가 없다면 괜찮습니다. 나는 그것을 대답으로 받아 들일 것입니다. 나는 불필요하게 어려운 길을 가고 있는지 알고 싶습니다.

도움이 되었습니까?

해결책

XML 파일에 서명하기위한 모든 옵션을 살펴보고 비표준 접근 방식을 사용하기로 결정했습니다. 표준은 너무 장악이었다. 또한 표준과의 호환성이 필요하지 않았습니다. XML 블록에 서명이 필요했습니다.

아마도 XML 블록을 "서명"하는 가장 쉬운 방법은 분리 된 서명과 함께 GPG를 사용하는 것입니다.

다른 팁

보세요 아파치 XML 보안. 패키지를 사용하여 서명을 생성하고 확인하려면 샘플을 체크 아웃하십시오. src_samples/org/apache/xml/security/samples/signature/.

Apache Santuario에서 건물 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