InvalidKeyException: Tamaño de clave ilegal: excepción de lanzamiento de código Java para la clase de cifrado: ¿cómo solucionarlo?
security encryption (5)
Agregue el código siguiente en su código de cliente:
static {
Security.insertProviderAt(new BouncyCastleProvider(),1);
}
con esto no hay necesidad de agregar ninguna entrada en el archivo java.security.
He intentado obtener un código Java que funcione para cifrar los botones de Paypal. ¡Esta no es una tarea fácil! Incluso cuando recibo un código, de Paypal, me enfrento a errores ... por ejemplo ...
Así que aquí está lo que tengo hasta ahora, que creo que va a funcionar con el tiempo.
Descargué el archivo Java.zip del sitio web de Paypal. Dentro de él hay dos clases: ClientSide.java y ButtonEncryption.java
El problema InvalidKeyException : Illegal key size
una InvalidKeyException : Illegal key size
error de InvalidKeyException : Illegal key size
.
Preguntas
1) ¿Cómo resuelvo este problema? 2) ¿Qué línea de código está arrojando el 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)
Clase ClientSide
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();
}
}
Clase ButtonEncryption
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();
}
}
}
Editado: información sobre claves / certificados
Genere la clave privada y el certificado público con OpenSSL a través de los siguientes comandos.
Llave privada
openssl genrsa -out private-key.pem 1024
Certificado público
openssl req -new -key private-key.pem -x509 -days 1095 -out public-cert.pem
Archivo creado PKCS12
openssl pkcs12 -export -en public-cert.pem -inkey private-key.pem -out my_pkcs12.p12
Además, tuve que descargar el certificado público de Paypal desde el sitio web de Paypal.
Editado - agregando advertencias de compilación - 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
Pasos de instalación del archivo de políticas de JCE
Estos son los pasos que tomé para instalar los archivos de la Política de fuerza ilimitada de JCE:
1) Fui a la página de descarga Java JCE en Oracle.
2) archivos extraídos de zip.
3) Colocaron los archivos local_policy.jar y US_export_policy.jar en la carpeta C: / Java / jdk1.6.0_22 / jre / lib / security.
Nota: C: / Java / jdk1.6.0_22 se establece como% JAVA_HOME%
4) ruta de clase del sistema actualizada para incluir la ubicación de los frascos.
Nota: Hay otros archivos, que vienen con el JDK 1.6 dentro de la carpeta de seguridad, que incluyen: java.policy, java.security, javaws.policy, trusted.libraries, pero probablemente no tienen nada que ver con los archivos JCE, ¿verdad?
Editar 23/06/2011 - resultados después de la configuración posterior
Fui a la página de Bouncy Castle en http://www.bouncycastle.org/specifications.html#install
Desplácese hasta 5.0 Bouncy Castle Provider y luego lea la información en 5.1 Ejemplo . Hace mención de agregar un parámetro para el proveedor de Bouncy Castle al archivo java.security
. Mi archivo está bajo C: / Java / jdk1.6.0_22 / jre / lib / security.
security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
la siguiente línea a mi archivo - security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
Además, descubrí que no había agregado los frascos de Bouncy Castle al classpath, así que seguí adelante y lo hice.
Ahora, después de hacer estos cambios, ClientSide.java
a compilar e intentar ejecutar ClientSide.java
, ClientSide.java
la misma excepción: pero tal vez el enfoque debe ser por parte de la excepción donde dice esto sobre el proveedor de bouncycastle:
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.cryptData(Unknown Source)
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
@PeteyB: estoy seguro de que instalé los archivos de política correctamente. En base a lo que dije aquí, ¿hay algo más que sugiera que intente? ¿Puedes mirar el sitio de Bouncy Castle @ http://www.bouncycastle.org/specifications.html#install y ver si hay algo que me falta?
Enfrenté el mismo problema. US_export_policy.jar
agregar US_export_policy.jar
y local_policy.jar
en la carpeta de seguridad de Java pero el problema persistió. Luego agregué lo siguiente en java_opts
dentro del archivo tomcat setenv.sh
y funcionó.
-Djdk.tls.ephemeralDHKeySize=2048
Por favor, consulte este link para obtener más información
Parece que el error se produce cuando intentas cargar el almacén de claves desde "C: /jakarta-tomcat/webapps/PlanB/Certs/my_pkcs12.p12" aquí:
ks.load( new FileInputStream(_privateKeyPath), _keyPass.toCharArray() );
¿Has intentado reemplazar "/" con "//" en tu ruta de archivo? Si eso no ayuda, probablemente tenga que ver con los archivos de política de jurisdicción de fuerza ilimitada de Java. Puede verificar esto escribiendo un pequeño programa que haga cifrado AES. Intente cifrar con una clave de 128 bits, y si eso funciona, intente con una clave de 256 bits y vea si falla.
Código que hace 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();
}
}
}
¿Este código funciona para usted?
También puede intentar especificar su proveedor de castillo hinchable en esta línea:
Cipher.getInstance(ALGORITHM +PADDING_MODE, "YOUR PROVIDER");
Y mira si podría ser un error asociado con el castillo hinchable.
Por lo tanto, el problema debe ser con su instalación JCE Unlimited Strength.
Asegúrese de sobrescribir local_policy.jar
y US_export_policy.jar
en jdk1.6.0_25/jre/lib/security/
su JDK y en la jdk1.6.0_25/jre/lib/security/
de su JRE.
En mi caso, colocaría los nuevos .jars en:
C:/Program Files/Java/jdk1.6.0_25/jre/lib/security
y
C:/Program Files/Java/jre6/lib/security
Si todavía está recibiendo InvalidKeyException al ejecutar mi programa de cifrado AES con claves de 256 bits, pero no con claves de 128 bits, es porque no ha instalado correctamente los nuevos archivos JAR de política, y no tiene nada que ver con BouncyCastle (que también es restringido por esos archivos de política). Intente desinstalar, luego reinstalar Java y luego reemplazar los viejos jar con los nuevos de fuerza ilimitada. Aparte de eso, me he quedado sin ideas, la mejor de las suertes.
Puede ver los archivos de políticas si abren los archivos lib / security / local_policy.jar y US_export_policy.jar en winzip y miran los archivos * .policy conatined en el bloc de notas y se aseguran de que se vean así:
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;
};