加密后丢失 x 509 证书信息 XML,冗余命名空间
Loosing x 509 certificate info after encrypting XML, redundant namespaces
我正在使用 Java 安全和 Javax XML 加密进行 X509 证书签名。使用 XML 签名
后效果很好
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 和证书中的 public 密钥对该密钥进行加密。
我为此使用 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>
我设法正确地唱和加密 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);
我正在使用 Java 安全和 Javax XML 加密进行 X509 证书签名。使用 XML 签名
后效果很好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 和证书中的 public 密钥对该密钥进行加密。 我为此使用 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>
我设法正确地唱和加密 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);