You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Verna Knapp <ve...@navicom.com> on 2000/07/07 18:38:58 UTC

[Fwd: Cannot set up certs for trusted CAs; JCE and tomcat]

Sorry, I forgot the code to reproduce this one. 

Here it is. Instantiate it from a JSP or XML file, and then call
encrypt(byte[] b, String any).

I am also reporting this one to Sun.

Verna


-----------------------------

import javax.crypto.*;
import java.security.cert.Certificate;
import java.io.*;
import java.security.*;
import java.security.Provider;
import java.security.Security;
import com.sun.crypto.provider.SunJCE;



public class CryptoSecurity
{
   
    private final String keyStoreFileName = ".\\store\\cryptokeystore";
    private final String cryptoFileDirectory = ".\\crypto";

    private final String keyStorePassword = "cryptodemo";
    private final String keyPasswordPrefix = "hpcryptox";
    
     KeyStore keyStore = null;
     SecretKey key = null;
    /* 
    
    CryptoSecurity constructor 
       
    */
    public CryptoSecurity() 
    { 
        Security.addProvider((Provider)(new
com.sun.crypto.provider.SunJCE()));
        loadKeyStore(keyStoreFileName, keyStorePassword);
    }
    
    
    
    public byte[] encrypt(byte[] clearText, String keyAlias)
    {
        //Get a new secret key.
        SecretKey key = getKey(keyAlias);
        return encrypt(clearText, key, getCipher());
    }
    
    private SecretKey getKey(String fileName)
    {
        SecretKey key = null;
        if (keyStore == null)
        {
            keyStore = newKeyStore(keyStorePassword);
        }
        else
        {
            key = getKeyFromKeyStore(fileName, keyPasswordPrefix +
fileName, keyStore);
        }
        if (key == null)
        {
            //Get a new secret key.
            key = createNewKey();
            
            //The alias is the file name. 
            //The password is derived from the file name by prepending
it with keyPasswordPrefix.
            setKeyEntryInKeyStore(fileName, keyPasswordPrefix +
fileName, key, keyStore);
            saveKeyStore(keyStoreFileName, keyStorePassword, keyStore);
        }
        return key;
    }
    
    private void encrypt(byte[] clearText, byte[] cipherText, String
fileName)
    {
        
        //Get a new secret key.
        SecretKey key = getKey(fileName);
        cipherText = encrypt(clearText, key, getCipher());
        
    }

    /* 
        encrypts input bytes using the specified key and cipher and
returns
       the encrypted bytes
    */
    private byte[] encrypt(byte[] clearText, SecretKey key, Cipher
cipher) 
    {
        try 
        {
            cipher.init(Cipher.ENCRYPT_MODE, key); 
            byte[] cipherText = cipher.doFinal(clearText); //encrypt the
bytes
            return cipherText;
        }
        catch(InvalidKeyException e) 
        {
            e.printStackTrace();
        }
        catch(IllegalBlockSizeException e)
        {
            e.printStackTrace();
        }
        catch(BadPaddingException e)
        {
            e.printStackTrace();
        }
        return new byte[1];
    } 
   
    
    private void decrypt(byte[] clearText, byte[] cipherText, String
fileName)
    {
        //Load the keystore
        KeyStore keyStore = loadKeyStore(keyStoreFileName,
keyStorePassword);
        //Get the secret key.
        //The alias is the file name. 
        //The password is derived from the file name by prepending it
with keyPasswordPrefix.
        SecretKey key = getKeyFromKeyStore(fileName, keyPasswordPrefix +
fileName, keyStore);
        clearText = decrypt(cipherText, key, getCipher());
    }
    /* 
        decrypts input bytes using the current key and
        returns the decrypted bytes
    */
    private byte[] decrypt(byte[] cipherText, SecretKey key, Cipher
cipher) 
    { 
        try 
        {
            cipher.init(Cipher.DECRYPT_MODE, key); 
            byte[] clearText = cipher.doFinal(cipherText);
            return clearText;
        }
        catch(InvalidKeyException e) 
        {
            e.printStackTrace();
        }
        catch(IllegalBlockSizeException e)
        {
            e.printStackTrace();
        }
        catch(BadPaddingException e)
        {
            e.printStackTrace();
        }
        return new byte[1]; 
    }
    
    /* void newKeyStore(password)
       creates a new keystore protected with the password
    */
    private KeyStore newKeyStore(String password) 
    {
        KeyStore keyStore = null;
	    try 
	    {
	        keyStore = KeyStore.getInstance("JCEKS", "SunJCE");
            char passwd[] = new char[password.length()];
            password.getChars(0, password.length(), passwd, 0);
            keyStore.load(null, passwd);
	    }
	    catch (KeyStoreException e) 
	    {
            e.printStackTrace();
        }
	    catch (NoSuchProviderException e) 
	    {
            e.printStackTrace();
        }
	    catch (java.security.cert.CertificateException e) 
	    {
           e.printStackTrace();
        }
	    catch (NoSuchAlgorithmException e) 
	    {
            e.printStackTrace();
        }
	    catch (IOException e) 
	    {
            e.printStackTrace();
        }
	    return keyStore;
	}
	
	/*  void saveKeyStore(String fileName, String password)
	    saves the current keyStore to disk
	*/
	private void saveKeyStore(String fileName, String password, KeyStore
keyStore) 
	{
	    try 
	    {    
	        char passwd[] = new char[password.length()];
	        password.getChars(0, password.length(), passwd, 0);
	        FileOutputStream f = new FileOutputStream(fileName);
	        keyStore.store(f, passwd);
	    }
	    catch (FileNotFoundException e) 
	    {
	        e.printStackTrace();
	    }
	    catch (KeyStoreException e) 
	    {
            e.printStackTrace();
        }
	    catch (IOException e) 
	    {
            e.printStackTrace();
        }
	    catch (NoSuchAlgorithmException e) 
	    {
	        e.printStackTrace();
	    }
	    catch (java.security.cert.CertificateException e) 
	    {
           e.printStackTrace();
        }
	}
    
    /*  void loadKeyStore(String fileName, String password)
        load the keyStore from disk
    */
    private KeyStore loadKeyStore(String fileName, String password) 
    {
        KeyStore keyStore = null;
        try 
        {
	        char passwd[] = new char[password.length()];
	        password.getChars(0, password.length(), passwd, 0); //convert
the String password into char[]
	        
	        FileInputStream f = new FileInputStream(fileName);
	        keyStore.load(f, passwd); //load the keyStore
	    }
	    catch(FileNotFoundException e)
	    {
	        e.printStackTrace();
	    }
	    catch(IOException e)
	    {
	        e.printStackTrace();
	    }
	    catch(NoSuchAlgorithmException e)
	    {
	        e.printStackTrace();
	    }
	    catch (java.security.cert.CertificateException e) 
	    {
           e.printStackTrace();
        }
	    return keyStore;
    }
    
    /*  void setKeyEntryInKeyStore(String alias, String password)
        puts a key into the keyStore undert the alias and protected
        by the password
    */
    private void setKeyEntryInKeyStore(String alias, String password,
SecretKey key, KeyStore keyStore) 
    {
        try 
        {
            Certificate[] chain = new Certificate[1]; //certificate not
needed for storing des keys
            char passwd[] = new char[password.length()]; 
	        password.getChars(0, password.length(), passwd, 0); //convert
the String password into char[]
	        
            keyStore.setKeyEntry(alias, key, passwd, chain); //store the
key
        }
        catch (KeyStoreException e) 
        {
	        e.printStackTrace();
	    }
    }
    
    /*  void getKeyFromKeyStore(String alias, String password)
        retrieves key with alias and protected by password from
        the current keyStore
    */
    private SecretKey getKeyFromKeyStore(String alias, String password,
KeyStore keyStore) 
    {
        SecretKey key = null;
        try 
        {
            char passwd[] = new char[password.length()];
	        password.getChars(0, password.length(), passwd, 0); //convert
the String password into char[]
	        
            key = (SecretKey)(keyStore.getKey(alias, passwd));
//retrieve the key from the keyStore
        }
        catch (KeyStoreException e) 
        {
	        e.printStackTrace();
	    }
	    catch(NoSuchAlgorithmException e)
	    {
	        e.printStackTrace();
	    }
	    catch(UnrecoverableKeyException e)
	    {
	    }
	    return key; 
	    
    }
    
    /*  
    void createNewKey()
    */
    private SecretKey createNewKey() 
    {
        SecretKey key = null;
        try 
        {
            key = KeyGenerator.getInstance("DES").generateKey();
        }
	    catch(NoSuchAlgorithmException e)
	    {
	        e.printStackTrace();
	    }
        return key;
    }
    /*
    Get the cipher.
    */
    private Cipher getCipher()
    {
        try
        {
            return Cipher.getInstance("DES/ECB/PKCS5Padding");
        }
	    catch(NoSuchAlgorithmException e)
	    {
	        e.printStackTrace();
	    }
	    catch(NoSuchPaddingException e)
	    {
	        e.printStackTrace();
	    }
	    return null;
    }
} 


Verna Knapp wrote:
> 
> This is starting to look more and more like a tomcat problem.
> 
> I am able to reproduce this bug both with cocoon and without cocoon
> installed, and on more than one machine.
> 
> The environment is:
> JCE1.2.1beta
> JDK1.3
> Tomcat 3.1
> (sometimes...Cocoon 1.7.4)
> 
> Windows NT 4.0 svc pack 5
> 
> This is very similar to a bug that happens when using JDK1.2.x. Right
> now the Sun site reports that JDK1.3 must be used to avoid the problem.
> The bug itself is in the JCE. However, it should not appear if JDK1.3 is
> being used.
> 
> I don't encounter the bug when executing the same code without Tomcat,
> just using the jdk 1.3 java. This makes me wonder what tomcat is doing
> to stir it up, and whether it is the same bug as the one reported on the
> Sun site or not.
> 
> What looks like the same bug is also reported in the archives by another
> user who was using Solaris and WebLogic. In that user's case, he was
> trying to getCipher rather than generate a key. It is probably the same
> bug, though.
> 
> I compile with the JDK compiler. JDK1.2.x of any flavor is not installed
> on one of the two machines I reproduced this on.
> 
> I have a version of this that happens with XSP/XML under cocoon, and
> another that happens at the same place in a JSP. Both instantiate a
> class and call it.
> 
> Verna Knapp
> vernak@navicom.com
> Verna_Knapp@cv.hp.com
> 
>              java.lang.ExceptionInInitializerError:
> java.lang.SecurityException: Cannot set up certs for trusted CAs
>                      at javax.crypto.b.([DashoPro-V1.2-120198])
>                      at
> javax.crypto.KeyGenerator.getInstance([DashoPro-V1.2-120198])
>                      at
> CryptoSecurity.createNewKey(CryptoSecurity.java:442)
>                      at CryptoSecurity.getKey(CryptoSecurity.java:130)
>                      at CryptoSecurity.encrypt(CryptoSecurity.java:112)
>                      at
> _I_._jakarta_tomcat._webapps._encryptDecrypt._encrypt.encrypt(_encrypt.java:62)
>                      at
> _I_._jakarta_tomcat._webapps._encryptDecrypt._encrypt.populateDocument(_encrypt.java:183)
>                      at
> org.apache.cocoon.processor.xsp.XSPPage.getDocument(XSPPage.java:96)
>                      at
> org.apache.cocoon.processor.xsp.XSPProcessor.process(XSPProcessor.java:456)
>                      at org.apache.cocoon.Engine.handle(Engine.java:305)
>                      at
> org.apache.cocoon.Cocoon.service(Cocoon.java:167)
>                      at
> javax.servlet.http.HttpServlet.service(HttpServlet.java:865)
>                      at
> org.apache.tomcat.core.ServletWrapper.handleRequest(ServletWrapper.java:503)
>                      at
> org.apache.tomcat.core.ContextManager.service(ContextManager.java:559)
>                      at
> org.apache.tomcat.service.http.HttpConnectionHandler.processConnection(HttpConnectionHandler.java:160)
>                      at
> org.apache.tomcat.service.TcpConnectionThread.run(SimpleTcpEndpoint.java:338)
>                      at java.lang.Thread.run(Unknown Source)