I have seperate classes which encrypt and decrypt input stream which is XML 
contents.
I am testing decryption using XmlCipher.
Encryption worked OK. However, in the decryptionOnly, I am getting the 
encrypted xml contents as an input and trying to convert its contents back to 
the original XML input.  I am getting the error below

java.lang.ArrayIndexOutOfBoundsException: -1 < 0
        at java.util.Vector.elementAt(Vector.java:437)
        at org.apache.xerces.dom.DeepNodeListImpl.item(Unknown Source)
        at org.apache.xml.security.encryption.XMLCipher$Factory.newEncryptedData
(XMLCipher.java:2182)
        at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray
(XMLCipher.java:1367)
        at org.apache.xml.security.encryption.XMLCipher.decryptElement
(XMLCipher.java:1299)
        at org.apache.xml.security.encryption.XMLCipher.doFinal
(XMLCipher.java:748)
        at XmlEncryptionTester.testDecryptOnly(XmlEncryptionTester.java:659)


---------------------------------------------------
My encrypted xml contents

<?xml version="1.0" encoding="UTF-8"?>
<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"; 
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#";>ECG7APZegNRhwInDUboc3Ret/T/wcGTaN
AillgDt8pyD8VLZSDntd+7u2jNkrjsT</xenc:CipherValue>
    </xenc:CipherData>
</xenc:EncryptedData>

----------------------------------------------------
Here is my codes. 
If I used the document which parse a file when Document is created, the 
Decryption works OK. When documentbyParsingInputStream is called to get the 
Document in testDecryptionOnly method, the prefix value of the ee element
ee = (Element) ed.getElementsByTagName("xenc:EncryptedData").item(0); is null.

private Document documentbyParsingInputStream(String inputFile) {
   Document d = null;
   try {
         File f = new File(inputFile);
         FileInputStream input = new FileInputStream(f);                        
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         dbf.setValidating(true);
         dbf.setNamespaceAware(true);
        d= db.parse(input);
   } catch (Exception e) {
         e.printStackTrace();
         System.exit(-1);
   }

   return (d);
}




private Document documentbyParsingInputStream(String inputFile) {
  Document d = null;
  try {
      File f = new File(inputFile);
      FileInputStream input = new FileInputStream(f);                           
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      dbf.setValidating(true);
      dbf.setNamespaceAware(true);
      d= db.parse(input);
  } catch (Exception e) {
      e.printStackTrace();
      System.exit(-1);
  }
      return (d);
}



public void testDecryptOnly() throws Exception{
    // if I call  document method instread   
    // the documentbyParsingInputStream   method , the deryption works fine.
    Document ed = document("encrypted_TrippleDes.xml"); // source
    
   // If documentbyParsingInputStream is called, then getting the 
   // exception above
   //Document ed = documentbyParsingInputStream("e_TrippleDes.xml");// source
    Document dd = null;      // target
    Element e = ed.getDocumentElement();
    Element ee = null;
    try {
         // prepare for encryption
         byte[] passPhrase = "24 Bytes per DESede key!".getBytes();
         DESedeKeySpec keySpec = new DESedeKeySpec(passPhrase);
         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
         SecretKey key = keyFactory.generateSecret(keySpec);
        //decrypt
        cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES);
        cipher.init(XMLCipher.DECRYPT_MODE, key);
        ee = (Element) ed.getElementsByTagName("xenc:EncryptedData").item(0);
        
        System.out.println(" ee.getPrefix() :"+ee.getPrefix());
        // ee.getPrefix()  is xenc when document is called.
        // ee.getPrefix()  is null when documentbyParsingInputStream is called.

        dd = cipher.doFinal(ed, ee);
        target = toString(dd);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
      Assert.assertEquals( toString(document().getDocumentElement()), target);

   }


I need to use an input as a stream when Document is created, I can't work out 
why prefix is null  if the inputStream is passed to the parse method when 
creating the Document object. contents of the ed is same regardless of a method 
I call.  What am I doing wrong ? Any ideas will be appreciated
Thanks

hyejung



Reply via email to