1

我在使用 Apache xmlsec 库对 XML 文档进行数字签名时遇到了一些问题。基于很少的文档和网络上的一些示例,我将以下代码放在一起:

public class SOAPTester
{
private static final TransformerFactory transformerFactory = TransformerFactory.newInstance();

public static void main(String[] args)
{
    //RESOURCES
    String uuid = UUID.randomUUID().toString();
    File soapFile = null;
    File ksFile = null;
    FileInputStream fis = null;
    MessageFactory mf = null;
    SOAPMessage msg = null;
    XMLSignatureFactory sf = null;
    XMLSignature sig = null;
    X509CertificateDetails x5dts = null;

    try
    {
        //INITIALIZE THE SIGNING LIBRARY
        if(!Init.isInitialized()) Init.init();

        System.out.println("SOAPTester.main: Initialized Santuario.");

        //GET INPUT SOAP MESSAGE
        soapFile = new File("SOAPTEST.xml");
        fis = new FileInputStream(soapFile);

        //CONSTRUCT SOAP ENVELOPE
        mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
        msg = mf.createMessage(null, fis);
        IOUtils.closeQuietly(fis);

        System.out.println("SOAPTester.main: Parsed SOAPMessage from File.");

        //LOAD KEYSTORE
        ksFile = new File("xml-sign.jks");
        x5dts = Cryptographer.loadXMLSigningCertificate(ksFile);

        System.out.println("SOAPTester.main: Loaded KeyStore.");

        //VALIDATE MESSAGE
        if(msg != null)
        {
            System.out.println("SOAPTester.main: SOAPMessage Valid.");

            //INITIALIZE SIGNATURE MECHANISM
            sig = new XMLSignature(msg.getSOAPPart(), "", XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256, Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);

            //TIMESTAMP REFERENCE
            InclusiveNamespaces tsin = new InclusiveNamespaces(msg.getSOAPPart(), "wse wsa soapenv air com hdr sec req");
            Transforms tsts = new Transforms(msg.getSOAPPart());
            tsts.setSecureValidation(true);
            tsts.addTransform(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS, tsin.getElement());
            sig.addDocument("#TS-5bbb45be-0a0b-482a-8214-edf06bf70ea7", tsts, "http://www.w3.org/2001/04/xmldsig-more#sha384");

            //MANIFEST REFERENCE
            InclusiveNamespaces mhin = new InclusiveNamespaces(msg.getSOAPPart(), "wse wsa soapenv com hdr sec req");
            Transforms mhts = new Transforms(msg.getSOAPPart());
            mhts.setSecureValidation(true);
            mhts.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, mhin.getElement());
            sig.addDocument("#MH-5bbb45be-0a0b-482a-8214-edf06bf70ea7", mhts, "http://www.w3.org/2001/04/xmldsig-more#sha384");

            //BUSINESS HEADER REFERENCE
            InclusiveNamespaces bhin = new InclusiveNamespaces(msg.getSOAPPart(), "wse wsa soapenv air com sec req");
            Transforms bhts = new Transforms(msg.getSOAPPart());
            bhts.setSecureValidation(true);
            bhts.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS, bhin.getElement());
            sig.addDocument("#BH-5bbb45be-0a0b-482a-8214-edf06bf70ea7", bhts, "http://www.w3.org/2001/04/xmldsig-more#sha384");

            //TODO: SIGN MESSAGE
            sig.sign(x5dts.getPrivateKey());
            sig.addKeyInfo(x5dts.getX509Certificate());

            System.out.println("SOAPTester.main: SOAPMessage Signed.");

            XMLUtils.outputDOM(sig.getElement(), System.out);
        }else
            System.out.println("SOAPTester.main: Unable to Parse SOAP File.");
    }catch(SOAPException | IOException | XMLSecurityException | CryptographyException e)
    {
        e.printStackTrace();
    }finally
    {
        uuid = null;
        soapFile = null;
        IOUtils.closeQuietly(fis);
        fis = null;
        mf = null;
        msg = null;
    }
}

这是包含我要签名的元素的文件:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:air="urn:us:gov:treasury:irs:ext:aca:air:ty17" xmlns:com="urn:us:gov:treasury:irs:common" xmlns:hdr="urn:us:gov:treasury:irs:msg:acabusinessheader" xmlns:req="urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wse:Security>
        <wsu:Timestamp wsu:Id="TS-5bbb45be-0a0b-482a-8214-edf06bf70ea7">
            <wsu:Created>2018-03-19T19:39:10Z</wsu:Created>
            <wsu:Expires>2018-03-19T19:49:10Z</wsu:Expires>
        </wsu:Timestamp>
    </wse:Security>
    <air:ACATransmitterManifestReqDtl wsu:Id="MH-5bbb45be-0a0b-482a-8214-edf06bf70ea7">
        <air:PaymentYr>2017</air:PaymentYr>
        <air:PriorYearDataInd>0</air:PriorYearDataInd>
        <com:EIN>999999999</com:EIN>
        <air:TransmissionTypeCd>O</air:TransmissionTypeCd>
        <air:TestFileCd>T</air:TestFileCd>
        <air:TransmitterForeignEntityInd>0</air:TransmitterForeignEntityInd>
        <air:TransmitterNameGrp>
            <air:BusinessNameLine1Txt>ETC</air:BusinessNameLine1Txt>
        </air:TransmitterNameGrp>
        <air:CompanyInformationGrp>
            <air:CompanyNm>ETC</air:CompanyNm>
            <air:MailingAddressGrp>
                <air:USAddressGrp>
                    <air:AddressLine1Txt>StreetAddress</air:AddressLine1Txt>
                    <com:CityNm>San Antonio</com:CityNm>
                    <air:USStateCd>TX</air:USStateCd>
                    <com:USZIPCd>78232</com:USZIPCd>
                </air:USAddressGrp>
            </air:MailingAddressGrp>
            <air:ContactNameGrp>
                <air:PersonFirstNm>FName</air:PersonFirstNm>
                <air:PersonMiddleNm>J</air:PersonMiddleNm>
                <air:PersonLastNm>MName</air:PersonLastNm>
            </air:ContactNameGrp>
            <air:ContactPhoneNm>1202101212</air:ContactPhoneNm>
        </air:CompanyInformationGrp>
        <air:VendorInformationGrp>
            <air:VendorCd>I</air:VendorCd>
            <air:ContactNameGrp>
                <air:PersonFirstNm>FName</air:PersonFirstNm>
                <air:PersonMiddleNm>J</air:PersonMiddleNm>
                <air:PersonLastNm>LName</air:PersonLastNm>
            </air:ContactNameGrp>
            <air:ContactPhoneNm>2102101212</air:ContactPhoneNm>
        </air:VendorInformationGrp>
        <air:TotalPayeeRecordCnt>2</air:TotalPayeeRecordCnt>
        <air:TotalPayerRecordCnt>1</air:TotalPayerRecordCnt>
        <air:SoftwareId>17A0000000</air:SoftwareId>
        <air:FormTypeCd>1094/1095B</air:FormTypeCd>
        <com:BinaryFormatCd>application/xml</com:BinaryFormatCd>
        <com:ChecksumAugmentationNum>de2d47ac82b0dd09c8a7d531b93c71c2</com:ChecksumAugmentationNum>
        <com:AttachmentByteSizeNum>6346</com:AttachmentByteSizeNum>
        <air:DocumentSystemFileNm>1094B_Request_BB06G_20180319T143910629Z.xml</air:DocumentSystemFileNm>
    </air:ACATransmitterManifestReqDtl>
    <hdr:ACABusinessHeader wsu:Id="BH-5bbb45be-0a0b-482a-8214-edf06bf70ea7">
        <air:UniqueTransmissionId>5bbb45be-0a0b-482a-8214-edf06bf70ea7:SYS12:BB00X::T</air:UniqueTransmissionId>
        <com:Timestamp>2018-03-19T19:39:10Z</com:Timestamp>
    </hdr:ACABusinessHeader>
    <wsa:Action>BulkRequestTransmitterService</wsa:Action>
</soapenv:Header>
<soapenv:Body xmlns:xop="http://www.w3.org/2004/08/xop/include">
    <req:ACABulkRequestTransmitter version="1.0">
        <com:BulkExchangeFile>
            <xop:Include href="cid:1094B_Request_BB06G_20180319T143910629Z.xml" />
        </com:BulkExchangeFile>
    </req:ACABulkRequestTransmitter>
</soapenv:Body>

我们需要使用定义的 wsu:Id 值对这三个部分进行签名,但是当我调用 XMLSignature.sign 时,我得到的是:

SOAPTester.main: Initialized Santuario.
SOAPTester.main: Parsed SOAPMessage from File.
SOAPTester.main: Loaded KeyStore.
SOAPTester.main: SOAPMessage Valid.
org.apache.xml.security.signature.ReferenceNotInitializedException: 
Could not find a resolver for URI TS-5bbb45be-0a0b-482a-8214-edf06bf70ea7 and Base 
Original Exception was org.apache.xml.security.utils.resolver.ResourceResolverException: Could not find a resolver for URI TS-5bbb45be-0a0b-482a-8214-edf06bf70ea7 and Base 
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:432)
at org.apache.xml.security.signature.Reference.calculateDigest(Reference.java:717)
at org.apache.xml.security.signature.Reference.generateDigestValue(Reference.java:409)
at org.apache.xml.security.signature.Manifest.generateDigestValues(Manifest.java:205)
at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:640)
at com.etc.test.SOAPTester.main(SOAPTester.java:108)
Caused by: org.apache.xml.security.utils.resolver.ResourceResolverException: Could not find a resolver for URI TS-5bbb45be-0a0b-482a-8214-edf06bf70ea7 and Base 
at org.apache.xml.security.utils.resolver.ResourceResolver.internalGetInstance(ResourceResolver.java:113)
at org.apache.xml.security.utils.resolver.ResourceResolver.getInstance(ResourceResolver.java:169)
at org.apache.xml.security.signature.Reference.getContentsBeforeTransformation(Reference.java:425)
... 5 more

显然,我遗漏了一些关于如何告诉库需要签名的文档元素在哪里的信息,但我不知道该怎么做。我试图让一个基本的签名首先工作,但最终,这就是我们试图让它产生的:

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<ds:Signature Id="SIG-E68EBBF1696C5DD4AA143353323390579" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
        <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" />
        <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <ds:Reference URI="#TS-E68EBBF1696C5DD4AA143353323390073">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <InclusiveNamespaces PrefixList="wsse wsa soapenv urn urn1 urn2 urn3" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <ds:DigestValue>?TimestampDigestValue?</ds:DigestValue>
        </ds:Reference>
        <ds:Reference URI="#id-E68EBBF1696C5DD4AA143353323390577">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <InclusiveNamespaces PrefixList="wsa soapenv urn1 urn2 urn3" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <ds:DigestValue>?ACATransmitterManifestReqDtlDigestValue?
</ds:DigestValue>
        </ds:Reference>
        <ds:Reference URI="#id-E68EBBF1696C5DD4AA143353323390578">
            <ds:Transforms>
                <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                    <InclusiveNamespaces PrefixList="wsa soapenv urn urn1 urn3" xmlns="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transform>
            </ds:Transforms>
            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <ds:DigestValue>?ACABusinessHeaderDigestValue?</ds:DigestValue>
        </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>?SignatureValue?</ds:SignatureValue>
    <ds:KeyInfo Id="KI-E68EBBF1696C5DD4AA143353323390475">
        <wsse:SecurityTokenReference wsu:Id="STR-E68EBBF1696C5DD4AA143353323390476">
            <wsse:KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wsssoap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509- token-profile-1.0#X509v3">?CertificateValue?</wsse:KeyIdentifier>
        </wsse:SecurityTokenReference>
    </ds:KeyInfo>
</ds:Signature>
<wsu:Timestamp wsu:Id="TS-E68EBBF1696C5DD4AA143353323390073">
    <wsu:Created>2016-03-05T19:40:33.900Z</wsu:Created>
    <wsu:Expires>2016-03-05T19:50:33.900Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>

任何帮助将不胜感激。

4

0 回答 0