2017-06-29 61 views
0

我正在使用Java安全性和Javax XML Crypto進行X509證書籤名。它的工作非常好,使用的XMLSignature標誌加密XML,冗餘名稱空間後鬆動x 509證書信息

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> 

在那之後,我使用產生的密鑰與3DES加密這一點,之後,我使用RSA 1.5和證書中的公鑰加密此密鑰。 我爲此使用Apache Santuario。 我的問題是我在加密後失去證書信息。此外,每個標籤有

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> 
+0

您的意思是簽名或加密證書嗎?你在哪裏/如何「鬆散」?它不是在XML中返回?驗證不成功?我試圖擺脫過去的虛假命名空間聲明。我不知道我到底做了什麼,但是我確實知道它有點絕望。除非你非常需要擺脫它們,否則我建議你將它們留在其中。 –

+0

我在問題中添加了預期結果。我的意思是簽署證書 - >但是RSA加密是使用從證書中提取的公鑰進行的。 「鬆動它」 - >部分「當前輸出」我提供了我在加密之後得到的當前xml - >正如您所看到的,那裏沒有關於數字簽名的任何信息。但是我在加密之前簽署這個xml - >它在第一個例子中顯示。 我很抱歉我在這件事上極度缺乏知識...... – user1974566

回答

0

我設法正確地唱歌和加密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);