Sorry, I forgot the error produced in JDK 1.5

Original Exception was java.security.InvalidKeyException: Wrong algorithm: DESede or TripleDES required
    at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.decryptElement(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source)
    at com.capeclear.pgh.stuff.SecurityKeyTests.main(SecurityKeyTests.java:98)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
java.security.InvalidKeyException: Wrong algorithm: DESede or TripleDES required
    at com.sun.crypto.provider.SunJCE_aa.a(DashoA12275)
    at com.sun.crypto.provider.SunJCE_m.a(DashoA12275)
    at com.sun.crypto.provider.SunJCE_h.a(DashoA12275)
    at com.sun.crypto.provider.DESedeCipher.engineInit(DashoA12275)
    at javax.crypto.Cipher.init(DashoA12275)
    at javax.crypto.Cipher.init(DashoA12275)
    at org.apache.xml.security.encryption.XMLCipher.decryptToByteArray(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.decryptElement(Unknown Source)
    at org.apache.xml.security.encryption.XMLCipher.doFinal(Unknown Source)
    at com.capeclear.pgh.stuff.SecurityKeyTests.main(SecurityKeyTests.java:98)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

Pete

Peter Hendry wrote:
The class attached contains test code that works Ok under JDK 1.4 but has never worked under 1.5. The scenario is where the secret key is to be included with the message and encrypted using a public key then decrypted by the recipient using their private key. When the key is decrypted an instance of SecretKeySpec is returned with its algorithm set to RSA (the original key is DESEde). This happens on both 1.4 and 1.5 but it only fails to decrypt the data in 1.5.

Any help/pointers appreciated.

Pete




package pgh; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.Security; import java.security.spec.KeySpec;

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.xml.security.encryption.EncryptedKey;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.transforms.Transforms;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


public class SecurityKeyTests {

    static {
        Security.addProvider(new BouncyCastleProvider());
        org.apache.xml.security.Init.init();
    }

    public static void main( String[] args )
        throws Exception {

        // the secret key to encrypt/decrypt our data
        final byte[] keyBytes = { (byte)0xA2, (byte) 0x15,
            (byte) 0x37, (byte) 0x07, (byte) 0xCB, (byte) 0x62, (byte) 0xC1,
            (byte) 0xD3, (byte) 0xF8, (byte) 0xF1, (byte) 0x97, (byte) 0xDF,
            (byte) 0xD0, (byte) 0x13, (byte) 0x4F, (byte) 0x79, (byte) 0x01,
            (byte) 0x67, (byte) 0x7A, (byte) 0x85, (byte) 0x94, (byte) 0x16,
            (byte) 0x31, (byte) 0x92 };

        final String dataToEncrypt = "Hello World";

        // use DESEde as the key algorithm
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESEde");
        final KeySpec spec = new DESedeKeySpec(keyBytes);
        final SecretKey secretKey = keyFactory.generateSecret(spec);

        // generate key pair for encrypting/decrypting the shared key
        final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        final KeyPair keyPair = generator.generateKeyPair();

        final Document doc = newDocument();

        // encrypt the secret key with RSA 1.5 and output the EncryptedKey
        XMLCipher cipher = XMLCipher.getInstance(XMLCipher.RSA_v1dot5);
        cipher.init(XMLCipher.WRAP_MODE, keyPair.getPublic());
        final EncryptedKey encryptedKey = cipher.encryptKey(doc, secretKey);
        final Element encKeyElement = cipher.martial(encryptedKey);

        writeNode("EncryptedKey:", encKeyElement);

        // encode some data with the secret key
        final Element element = doc.createElement("test");
        element.appendChild(doc.createTextNode(dataToEncrypt));
        doc.appendChild(element);

        cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES, Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
        cipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
        cipher.doFinal(doc, element, false);

        final Element encryptedElement = (Element)doc.getDocumentElement();
        writeNode("\nEncryptedData: ", encryptedElement);

        // get the key back from the EncryptedKey (i.e. don't use the original key)
        cipher = XMLCipher.getInstance(XMLCipher.RSA_v1dot5);
        cipher.init(XMLCipher.UNWRAP_MODE, keyPair.getPrivate());
        final SecretKey unwrappedKey = (SecretKey)cipher.decryptKey(encryptedKey, XMLCipher.RSA_v1dot5);

        if ( unwrappedKey instanceof SecretKeySpec ) {
            final SecretKeySpec sks = (SecretKeySpec)unwrappedKey;
            System.out.println("\nUnwrapped Key: algorithm=" + sks.getAlgorithm());
        }
        else {
            System.out.println("\nUnwrapped Key: " + unwrappedKey);
        }

        // and use it to decrypt the element
        cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES, Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
        cipher.init(XMLCipher.DECRYPT_MODE, unwrappedKey);

        // the error occurs here in JDK1.5 because the unwrapped key is marked as "RSA" but the
        // decryption algorithm is TripleDES?
        cipher.doFinal(doc, encryptedElement, false);

        writeNode("\nDecrypted: ", doc);
    }


    private static void writeNode( String msg, Node element )
        throws Exception {

        System.out.println(msg);
        final Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(new DOMSource(element), new StreamResult(System.out));
    }


    private static Document newDocument()
        throws Exception {

        return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    }
}
  

Reply via email to