代码之家  ›  专栏  ›  技术社区  ›  user1974566

加密XML、冗余命名空间后丢失x 509证书信息

  •  1
  • user1974566  · 技术社区  · 7 年前

    我使用Java安全性和Javax XML加密进行X509证书签名。在使用XMLSignature sign之后,它运行得很好

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

    <?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>
    

    在那之后,我使用生成的密钥用3DES加密这个密钥,然后,我使用RSA 1.5和证书中的公钥加密这个密钥。 我的问题是加密后我会丢失证书信息。此外,每个标签都有

    xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
    

    名称空间添加了我不想在这里除了一个位置之外的内容->

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

    电流输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <bxd:ApplicationRequest xmlns:bxd="http://bxd.fi/xmldata/">
        <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/>
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/>
                    <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                        <xenc:CipherValue xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">ciphervalueone</xenc:CipherValue>
                    </xenc:CipherData>
                </xenc:EncryptedKey>
            </ds:KeyInfo>
            <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                <xenc:CipherValue xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">cipherval</xenc:CipherValue>
            </xenc:CipherData>
        </xenc:EncryptedData>
    </bxd:ApplicationRequest>
    

    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>
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   user1974566    7 年前

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

    问题在于在加密期间向KeyInfo添加信息。 在xml文件签名期间,正确添加了有关证书的信息。

    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);