You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by Miroslav Nachev <mi...@space-comm.com> on 2006/09/19 12:07:21 UTC

Help: How to encrypt XML Element Data by Reference instead by Value

   Hi,

   From XML Encryption Syntax and Processing specification I see that
it is possible the data of some of element to be encrypted by
reference instead by value (CipherValue or CipherReference).
Unfortunately I can't see any example how can be done this?
   Any ideas or/and help?

   Thank you in advance.


   Best Regards,
   Miroslav Nachev



Re[2]: Help: How to encrypt XML Element Data by Reference instead by Value

Posted by Miroslav Nachev <mi...@space-comm.com>.
   Dear Sean,

   Thank you very much for the help. Now I can't decrypt the content
from XML file.
   I attach 2 files:
   1. The encrypted file "CSDoc.woe.xml"
   2. The original file "CSDoc.xml"

   The encryption steps are:
SessionKey sessionKey = getSessionKey();
dataElement.setTextContent(getCompressedCipherBase64Data(sessionKey));

Key symmetricKey = sessionKey.getSecretKeySpec();
X509Certificate cert = certHelper.getCertificate();
XMLCipher keyCipher = XMLCipher.getInstance(keyWrapAlgorithmURI);
keyCipher.init(XMLCipher.WRAP_MODE, cert.getPublicKey());
EncryptedKey encryptedKey = keyCipher.encryptKey(xmlDocument, symmetricKey);

XMLCipher cipher = XMLCipher.getInstance();
String referenceId = dataElement.getAttribute("Id");
if(referenceId == null || referenceId.trim().length() <= 0)
{
   throw new CryptXMLException("ERROR: It is not possible the encrypted XML element to be without Id.");
}

EncryptedData encryptedData = cipher.createEncryptedData(CipherData.REFERENCE_TYPE, "#" + referenceId);
EncryptionMethod em = cipher.createEncryptionMethod(algorithmURI);
encryptedData.setEncryptionMethod(em);

com.sun.org.apache.xml.internal.security.encryption.Transforms xencTransforms = cipher.createTransforms(xmlDocument);
encryptedData.getCipherData().getCipherReference().setTransforms(xencTransforms);
com.sun.org.apache.xml.internal.security.transforms.Transforms dsTransforms = xencTransforms.getDSTransforms();

XPathContainer xpc = new XPathContainer(xmlDocument);
xpc.setXPath(getXPathFromElement(dataElement));
dsTransforms.addTransform(com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_XPATH,
                          xpc.getElementPlusReturns());

// Add a Base64 Transforms
dsTransforms.addTransform(com.sun.org.apache.xml.internal.security.transforms.Transforms.TRANSFORM_BASE64_DECODE);

com.sun.org.apache.xml.internal.security.keys.KeyInfo keyInfo;
keyInfo = new com.sun.org.apache.xml.internal.security.keys.KeyInfo(xmlDocument);
keyInfo.add(encryptedKey);
com.sun.org.apache.xml.internal.security.keys.content.X509Data certData;
certData = new com.sun.org.apache.xml.internal.security.keys.content.X509Data(xmlDocument);
certData.addCertificate(cert);
keyInfo.add(certData);
encryptedData.setKeyInfo(keyInfo);

Element encryptedDataElement = cipher.martial(xmlDocument, encryptedData);
encryptBlockElement.appendChild(encryptedDataElement);


   The decryption steps are:
xmlCipher = XMLCipher.getInstance();
xmlCipher.init(XMLCipher.DECRYPT_MODE, null);
xmlCipher.setKEK(certHelper.getPrivateKey());
xmlCipher.decryptToByteArray(encryptedDataElement);


   The errors are:
2006-9-25 16:33:26 com.sun.org.apache.xml.internal.security.utils.CachedXPathFuncHereAPI fixupFunctionTable
INFO: Registering Here function
com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException: Given final block not properly padded
Original Exception was javax.crypto.BadPaddingException: Given final block not properly padded
        at com.sun.org.apache.xml.internal.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
        at com.cosmos.security.xml.XMLCipherDecoder.decryptByReference(XMLCipherDecoder.java:82)
        at com.cosmos.security.xml.test.TestXMLCipher.main(TestXMLCipher.java:109)
javax.crypto.BadPaddingException: Given final block not properly padded
        at com.sun.crypto.provider.SunJCE_h.b(DashoA6275)
        at com.sun.crypto.provider.SunJCE_h.b(DashoA6275)
        at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA6275)
        at javax.crypto.Cipher.doFinal(DashoA12275)
        at com.sun.org.apache.xml.internal.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
        at com.cosmos.security.xml.XMLCipherDecoder.decryptByReference(XMLCipherDecoder.java:82)
        at com.cosmos.security.xml.test.TestXMLCipher.main(TestXMLCipher.java:109)   


   Any ideas where is the problem?


   Best Regards,
   Miroslav Nachev

SM> Miroslav Nachev wrote:
>>    Hi,
>> 
>>    From XML Encryption Syntax and Processing specification I see that
>> it is possible the data of some of element to be encrypted by
>> reference instead by value (CipherValue or CipherReference).
>> Unfortunately I can't see any example how can be done this?
>>    Any ideas or/and help?

SM> Here is an example from one of the unit tests (XMLCipherTester):

SM> DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
SM> DocumentBuilder db = dbf.newDocumentBuilder();
SM> Document d = db.newDocument();
SM> Element docElement = d.createElement("EncryptedDoc");
SM> d.appendChild(docElement);

SM> // Create the XMLCipher object
SM> cipher = XMLCipher.getInstance();
SM> EncryptedData ed =
SM> cipher.createEncryptedData(CipherData.REFERENCE_
SM> TYPE, "#CipherTextId");
SM> EncryptionMethod em =
SM> cipher.createEncryptionMethod(XMLCipher.AES_128);
SM> ed.setEncryptionMethod(em);
SM> org.apache.xml.security.encryption.Transforms xencTransforms = 

SM>      cipher.createTransforms(d);
 
SM> ed.getCipherData().getCipherReference().setTransforms(xencTransforms);
SM> org.apache.xml.security.transforms.Transforms dsTransforms =
SM>      xencTransforms.getDSTransforms();

SM> // An XPath transform
SM> XPathContainer xpc = new XPathContainer(d);
SM> xpc.setXPath("self::text()[parent::CipherText[@Id=\"CipherTextId\"]]");
 
SM> dsTransforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_XPATH,

SM> xpc.getElementPlusReturns());

SM> // Add a Base64 Transforms
SM> dsTransforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_BASE64_DECODE);

SM> Element ee = cipher.martial(d, ed);
SM> docElement.appendChild(ee);

SM> // Add the cipher text
SM> Element encryptedElement = d.createElement("CipherText");
SM> encryptedElement.setAttributeNS(null, "Id", "CipherTextId");
SM> IdResolver.registerElementById(encryptedElement, "CipherTextId");
 
SM> encryptedElement.appendChild(d.createTextNode(tstBase64EncodedString));
SM> docElement.appendChild(encryptedElement);

SM> --Sean

Re: Help: How to encrypt XML Element Data by Reference instead by Value

Posted by Sean Mullan <Se...@Sun.COM>.
Miroslav Nachev wrote:
>    Hi,
> 
>    From XML Encryption Syntax and Processing specification I see that
> it is possible the data of some of element to be encrypted by
> reference instead by value (CipherValue or CipherReference).
> Unfortunately I can't see any example how can be done this?
>    Any ideas or/and help?

Here is an example from one of the unit tests (XMLCipherTester):

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.newDocument();
Element docElement = d.createElement("EncryptedDoc");
d.appendChild(docElement);

// Create the XMLCipher object
cipher = XMLCipher.getInstance();
EncryptedData ed = cipher.createEncryptedData(CipherData.REFERENCE_
TYPE, "#CipherTextId");
EncryptionMethod em = cipher.createEncryptionMethod(XMLCipher.AES_128);
ed.setEncryptionMethod(em);
org.apache.xml.security.encryption.Transforms xencTransforms = 

     cipher.createTransforms(d);
 
ed.getCipherData().getCipherReference().setTransforms(xencTransforms);
org.apache.xml.security.transforms.Transforms dsTransforms =
     xencTransforms.getDSTransforms();

// An XPath transform
XPathContainer xpc = new XPathContainer(d);
xpc.setXPath("self::text()[parent::CipherText[@Id=\"CipherTextId\"]]");
 
dsTransforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_XPATH, 

xpc.getElementPlusReturns());

// Add a Base64 Transforms
dsTransforms.addTransform(org.apache.xml.security.transforms.Transforms.TRANSFORM_BASE64_DECODE);

Element ee = cipher.martial(d, ed);
docElement.appendChild(ee);

// Add the cipher text
Element encryptedElement = d.createElement("CipherText");
encryptedElement.setAttributeNS(null, "Id", "CipherTextId");
IdResolver.registerElementById(encryptedElement, "CipherTextId");
 
encryptedElement.appendChild(d.createTextNode(tstBase64EncodedString));
docElement.appendChild(encryptedElement);

--Sean