You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by Dave Oxley <da...@daveoxley.co.uk> on 2006/05/31 05:32:30 UTC

Help with X.509 public key decryption of XML

Hi,

I'm using the sample Encrypter.java and Decrypter.java as provided in
the xml-security dist as a base to create a program to encrypt and
decrypt an xml file using openssl created private key and X.509
certificate respectively. I'm fairly new to encryption so I'm fairly
sure I'm doing something wrong. But I think I at least have the theory
right: Data encrypted with the private key can be decrypted with the
public key of the certificate and vice-versa. When I attempt to do this
I get the following error:
org.apache.xml.security.encryption.XMLEncryptionException: No Key
Encryption Key loaded and cannot determine using key resolvers
        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 testapp.Main.main(Main.java:118)
I have supplied my code at the end of the email. Could someone please
take a quick look and tell me what I'm doing wrong?

Cheers,
Dave
* *
Here is the code:
    public static void main(String[] args)
    {
        try
        {
            Security.addProvider(new BouncyCastleProvider());
            org.apache.xml.security.Init.init();

            Document import_doc = loadDocument();

            Key symmetric_key = generateDataEncryptionKey();

            Key private_key = loadPrivateKey();

            X509Certificate cert = loadCertificate();

            String algorithmURI = XMLCipher.TRIPLEDES_KeyWrap;

            XMLCipher keyCipher =
                XMLCipher.getInstance(algorithmURI);
            keyCipher.init(XMLCipher.WRAP_MODE, private_key);
            EncryptedKey encryptedKey =
                keyCipher.encryptKey(import_doc, symmetric_key);

            algorithmURI = XMLCipher.AES_128;

            XMLCipher xmlCipher =
                XMLCipher.getInstance(algorithmURI);
            xmlCipher.init(XMLCipher.ENCRYPT_MODE, symmetric_key);

            /*
             * Setting keyinfo inside the encrypted data being prepared.
             */
            EncryptedData encryptedData = xmlCipher.getEncryptedData();
            KeyInfo keyInfo = new KeyInfo(import_doc);
            keyInfo.add(encryptedKey);
            encryptedData.setKeyInfo(keyInfo);

            Element rootElement = import_doc.getDocumentElement();
            xmlCipher.doFinal(import_doc, rootElement, true);
            //xmlCipher.doFinal(import_doc, import_doc);

            outputDocToFile(import_doc, "encryptedInfo.xml");



            Element encryptedDataElement =
                (Element) import_doc.getElementsByTagNameNS(
                    EncryptionConstants.EncryptionSpecNS,
                    EncryptionConstants._TAG_ENCRYPTEDDATA).item(0);

            XMLCipher xmlCipher2 =
                XMLCipher.getInstance();
            /*
             * The key to be used for decrypting xml data would be obtained
             * from the keyinfo of the EncrypteData using the kek.
             */
            xmlCipher2.init(XMLCipher.DECRYPT_MODE, null);
            xmlCipher2.setKEK(cert.getPublicKey());
            /*
             * The following doFinal call replaces the encrypted data with
             * decrypted contents in the document.
             */
            xmlCipher2.doFinal(import_doc, encryptedDataElement);

            outputDocToFile(import_doc, "decryptedInfo.xml");
        }
        catch (Exception e)
        {
            StringWriter sw = new StringWriter();
            PrintWriter pr = new PrintWriter(sw);
            e.printStackTrace(pr);
            System.out.println(sw.toString());
        }
    }

    private static Document loadDocument() throws Exception
    {
        String file_name = "employee_import.xml";
        File import_file = new File(file_name);
        javax.xml.parsers.DocumentBuilderFactory dbf =
            javax.xml.parsers.DocumentBuilderFactory.newInstance();
        javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.parse(import_file);
        System.out.println(
            "Document loaded from " +
            import_file.toURI().toURL().toString());
        return document;
    }

    private static SecretKey generateDataEncryptionKey() throws Exception {

        String jceAlgorithmName = "AES";
        KeyGenerator keyGenerator =
            KeyGenerator.getInstance(jceAlgorithmName);
        keyGenerator.init(128);
        return keyGenerator.generateKey();
    }

    private static SecretKey loadPrivateKey() throws Exception
    {
        String key_file_name = "certs/javaapp_key.pem";
        String jceAlgorithmName = "DESede";

        File key_file = new File(key_file_name);

        DESedeKeySpec key_spec =
            new DESedeKeySpec(JavaUtils.getBytesFromFile(key_file_name));

        SecretKeyFactory skf =
             SecretKeyFactory.getInstance(jceAlgorithmName);
        SecretKey key = skf.generateSecret(key_spec);

        System.out.println(
            "Key encryption key loaded from " +
key_file.toURI().toURL().toString());

        return key;
    }

    private static X509Certificate loadCertificate() throws Exception
    {
        String cert_file_name = "certs/javaapp_cert2.pem";

        File cert_file = new File(cert_file_name);

        CertificateFactory  cf = CertificateFactory.getInstance("X.509");

        X509Certificate cert = (X509Certificate)
cf.generateCertificate(new
ByteArrayInputStream(JavaUtils.getBytesFromFile(cert_file_name)));

        System.out.println(
            "Certificate loaded from " +
cert_file.toURI().toURL().toString());

        return cert;
    }

    private static void outputDocToFile(Document doc, String fileName)
        throws Exception {
        File encryptionFile = new File(fileName);
        FileOutputStream f = new FileOutputStream(encryptionFile);

        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(f);
        transformer.transform(source, result);

        f.close();
        System.out.println(
            "Wrote document containing encrypted data to " +
            encryptionFile.toURI().toURL().toString());
    }


Unsubscribed

Posted by ga...@cmcltd.com.
> I have been doing an awful lot of reading and experimenting and still
> have problems. I am now trying to sign an xml document with an RSA key.
> The key's generated like this:
>         KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
>         keyGen.initialize(2048, sr);
>         KeyPair keypair = keyGen.generateKeyPair();
>         PrivateKey privKey = keypair.getPrivate();
>
> And when I call:
>          sig.sign(privKey);
>
> I get this exception:
> org.apache.xml.security.signature.XMLSignatureException: No installed
> provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
> Original Exception was
> org.apache.xml.security.signature.XMLSignatureException: No installed
> provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
> Original Exception was java.security.InvalidKeyException: No installed
> provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
>         at org.apache.xml.security.signature.XMLSignature.sign(Unknown
> Source)
>
> or this exception with BC:
> org.apache.xml.security.signature.XMLSignatureException: No installed
> provider supports this key:
> org.bouncycastle.jce.provider.JCERSAPrivateCrtKey
> Original Exception was
> org.apache.xml.security.signature.XMLSignatureException: No installed
> provider supports this key:
> org.bouncycastle.jce.provider.JCERSAPrivateCrtKey
> Original Exception was java.security.InvalidKeyException: No installed
> provider supports this key:
> org.bouncycastle.jce.provider.JCERSAPrivateCrtKey
>         at org.apache.xml.security.signature.XMLSignature.sign(Unknown
> Source)
>
> What am I doing wrong? This is driving me nuts, I've been working on
> this 4 days straight now.
>
> Cheers,
> Dave.
>
>




Re: Help with X.509 public key decryption of XML

Posted by Dave Oxley <da...@daveoxley.co.uk>.
I have been doing an awful lot of reading and experimenting and still
have problems. I am now trying to sign an xml document with an RSA key.
The key's generated like this:
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048, sr);
        KeyPair keypair = keyGen.generateKeyPair();
        PrivateKey privKey = keypair.getPrivate();

And when I call:
         sig.sign(privKey);

I get this exception:
org.apache.xml.security.signature.XMLSignatureException: No installed
provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
Original Exception was
org.apache.xml.security.signature.XMLSignatureException: No installed
provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
Original Exception was java.security.InvalidKeyException: No installed
provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
        at org.apache.xml.security.signature.XMLSignature.sign(Unknown
Source)

or this exception with BC:
org.apache.xml.security.signature.XMLSignatureException: No installed
provider supports this key:
org.bouncycastle.jce.provider.JCERSAPrivateCrtKey
Original Exception was
org.apache.xml.security.signature.XMLSignatureException: No installed
provider supports this key:
org.bouncycastle.jce.provider.JCERSAPrivateCrtKey
Original Exception was java.security.InvalidKeyException: No installed
provider supports this key:
org.bouncycastle.jce.provider.JCERSAPrivateCrtKey
        at org.apache.xml.security.signature.XMLSignature.sign(Unknown
Source)

What am I doing wrong? This is driving me nuts, I've been working on
this 4 days straight now.

Cheers,
Dave.