39

I've been trying to get some working Java code to use for encrypting Paypal buttons. This is no easy task! Even when I get some code, from Paypal, I'm faced with errors..ugh..

So here is what I have so far, that I think will work eventually.

I downloaded the Java.zip file from Paypal's website. Within it are two classes - ClientSide.java and ButtonEncryption.java

The Problem - I'm getting an InvalidKeyException : Illegal key size error.

Questions
1) How do I resolve this issue? 2) What line of code is throwing the error?

C:\jakarta-tomcat\webapps\PlanB\WEB-INF\classes>java palmb.servlets.paypal.ButtonEncryption
java.io.IOException: exception decrypting data - java.security.InvalidKeyException: Illegal key size
        at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.cryptData(Unknown Source)
        at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
        at java.security.KeyStore.load(Unknown Source)
        at palmb.servlets.paypal.ClientSide.getButtonEncryptionValue(ClientSide.java:63)
        at palmb.servlets.paypal.ButtonEncryption.main(ButtonEncryption.java:81)


ClientSide class

package palmb.servlets.paypal;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;

import org.bouncycastle.cms.CMSEnvelopedData;
import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.util.encoders.Base64;

/**
 */
public class ClientSide 
{
    private String  keyPath;
    private String  certPath;
    private String  paypalCertPath;
    private String  keyPass;

    public ClientSide( String keyPath, String certPath, String paypalCertPath, String keyPass )
    {
        this.keyPath = keyPath;
        this.certPath = certPath;
        this.paypalCertPath = paypalCertPath;
        this.keyPass = keyPass;
    }   

    public String getButtonEncryptionValue(String _data, String _privateKeyPath, String _certPath, String _payPalCertPath,
                                            String _keyPass) throws IOException,CertificateException,KeyStoreException,
                                            UnrecoverableKeyException,InvalidAlgorithmParameterException,NoSuchAlgorithmException,
                                            NoSuchProviderException,CertStoreException,CMSException {
        _data = _data.replace(',', '\n');
        CertificateFactory cf = CertificateFactory.getInstance("X509", "BC");

        // Read the Private Key
        KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
        ks.load( new FileInputStream(_privateKeyPath), _keyPass.toCharArray() );

        String keyAlias = null;
        Enumeration aliases = ks.aliases();
        while (aliases.hasMoreElements()) {
            keyAlias = (String) aliases.nextElement();
        }

        PrivateKey privateKey = (PrivateKey) ks.getKey( keyAlias, _keyPass.toCharArray() );

        // Read the Certificate
        X509Certificate certificate = (X509Certificate) cf.generateCertificate( new FileInputStream(_certPath) );

        // Read the PayPal Cert
        X509Certificate payPalCert = (X509Certificate) cf.generateCertificate( new FileInputStream(_payPalCertPath) );

        // Create the Data
        byte[] data = _data.getBytes();

        // Sign the Data with my signing only key pair
        CMSSignedDataGenerator signedGenerator = new CMSSignedDataGenerator();

        signedGenerator.addSigner( privateKey, certificate, CMSSignedDataGenerator.DIGEST_SHA1 );

        ArrayList certList = new ArrayList();
        certList.add(certificate);
        CertStore certStore = CertStore.getInstance( "Collection", new CollectionCertStoreParameters(certList) );
        signedGenerator.addCertificatesAndCRLs(certStore);

        CMSProcessableByteArray cmsByteArray = new CMSProcessableByteArray(data);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        cmsByteArray.write(baos);
        System.out.println( "CMSProcessableByteArray contains [" + baos.toString() + "]" );

        CMSSignedData signedData = signedGenerator.generate(cmsByteArray, true, "BC");

        byte[] signed = signedData.getEncoded();

        CMSEnvelopedDataGenerator envGenerator = new CMSEnvelopedDataGenerator();
        envGenerator.addKeyTransRecipient(payPalCert);
        CMSEnvelopedData envData = envGenerator.generate( new CMSProcessableByteArray(signed),
                CMSEnvelopedDataGenerator.DES_EDE3_CBC, "BC" );

        byte[] pkcs7Bytes = envData.getEncoded();


        return new String( DERtoPEM(pkcs7Bytes, "PKCS7") );

    }

    public static byte[] DERtoPEM(byte[] bytes, String headfoot) 
    {
        ByteArrayOutputStream pemStream = new ByteArrayOutputStream();
        PrintWriter writer = new PrintWriter(pemStream);

        byte[] stringBytes = Base64.encode(bytes);

        System.out.println("Converting " + stringBytes.length + " bytes");

        String encoded = new String(stringBytes);

        if (headfoot != null) {
            writer.print("-----BEGIN " + headfoot + "-----\n");
        }

        // write 64 chars per line till done
        int i = 0;
        while ((i + 1) * 64 < encoded.length()) {
            writer.print(encoded.substring(i * 64, (i + 1) * 64));
            writer.print("\n");
            i++;
        }
        if (encoded.length() % 64 != 0) {
            writer.print(encoded.substring(i * 64)); // write remainder
            writer.print("\n");
        }
        if (headfoot != null) {
            writer.print("-----END " + headfoot + "-----\n");
        }
        writer.flush();
        return pemStream.toByteArray();
    }

}


ButtonEncryption class

package palmb.servlets.paypal;

//import com.paypal.crypto.sample.*;

import palmb.servlets.paypal.ClientSide;

import java.io.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertStoreException;
import java.security.cert.CertificateException;
import org.bouncycastle.cms.CMSException;

/**
 */
public class ButtonEncryption {


    //path to public cert
    private static String certPath = "C:/jakarta-tomcat/webapps/PlanB/Certs/public-cert.pem";

    //path to private key in PKCS12 format
    private static String keyPath = "C:/jakarta-tomcat/webapps/PlanB/Certs/my_pkcs12.p12";

    //path to Paypal's public cert
    private static String paypalCertPath = "C:/jakarta-tomcat/webapps/PlanB/Certs/paypal_cert_pem.txt";

    //private key password
    private static String keyPass = "password"; //will be replaced with actual password when compiled and executed

    //the button command, properties/parameters
    private static String cmdText = "cmd=_xclick\nbusiness=buyer@hotmail.com\nitem_name=vase\nitemprice=25.00";  //cmd=_xclick,business=sample@paypal.com,amount=1.00,currency_code=USD

    //output file for form code
    private static String output = "test.html";


    public static void main(String[] args) 
    {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 


        String stage = "sandbox";

        try 
        {
            ClientSide client_side = new ClientSide( keyPath, certPath, paypalCertPath, keyPass );

            String result = client_side.getButtonEncryptionValue( cmdText, keyPath, certPath, paypalCertPath, keyPass );

            File outputFile = new File( output );
            if ( outputFile.exists() )
                outputFile.delete();

            if ( result != null && result != "")
            {
                try {        
                    OutputStream fout= new FileOutputStream( output );
                    OutputStream bout= new BufferedOutputStream(fout);
                    OutputStreamWriter out = new OutputStreamWriter(bout, "US-ASCII");

                    out.write( "<form action=\"https://www." );
                    out.write( stage );
                    out.write( "paypal.com/cgi-bin/webscr\" method=\"post\">" );  
                    out.write( "<input type=\"hidden\" name=\"cmd\" value=\"_s-xclick\">" );  ;
                    out.write( "<input type=\"image\" src=\"https://www." );
                    out.write( stage );
                    out.write( "paypal.com/en_US/i/btn/x-click-but23.gif\" border=\"0\" name=\"submit\" " );
                    out.write( "alt=\"Make payments with PayPal - it's fast, free and secure!\">" );
                    out.write( "<input type=\"hidden\" name=\"encrypted\" value=\"" );
                    out.write( result );
                    out.write( "\">" );
                    out.write( "</form>");

                    out.flush();  // Don't forget to flush!
                    out.close();
                  }
                  catch (UnsupportedEncodingException e) {
                    System.out.println(
                     "This VM does not support the ASCII character set."
                    );
                  }
                  catch (IOException e) {
                    System.out.println(e.getMessage());        
                  }
            }
        } 
        catch (NoSuchAlgorithmException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (NoSuchProviderException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (CMSException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (CertificateException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (KeyStoreException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (UnrecoverableKeyException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (InvalidAlgorithmParameterException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
        catch (CertStoreException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


Edited : info about keys/certificates

I generated the Private Key and Public Certificate with OpenSSL via the following commands.
Private Key
openssl genrsa -out private-key.pem 1024
Public Certificate
openssl req -new -key private-key.pem -x509 -days 1095 -out public-cert.pem
Created PKCS12 File
openssl pkcs12 -export -in public-cert.pem -inkey private-key.pem -out my_pkcs12.p12


Additionally, I had to download the Paypal Public Certificate from the Paypal website.


Edited - adding compilation warnings - BouncyCastle

C:\jakarta-tomcat\webapps\PlanB\WEB-INF\classes>javac .\palmb\servlets\paypal\ClientSide.java -Xlint
.\palmb\servlets\paypal\ClientSide.java:85: warning: [deprecation] addSigner(java.security.PrivateKey,java.security.cert.X509Certificate,java.lang.String) in org.bouncycastle.cms.CMSSignedDataGenerator has been deprecated
                signedGenerator.addSigner( privateKey, certificate, CMSSignedDat
aGenerator.DIGEST_SHA1 );
                               ^
.\palmb\servlets\paypal\ClientSide.java:88: warning: [unchecked] unchecked call
to add(E) as a member of the raw type java.util.ArrayList
                certList.add(certificate);
                            ^
.\palmb\servlets\paypal\ClientSide.java:90: warning: [deprecation] addCertificatesAndCRLs(java.security.cert.CertStore) in org.bouncycastle.cms.CMSSignedGenerat
or has been deprecated
                signedGenerator.addCertificatesAndCRLs(certStore);
                               ^
.\palmb\servlets\paypal\ClientSide.java:97: warning: [deprecation] generate(org.
bouncycastle.cms.CMSProcessable,boolean,java.lang.String) in org.bouncycastle.cm
s.CMSSignedDataGenerator has been deprecated
                CMSSignedData signedData = signedGenerator.generate(cmsByteArray, true, "BC");
                                                          ^
.\palmb\servlets\paypal\ClientSide.java:102: warning: [deprecation] addKeyTransR
ecipient(java.security.cert.X509Certificate) in org.bouncycastle.cms.CMSEnvelope
dGenerator has been deprecated
                envGenerator.addKeyTransRecipient(payPalCert);
                            ^
.\palmb\servlets\paypal\ClientSide.java:103: warning: [deprecation] generate(org.bouncycastle.cms.CMSProcessable,java.lang.String,java.lang.String) in org.bouncycastle.cms.CMSEnvelopedDataGenerator has been deprecated
                CMSEnvelopedData envData = envGenerator.generate( new CMSProcess
ableByteArray(signed),
                                                       ^
6 warnings


JCE policy file installation steps

These are the steps I took to installing the JCE Unlimited Strength Policy files:
1) Went to Java JCE Download Page on Oracle.
2) Extracted files from zip.
3) Placed local_policy.jar and US_export_policy.jar files in C:\Java\jdk1.6.0_22\jre\lib\security folder.
Note: C:\Java\jdk1.6.0_22 is set as %JAVA_HOME%
4) Updated system classpath to include location of jars.
Note: There are other files, that came with the JDK 1.6 within the security folder, including : java.policy, java.security, javaws.policy, trusted.libraries - but those probably have nothing to do with the JCE files, right?


Edit 6/23/2011 - results after further configuration

I went to Bouncy Castle page at http://www.bouncycastle.org/specifications.html#install
Scroll down to 5.0 Bouncy Castle Provider then read info under 5.1 Example. It makes mention of adding a parameter for the Bouncy Castle Provider to the java.security file. My file is under C:\Java\jdk1.6.0_22\jre\lib\security.

I added the following line to my file - security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

In addition, I discovered that I hadn't added the Bouncy Castle jars to the classpath, so I went ahead and did so.

Now after making these changes, recompiling and attempting to execute ClientSide.java I'm given the same exception : but maybe the focus should be on the part of the exception where it says this about bouncycastle provider -

at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.cryptData(Unknown Source)
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)

@PeteyB - I'm certain that I installed the policy files correctly. Based on what I've stated here, is there anything else you can suggest I try? Can you look at the Bouncy Castle site @ http://www.bouncycastle.org/specifications.html#install and see if there is something I'm missing?

katura
  • 2,177
  • 14
  • 39
  • 48
  • Would this exception have anything to do with Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files? I downloaded the ones for Java version 1.6 - and put the jars into <%JAVA_HOME%>\jre\lib\security folder on my pc. – katura Jun 15 '11 at 20:32
  • Is your company called "Plan B"? I wanted to choose that name as well, until I saw it was already used. – Martijn Courteaux Jun 15 '11 at 21:00
  • @katura - "Would this exception have anything to do with Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files?" Yes, it has a quite a lot to do with that. Has it resolved your problem though? – Vineet Reynolds Jun 15 '11 at 21:08
  • @Vineet Reynolds - I already had the policy files/jars put into the 'security' folder when I compiled and got the InvalidKeyException : Illegal key size error. What can I do as of now? Does my classpath have to be updated with the path to the security folder? – katura Jun 16 '11 at 13:28
  • @katura, no, it doesn't need to be done; it is already in the classpath. We need more info - the type of entries in the keystore, and the type & size of the keys used in the certificates. – Vineet Reynolds Jun 16 '11 at 15:43
  • @Vineet Reynolds - ok, just so I'm sure I understand you correctly, do you need information about the certificates I generated with OpenSSL? If so, I want to be sure I post the correct info, can you guide me as to what I should be looking for? – katura Jun 16 '11 at 16:37
  • Yes, that would the info. We need the info to reproduce the conditions responsible for the exception. Don't forget to anonymize any details that are not meant to be posted here. – Vineet Reynolds Jun 16 '11 at 16:44
  • I appended info for how I created the certificates and keys. Mind you I got that info from a book that showed me the commands to enter into the OpenSSL dos-prompt. I can't post the keys themselves...what other information should I be providing? I'm a bit lost - I don't know much about keys and certs. – katura Jun 16 '11 at 20:03
  • @Vineet - one other thing I should mention, which could very well be related to the problem I'm having, is that the ClientSide.java class is using deprecated methods from BouncyCastle. While it does compile, I recompiled with -Xlint, and it showed the warnings. Will post those to my original question now. – katura Jun 17 '11 at 12:50
  • @Vineet - I am using a 1024 bit RSA private key for the private-key.pem file. – katura Jun 17 '11 at 13:39
  • @katura, I'll need some time to check the info you've provided. I need to create certs of my own and see the behavior. Which version of BouncyCastle are you using? – Vineet Reynolds Jun 17 '11 at 13:49
  • @Vineet - I'm using version 1.6. I have the following Bouncy Castle jars - bcmail-jdk16-146.jar, bcpg-jdk16-146.jar, bcprov-jdk16-146.jar and bctest-jdk16-146.jar. As for OpenSSL- I downloaded it from http://www.slproweb.com/download/Win32OpenSSL_Light-1_0_0d.exe (http://www.slproweb.com/products/Win32OpenSSL.html). Thank you for looking into this for me, I greatly appreciate it. – katura Jun 17 '11 at 14:07
  • @Vineet - have you been able to replicate my problem? – katura Jun 21 '11 at 13:51
  • Nope, I'll look into it. I thought Petey made some progress. – Vineet Reynolds Jun 21 '11 at 13:55
  • @Vineet - I wish it was as simple as those policy files, but I followed the instructions for installation, so I don't know why this isn't working. Thank you for continuing to look into it for me - I'll check back often for updates. – katura Jun 22 '11 at 15:42
  • @katura - Same problem for me.. Can you please tell me how did you solve the problem finally.. – deadend Aug 07 '18 at 07:27

5 Answers5

77

So the problem must be with your JCE Unlimited Strength installation.

Be sure you overwrite the local_policy.jar and US_export_policy.jar in both your JDK's jdk1.6.0_25\jre\lib\security\ and in your JRE's lib\security\ folder.

In my case I would place the new .jars in:

C:\Program Files\Java\jdk1.6.0_25\jre\lib\security

and

C:\Program Files\Java\jre6\lib\security


If you are running Java 8 and you encounter this issue. Below steps should help!

Go to your JRE installation (e.g - jre1.8.0_181\lib\security\policy\unlimited) copy local_policy.jar and replace it with 'local_policy.jar' in your JDK installation directory (e.g - jdk1.8.0_141\jre\lib\security).

Humble Bee
  • 1,130
  • 2
  • 12
  • 19
Petey B
  • 11,439
  • 25
  • 81
  • 101
  • I removed the policy files in the C:\Java\jdk1.6.0_22\jre\lib\security folder, put the new files in and also placed both files in the C:\Java\jre6\lib\security folder per your instructions - unfortunately, the exception is still coming up:( Could this have anything to do with the Bouncy Castle jars? – katura Jun 17 '11 at 21:08
  • @Petey - Is there anything else I can do? – katura Jun 21 '11 at 13:51
  • @katura, Is the exception still happening when you run the AES code with a 256 bit key? – Petey B Jun 21 '11 at 14:29
  • 1
    @Petey - I ran the AES code with 128, which worked. But 192 and 256 threw the exception : InvalidKeyException - Illegal key size or default parameters – katura Jun 22 '11 at 15:45
  • @katura, you still havn't properly installed the Unlimited Strength policies mate. – Petey B Jun 22 '11 at 16:09
  • @Petey - aside from the instructions I followed to the "T" - what am I doing wrong? – katura Jun 22 '11 at 18:30
  • @katura, it sounds to me like you are doing it properly, but you must be missing something because it is still reading the old policies. – Petey B Jun 23 '11 at 02:12
  • @Petey - bummer. I will try a few other things with the installation of the policy files - I really want this to work. Will update results soon. – katura Jun 23 '11 at 14:55
  • @Petey - please review my results after further configuration - I edited my original question/post and appended the results to the bottom of the post. – katura Jun 23 '11 at 15:56
  • 2
    This is absolutely because of the policy files without any doubt. I spent at least 5 hours on this exact problem. – Hut8 Jun 23 '11 at 17:04
  • @Petey B - The answer to this problem I'm having has likely to do with the JCE policy files - I want to thank you for all the effort you put in to trying to help me out with this all - thank you:) In the end, I can't get it to work, wish I could though! So, I've decided to use the Paypal NVP API for creating buttons. It allows me to encrypt buttons with dynamically generated values. My first test servlet worked, and now I'm, finally, one happy programmer. Thanks again Petey B. I'm markign your answer as correct, its got to be! – katura Jun 23 '11 at 19:32
  • @katura, no problem, happy to help. You should try doing this on a different, fresh, machine and see if you can get it working. – Petey B Jun 23 '11 at 19:59
  • 1
    Very important the part "and in your JRE's lib\security\ folder." This helped me. Cheers. – vantesllar Apr 01 '15 at 11:11
  • now i get: Caused by: java.lang.SecurityException: The jurisdiction policy files are not signed by a trusted signer! – Alfredo M Mar 22 '16 at 19:37
  • I am experiencing this problem on my Ubuntu 14.04, replaced 2 files in my java_home/jre/lib/security. reboot my machine, still get illegal key size exception. spent hours on this, still not working – Maxi Wu Jan 24 '17 at 03:32
7

If you are still recieving the InvalidKeyException when running my AES encryption program with 256 bit keys, but not with 128 bit keys, it is because you have not installed the new policy JAR files correctly, and has nothing to do with BouncyCastle (which is also restrained by those policy files). Try uninstalling, then re-installing java and then replaceing the old jar's with the new unlimited strength ones. Other than that, I'm out of ideas, best of luck.

You can see the policy files themselves if you open up the lib/security/local_policy.jar and US_export_policy.jar files in winzip and look at the conatined *.policy files in notepad and make sure they look like this:

default_local.policy:

    // Country-specific policy file for countries with no limits on crypto strength.
grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission; 
};

default_US_export.policy:

// Manufacturing policy file.
grant {
    // There is no restriction to any algorithms.
    permission javax.crypto.CryptoAllPermission; 
};
Petey B
  • 11,439
  • 25
  • 81
  • 101
  • Would it do me any good to extract the files from the 2 jar files, and leave the extracted files in the security folder? – katura Jun 23 '11 at 17:23
  • @katura, No, keep them in their packaged jars, though I don't think it would hurt if you wanted to try it. – Petey B Jun 23 '11 at 17:59
4

Add below code in your client code :

static {
    Security.insertProviderAt(new BouncyCastleProvider(),1);
 }

with this there is no need to add any entry in java.security file.

Anil Verma
  • 181
  • 1
  • 5
1

I faced the same issue. Tried adding the US_export_policy.jar and local_policy.jar in the java security folder first but the issue persisted. Then added the below in java_opts inside tomcat setenv.shfile and it worked.

-Djdk.tls.ephemeralDHKeySize=2048

Please check this link for further info

Divya S
  • 59
  • 1
1

The error seems to be thrown when you try and load they keystore from "C:/jakarta-tomcat/webapps/PlanB/Certs/my_pkcs12.p12" here:

ks.load( new FileInputStream(_privateKeyPath), _keyPass.toCharArray() ); 

Have you tried replaceing "/" with "\\" in your file path? If that doesn't help it probably has to do with Java's Unlimited Strength Jurisdiction Policy Files. You could check this by writing a little program that does AES encryption. Try encrypting with a 128 bit key, then if that works, try with a 256 bit key and see if it fails.

Code that does AES encyrption:

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Test 
{
    final String ALGORITHM = "AES";                       //symmetric algorithm for data encryption
    final String PADDING_MODE = "/CBC/PKCS5Padding";      //Padding for symmetric algorithm
    final String CHAR_ENCODING = "UTF-8";                 //character encoding
    //final String CRYPTO_PROVIDER = "SunMSCAPI";             //provider for the crypto

    int AES_KEY_SIZE = 256;  //symmetric key size (128, 192, 256) if using 256 you must have the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files  installed

    private String doCrypto(String plainText) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException
    {
        byte[] dataToEncrypt = plainText.getBytes(CHAR_ENCODING);

        //get the symmetric key generator
        KeyGenerator keyGen = KeyGenerator.getInstance(ALGORITHM);
        keyGen.init(AES_KEY_SIZE); //set the key size

        //generate the key
        SecretKey skey = keyGen.generateKey();

        //convert to binary
        byte[] rawAesKey = skey.getEncoded();

        //initialize the secret key with the appropriate algorithm
        SecretKeySpec skeySpec = new SecretKeySpec(rawAesKey, ALGORITHM);

        //get an instance of the symmetric cipher
        Cipher aesCipher = Cipher.getInstance(ALGORITHM + PADDING_MODE);

        //set it to encrypt mode, with the generated key
        aesCipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        //get the initialization vector being used (to be returned)
        byte[] aesIV = aesCipher.getIV();

        //encrypt the data
        byte[] encryptedData = aesCipher.doFinal(dataToEncrypt);    

        //initialize the secret key with the appropriate algorithm
        SecretKeySpec skeySpecDec = new SecretKeySpec(rawAesKey, ALGORITHM);

        //get an instance of the symmetric cipher
        Cipher aesCipherDec = Cipher.getInstance(ALGORITHM +PADDING_MODE);

        //set it to decrypt mode with the AES key, and IV
        aesCipherDec.init(Cipher.DECRYPT_MODE, skeySpecDec, new IvParameterSpec(aesIV));

        //decrypt and return the data
        byte[] decryptedData = aesCipherDec.doFinal(encryptedData);

        return new String(decryptedData, CHAR_ENCODING);
    }

    public static void main(String[] args)
    {
        String text = "Lets encrypt me";

        Test test = new Test();

        try {
            System.out.println(test.doCrypto(text));
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Does this code work for you?

You might also want to try specifying your bouncy castle provider in this line:

Cipher.getInstance(ALGORITHM +PADDING_MODE, "YOUR PROVIDER");

And see if it could be an error associated with bouncy castle.

Petey B
  • 11,439
  • 25
  • 81
  • 101
  • I tried your suggestion with the path, using "\\" instead of "/". Didn't work:( Then I tried creating the RSA key with 128 and 256 encryption. While the file was successfully generated, I couldn't create the public-cert.pem using the private-key.pem as I was presented with errors : 3576:error:04075070:rsa routines: RSA_sign:digest too big for rsa key:.\crypto\rsa\rsa_sign.c:119: 3576:error:0D0C3006:asn1 encoding routines: ASN1_item_sign:EVP lib:.\crypto\asn1\a_sign.c:279: error in req. It seems to be okay with 1024 bit though... – katura Jun 17 '11 at 14:23
  • @Petey B - I really don't know anything much about certs and keys - so it'll be rather difficult for me to understand AES encryption and the use of your code snippet. I'm sorry. – katura Jun 17 '11 at 14:25
  • @katura, I added the full code for AES encryption with a 256 bit key. See if it works on your end. – Petey B Jun 17 '11 at 14:44
  • @Petey - Thank you. I ran the code and this is the exception I got : java.security.InvalidKeyException: Illegal key size or default parameters at javax.crypto.Cipher.a(DashoA13*..) at javax.crypto.Cipher.a(DashoA13*..) at javax.crypto.Cipher.a(DashoA13*..) at javax.crypto.Cipher.init(DashoA13*..) at javax.crypto.Cipher.init(DashoA13*..) at palmb.servlets.paypal.Test.doCrypto(Test.java:48) at palmb.servlets.paypal.Test.main(Test.java:78) – katura Jun 17 '11 at 14:58
  • @katura, change the "AES_KEY_SIZE = 256" to "AES_KEY_SIZE = 128" and see if it works. If it does, then you have not properly installed the Unlimited Strength Policy, so that is what is causing the error in your question. – Petey B Jun 17 '11 at 15:55
  • @Petey - I changed AES_KEY_SIZE="128" - and it worked, as I saw "Lets encrypt me". I'm pretty sure I followed the instructions properly for JCE installation. Maybe I should post the steps I took in doing so, but add this info to my original post...will get that up in a few mins. – katura Jun 17 '11 at 15:59