web-dev-qa-db-ja.com

InvalidKeyException:無効なキーサイズ-Java暗号化クラスの例外をスローするコード-修正方法

Paypalボタンの暗号化に使用するいくつかのJavaコードを取得しようとしています。これは簡単な作業ではありません! Paypalからコードを取得しても、エラーに直面します。

これが私がこれまでに持っているもので、最終的にはうまくいくと思います。

PaypalのWebサイトからJava.Zipファイルをダウンロードしました。その中には、ClientSide.JavaとButtonEncryption.Javaの2つのクラスがあります

問題-InvalidKeyException : Illegal key sizeエラーが表示されます。

質問
1)この問題を解決するにはどうすればよいですか? 2)どのコード行がエラーをスローしていますか?

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クラス

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クラス

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();
        }
    }
}


編集済み:キー/証明書に関する情報

次のコマンドを使用して、OpenSSLで秘密鍵と公開証明書を生成しました。
秘密鍵
openssl genrsa -out private-key.pem 1024
公開証明書
openssl req -new -key private-key.pem -x509 -days 1095 -out public-cert.pem
PKCS12ファイルの作成
openssl pkcs12 -export -in public-cert.pem -inkey private-key.pem -out my_pkcs12.p12


さらに、Paypal WebサイトからPaypal公開証明書をダウンロードする必要がありました。


編集-コンパイル警告を追加-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ポリシーファイルのインストール手順

これらは、JCE無制限強度ポリシーファイルをインストールするために行った手順です。
1) Java JCEダウンロード Oracleのページに行きました。
2)Zipからファイルを抽出しました。
3)local_policy.jarおよびUS_export_policy.jarファイルをC:\ Java\jdk1.6.0_22\jre\lib\securityフォルダーに配置しました。
注:C:\ Java\jdk1.6.0_22は%Java_HOME%として設定されます
4)システムクラスパスを更新して、jarの場所を含めました。
[。 JCEファイルですよね?


2011年6月23日の編集-さらに構成した後の結果

http://www.bouncycastle.org/specifications.html#install のBouncy Castleページに行きました
下にスクロールして5.0 Bouncy Castle Providerに移動し、5.1例。 Bouncy Castle ProviderのパラメーターをJava.securityファイルに追加することについて言及しています。私のファイルはC:\ Java\jdk1.6.0_22\jre\lib\securityの下にあります。

次の行をファイルに追加しました-security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

さらに、Bouncy Castleのjarファイルをクラスパスに追加していないことを発見したので、先に進んで追加しました。

今、これらの変更を行った後、再コンパイルして_ClientSide.Javaを実行しようとしていますが、同じ例外が与えられています:しかし、おそらくバウンスキャッスルプロバイダーについてこれを言っている例外の部分に焦点を当てるべきです

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

@ PeteyB-ポリシーファイルを正しくインストールしたことは確かです。ここで述べたことに基づいて、私が試してみることを提案できるものは他にありますか? Bouncy Castleサイト@ http://www.bouncycastle.org/specifications.html#install を見て、不足しているものがあるかどうかを確認できますか?

37
katura

したがって、問題はJCE Unlimited Strengthインストールにある必要があります。

JDKのlocal_policy.jarとJREのUS_export_policy.jarフォルダーの両方でjdk1.6.0_25\jre\lib\security\lib\security\を必ず上書きしてください。

私の場合、新しい.jarを次の場所に配置します。

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

そして

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


Java 8を実行していて、この問題が発生した場合。以下の手順が役立ちます!

JREインストール(たとえば-jre1.8.0_181\lib\security\policy\unlimited)に移動しますlocal_policy.jarをコピーし、JDKインストールディレクトリ(たとえば-jdk1 .8.0_141\jre\lib\security)。

73
Petey B

128ビットキーではなく256ビットキーでAES暗号化プログラムを実行しているときにInvalidKeyExceptionを受信して​​いる場合は、新しいポリシーJARファイルが正しくインストールされておらず、BouncyCastle(これもそれらのポリシーファイルによって制限されています)。アンインストールしてから、Javaを再インストールし、古いjarを新しい無制限の強度のjarに置き換えてみてください。それ以外は、うまくいきません。

Winzipでlib/security/local_policy.jarおよびUS_export_policy.jarファイルを開き、メモ帳で接続された* .policyファイルを見て、次のようになっていることを確認すると、ポリシーファイル自体を確認できます。

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; 
};
6
Petey B

クライアントコードに以下のコードを追加します。

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

これにより、Java.securityファイルにエントリを追加する必要はありません。

4
Anil Verma

ここで「C:/jakarta-Tomcat/webapps/PlanB/Certs/my_pkcs12.p12」からキーストアをロードしようとすると、エラーがスローされるようです。

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

ファイルパスの「/」を「\\」に置き換えようとしましたか?それでも解決しない場合は、おそらくJavaのUnlimited Strength Jurisdiction Policy Filesに関係しています。これを確認するには、AES暗号化を行う小さなプログラムを作成します。 128ビットキーで暗号化してみて、それが機能する場合は、256ビットキーで試して、失敗するかどうかを確認します。

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();
        }
    }
}

このコードは役に立ちますか?

また、この行で弾力のある城のプロバイダーを指定してみることもできます。

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

そして、それが弾力がある城に関連するエラーである可能性があるかどうかを確認します。

1
Petey B

私は同じ問題に直面しました。 JavaセキュリティフォルダーにUS_export_policy.jarlocal_policy.jarを最初に追加しようとしましたが、問題は解決しませんでした。次に、Tomcat Java_optsfile内のsetenv.shに以下を追加しました。

-Djdk.tls.ephemeralDHKeySize=2048

詳細を確認してください link

0
Divya S