Java 加密XML后丢失x 509证书信息,冗余名称空间

Java 加密XML后丢失x 509证书信息,冗余名称空间,java,xml,encryption,rsa,x509certificate,Java,Xml,Encryption,Rsa,X509certificate,我正在使用Java安全性和JavaXml加密进行X509证书签名。在使用XMLSignature之后,它运行得非常好 XMLSignature signature = xmlsignaturefactory.newXMLSignature(signedinfo, keyinfo); signature.sign(domsigncontext); 我的xml文件已正确签名,格式如下: <?xml version="1.0" encoding="UTF-8"?> <bxd:Ap

我正在使用Java安全性和JavaXml加密进行X509证书签名。在使用XMLSignature之后,它运行得非常好

XMLSignature signature = xmlsignaturefactory.newXMLSignature(signedinfo, keyinfo);

signature.sign(domsigncontext);
我的xml文件已正确签名,格式如下:

<?xml version="1.0" encoding="UTF-8"?>
<bxd:ApplicationRequest xmlns:bxd="http://bxd.fi/xmldata/">
    <bxd:CustomerId>zzz</bxd:CustomerId>
    <bxd:Command>UploadFile</bxd:Command>
    <bxd:Timestamp>2011-11-17T09:30:47Z</bxd:Timestamp>
    <bxd:Environment>TEST</bxd:Environment>
    <bxd:Encryption>true</bxd:Encryption>
    <bxd:Compression>true</bxd:Compression>
    <bxd:CompressionMethod>gzip</bxd:CompressionMethod>
    <bxd:SoftwareId>CustomerSoftwareId</bxd:SoftwareId>
    <bxd:FileType>pain.001.001.02</bxd:FileType>
    <bxd:Content>testtesttest</bxd:Content>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
            <Reference URI="">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                    <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                <DigestValue>AdsaH3fjwrbbcYxX3Nv5few+eFyEuTww=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>valuehere</SignatureValue>
        <KeyInfo>
            <X509Data>
                <X509Certificate>certificatehere</X509Certificate>
                <X509IssuerSerial>
                    <X509IssuerName>CN=test,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=Unknown</X509IssuerName>
                    <X509SerialNumber>2312434323</X509SerialNumber>
                </X509IssuerSerial>
            </X509Data>
        </KeyInfo>
    </Signature>
</bxd:ApplicationRequest>
名称空间已添加,我不希望在此处添加一个位置->

<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Element">
预期结果:

<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
    <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <xenc:EncryptedKey>
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
            <dsig:KeyInfo>
                <dsig:X509Data>
                    <dsig:X509Certificate>DigitalSignatureOfCertificateHere</dsig:X509Certificate>
                </dsig:X509Data>
            </dsig:KeyInfo>
            <xenc:CipherData>
                <xenc:CipherValue>CipherValueofEncryptedKeyHere</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedKey>
    </dsig:KeyInfo>
    <xenc:CipherData>
        <xenc:CipherValue>CipherValueOfProvidedXMLHere</xenc:CipherValue>
    </xenc:CipherData>
</xenc:EncryptedData>

数字签名证书在此
此处加密密钥的密码值
此处提供的CipherValueOfXmlhere

我设法正确地唱出并加密xml文件。答案供将来参考

问题在于在加密期间向KeyInfo添加信息。 在xml文件签名期间,已正确添加有关证书的信息。 但在加密过程中,这些信息也被加密了。解决方案是将证书数据再次添加到KeyInfo

EncryptedData encryptedDataElement =
        xmlCipher.getEncryptedData();
KeyInfo keyInfo = new KeyInfo(document);
X509Data x509data = new org.apache.xml.security.keys.content.X509Data(document);
x509data.addCertificate(cert);
keyInfo.add(x509data);
keyInfo.add(encKey);

encryptedDataElement.setKeyInfo(keyInfo);

// do the actual encryption
xmlCipher.doFinal(document,
        rootElement, true);

您是指用于签名还是加密的证书?在哪里/如何“松开”?它不是以XML格式返回的吗?验证没有成功吗?我过去也曾尝试过消除虚假的名称空间声明。我不知道我最后做了什么,但我知道这有点绝望。我建议你把它们留在家里,除非你有非常强烈的摆脱它们的需要。我在这个问题上补充了预期的结果。我的意思是用于签名的证书->但RSA加密是使用我从证书中提取的公钥进行的。“松开它”->在“当前输出”的一部分中,我提供了加密后得到的当前xml->正如您所看到的,这里没有任何关于数字签名的信息。但我在加密之前对这个xml签名->第一个示例中显示了它。很抱歉我对这件事一无所知。。。
public class Encryption
{
    static
    {
        org.apache.xml.security.Init.init();
    }

public static EncryptedKey encryptKey(Document document, SecretKey keyToBeEncrypted, PublicKey keyUsedToEncryptSecretKey) throws org.apache.xml.security.encryption.XMLEncryptionException {
    XMLCipher keyCipher = null;
    String pubKeyAlg = keyUsedToEncryptSecretKey.getAlgorithm();

    try {
        String keyWrapAlgo = XMLCipher.RSA_v1dot5;
        keyCipher = XMLCipher.getInstance(keyWrapAlgo);

        keyCipher.init(XMLCipher.WRAP_MODE, keyUsedToEncryptSecretKey);
        //return keyCipher.encryptKey(document, keyToBeEncrypted);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return keyCipher.encryptKey(document, keyToBeEncrypted);
}

private static SecretKey GenerateSymmetricKey()
        throws Exception
{
    String jceAlgorithmName = "DESede";
    KeyGenerator keyGenerator =
            KeyGenerator.getInstance(jceAlgorithmName);
    return keyGenerator.generateKey();
}

public static Document EncryptDocument(Document document, String elementToEncode, KeyPair pair)
        throws Exception
{
    // generate symmetric key
    SecretKey symmetricKey = GenerateSymmetricKey();

    EncryptedKey encKey = encryptKey(document,symmetricKey, pair.getPublic());

    Element rootElement = document.getDocumentElement();
    Element elementToEncrypt = rootElement;

    XMLCipher xmlCipher =
            XMLCipher.getInstance(XMLCipher.TRIPLEDES);
    xmlCipher.init(XMLCipher.ENCRYPT_MODE, symmetricKey);

    // add key info to encrypted data element
    EncryptedData encryptedDataElement =
            xmlCipher.getEncryptedData();
    KeyInfo keyInfo = new KeyInfo(document);
    keyInfo.add(encKey);
    encryptedDataElement.setKeyInfo(keyInfo);

    // do the actual encryption
    //boolean encryptContentsOnly = false;
    xmlCipher.doFinal(document,
            elementToEncrypt, true);

    // write the results to a file
    return document;
}
}
<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
    <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        <xenc:EncryptedKey>
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
            <dsig:KeyInfo>
                <dsig:X509Data>
                    <dsig:X509Certificate>DigitalSignatureOfCertificateHere</dsig:X509Certificate>
                </dsig:X509Data>
            </dsig:KeyInfo>
            <xenc:CipherData>
                <xenc:CipherValue>CipherValueofEncryptedKeyHere</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedKey>
    </dsig:KeyInfo>
    <xenc:CipherData>
        <xenc:CipherValue>CipherValueOfProvidedXMLHere</xenc:CipherValue>
    </xenc:CipherData>
</xenc:EncryptedData>
EncryptedData encryptedDataElement =
        xmlCipher.getEncryptedData();
KeyInfo keyInfo = new KeyInfo(document);
X509Data x509data = new org.apache.xml.security.keys.content.X509Data(document);
x509data.addCertificate(cert);
keyInfo.add(x509data);
keyInfo.add(encKey);

encryptedDataElement.setKeyInfo(keyInfo);

// do the actual encryption
xmlCipher.doFinal(document,
        rootElement, true);