J'ai essayé d'obtenir du code Java fonctionnel pour chiffrer les boutons Paypal. Ce n'est pas une tache facile! Même quand je reçois du code, de Paypal, je suis confronté à des erreurs .. euh ..
Voici donc ce que j’ai eu jusqu’à présent, qui, je pense, fonctionnera éventuellement.
J'ai téléchargé le fichier Java.Zip à partir du site Web de Paypal. Il contient deux classes: ClientSide.Java et ButtonEncryption.Java.
Le problème - Je reçois une erreur InvalidKeyException : Illegal key size
.
Des questions
1) Comment résoudre ce problème? 2) Quelle ligne de code génère l'erreur?
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)
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();
}
}
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();
}
}
}
J'ai généré la clé privée et le certificat public avec OpenSSL via les commandes suivantes .
Clé privée
openssl genrsa -out clé privée.pem 1024
Certificat public
openssl req -new -key clé-privée.pem -x509 -days 1095 -out public-cert.pem
Fichier PKCS12 créé
openssl pkcs12 -export -in public-cert.pem -inkey clé-privée.pem -out mon_pkcs12.p12
De plus, je devais télécharger le certificat public Paypal depuis le site Web de Paypal.
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
Voici les étapes que j'ai suivies pour installer les fichiers de stratégie JCE Unlimited Strength:
1) Nous sommes allés à Téléchargement de JCE Java Page sur Oracle.
2) Fichiers extraits de Zip.
3) Placé les fichiers local_policy.jar et US_export_policy.jar dans le dossier C:\Java\jdk1.6.0_22\jre\lib\security.
Remarque: C:\Java\jdk1.6.0_22 est défini sur% Java_HOME%
4) Chemin de classe système mis à jour pour inclure l’emplacement des bocaux .
Remarque: le dossier de sécurité contient d’autres fichiers fournis avec JDK 1.6, notamment: Java.policy, Java.security, javaws.policy, Trusted.libraries - mais ils n’ont probablement rien à voir avec les fichiers JCE. , droite?
Je suis allé à la page du château de Bouncy à l'adresse _ { http://www.bouncycastle.org/specifications.html#install } _
Faites défiler la liste jusqu’à 5.0 Bouncy Castle Provider puis lisez les informations sous 5.1 Exemple. Il mentionne l'ajout d'un paramètre pour le fournisseur du château gonflable au fichier Java.security
. Mon fichier est sous C:\Java\jdk1.6.0_22\jre\lib\security.
J'ai ajouté la ligne suivante à mon fichier - security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider
De plus, j'ai découvert que je n'avais pas ajouté les jarres Bouncy Castle au parcours de la classe, alors je suis allé de l'avant et je l'ai fait .
Maintenant, après avoir apporté ces modifications, recompilé et tenté d’exécuter ClientSide.Java
, on me donne la même exception: mais peut-être que l’accent devrait être mis sur la partie de l’exception où il est dit ceci sur le fournisseur de Bouncycastle -
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.cryptData(Unknown Source)
at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown Source)
@PeteyB - Je suis certain d'avoir correctement installé les fichiers de règles. D'après ce que j'ai dit ici, pouvez-vous suggérer autre chose d'essayer? Pouvez-vous consulter le site du château gonflable @ _ { http://www.bouncycastle.org/specifications.html#install et voir s’il manque quelque chose?
Le problème doit donc venir de votre installation JCE Unlimited Strength.
Assurez-vous d’écraser les local_policy.jar
et US_export_policy.jar
à la fois dans le jdk1.6.0_25\jre\lib\security\
de votre JDK et dans le dossier lib\security\
de votre JRE.
Dans mon cas, je placerais les nouveaux .jars dans:
C:\Program Files\Java\jdk1.6.0_25\jre\lib\security
et
C:\Program Files\Java\jre6\lib\security
Si vous exécutez Java 8 et que vous rencontrez ce problème. Les étapes ci-dessous devraient aider!
Accédez à votre installation JRE (par exemple - jre1.8.0_181\lib\security\policy\unlimited), copiez local_policy.jar et remplacez-la par «local_policy.jar» dans votre répertoire d'installation JDK (par exemple, jdk1.8.0_141\jre\lib\security).
Si vous recevez toujours l'InvalidKeyException lors de l'exécution de mon programme de chiffrement AES avec des clés de 256 bits, mais pas avec des clés de 128 bits, c'est parce que vous n'avez pas installé correctement les nouveaux fichiers JAR de règles et qu'il n'a rien à voir avec BouncyCastle (qui est également restreint par ces fichiers de politique). Essayez de désinstaller, puis de réinstaller Java, puis de remplacer les anciens fichiers jar par les nouveaux. Sinon, je suis à court d'idées et je souhaite la meilleure des chances.
Vous pouvez voir les fichiers de règles eux-mêmes si vous ouvrez les fichiers lib/security/local_policy.jar et US_export_policy.jar dans winzip et regardez les fichiers * .policy dans le bloc-notes et assurez-vous qu'ils ressemblent à ceci:
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;
};
Ajoutez le code ci-dessous dans votre code client:
static {
Security.insertProviderAt(new BouncyCastleProvider(),1);
}
avec cela, il n'est pas nécessaire d'ajouter une entrée dans le fichier Java.security.
L'erreur semble être générée lorsque vous essayez de charger le fichier de clés à partir de "C: /jakarta-Tomcat/webapps/PlanB/Certs/my_pkcs12.p12" ici:
ks.load( new FileInputStream(_privateKeyPath), _keyPass.toCharArray() );
Avez-vous essayé de remplacer "/" par "\\" dans votre chemin de fichier? Si cela ne vous aide pas, cela a probablement un rapport avec les fichiers de stratégie juridictionnelle à puissance illimitée de Java. Vous pouvez vérifier cela en écrivant un petit programme qui effectue le cryptage AES. Essayez de chiffrer avec une clé de 128 bits, puis si cela fonctionne, essayez avec une clé de 256 bits et voyez si elle échoue.
Code qui encyrpte AES:
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();
}
}
}
Ce code fonctionne-t-il pour toi?
Vous pouvez également essayer de spécifier votre fournisseur de château gonflable dans cette ligne:
Cipher.getInstance(ALGORITHM +PADDING_MODE, "YOUR PROVIDER");
Et voyez si cela pourrait être une erreur associée à un château gonflable.
J'ai fait face au même problème. J'ai essayé d'ajouter les US_export_policy.jar
et local_policy.jar
dans le dossier de sécurité Java, mais le problème persistait. Puis ajouté le ci-dessous dans Java_opts
à l'intérieur de Tomcat setenv.sh
file et cela a fonctionné.
-Djdk.tls.ephemeralDHKeySize=2048
Veuillez vérifier ce lien link pour plus d'informations