Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InvalidKeyException : Illegal Key Size - Java code throwing exception for encryption class - how to fix?

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\[email protected]\nitem_name=vase\nitemprice=25.00";  //cmd=_xclick,[email protected],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?

like image 664
katura Avatar asked Jun 15 '11 20:06

katura


People also ask

How do I fix Java security InvalidKeyException illegal key size?

How to remove the key size restriction? You can remove the maximum key restriction by replacing the existing JCE jars with unlimited strength policy jars. Then simply restart you java application and the Exception should be gone.

What is InvalidKeyException?

KeyException which in turn is a subclass of java. security. GeneralSecurityException . As the name suggests, InvalidKeyException emerges when there is something wrong with the encryption key you are trying to use in one of your encryption algorithms.

How do I set crypto policy Unlimited?

To enable JCE Unlimited, use the crypto. policy Security property introduced in JDK 8u151. DataStax recommends enabling Java Cryptography Extension (JCE) Unlimited to ensure support for all encryption algorithms, especially AES-256 for Kerberos and SSL when using Oracle Java.


1 Answers

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).

like image 136
Petey B Avatar answered Sep 19 '22 13:09

Petey B