原因:java.security.KeyException:错误数据

原因:java.security.KeyException:错误数据,java,applet,cryptography,cryptoapi,Java,Applet,Cryptography,Cryptoapi,下面的代码可以很好地加密数据,但在尝试解密数据时出错 public static void cryptoFunction() throws Exception { KeyStore store = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); store.load(null); String alias = "alias"; Cert

下面的代码可以很好地加密数据,但在尝试解密数据时出错

public static void cryptoFunction() throws Exception
        {
            KeyStore store = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
            store.load(null);
            String alias = "alias";
            Certificate cert = store.getCertificate(alias);
            PublicKey pubKey = (PublicKey) cert.getPublicKey();
            PrivateKey privKey = (PrivateKey) store.getKey(alias, "123456".toCharArray());
            Cipher ecipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            Cipher dcipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

            ecipher.init(Cipher.ENCRYPT_MODE, pubKey);

            File userDir = new File("C:\\TestCryptoFiles");
            userDir.mkdir();

            File tmpdestFile = new File(userDir, "outFile.txt");
            File sourceFile = new File(userDir, "InFile.txt");

            int cipherMode = Cipher.ENCRYPT_MODE; //Cipher.DECRYPT_MODE

            byte[] buf = cipherMode == Cipher.ENCRYPT_MODE ? new byte[100]: new byte[128];
            int bufl;

            FileOutputStream outputWriter = new FileOutputStream(tmpdestFile);
            FileInputStream inputReader = new FileInputStream(sourceFile);         
            if(cipherMode == Cipher.ENCRYPT_MODE){
                while ((bufl = inputReader.read(buf)) != -1) {
                    byte[] encText = null;
                    encText = ecipher.doFinal(copyBytes(buf, bufl));
                    System.out.println(new String(encText));
                //  encText = dcipher.doFinal(encText);  // works well...
                    outputWriter.write(encText);
                }
            }else{
                while ((bufl = inputReader.read(buf)) != -1) {
                    byte[] encText = null;
                    encText = dcipher.doFinal(copyBytes(buf, bufl)); // throws exception Bad data...
                    System.out.println(new String(encText));
                    outputWriter.write(encText);
                }
            }
        }
     public static byte[] copyBytes(byte[] arr, int length) {
            byte[] newArr = null;
            if (arr.length == length)
                newArr = arr;
            else {
                newArr = new byte[length];
                for (int i = 0; i < length; i++) {
                    newArr[i] = (byte) arr[i];
                }
            }
            return newArr;
        }
public static void cryptoFunction()引发异常
{
KeyStore store=KeyStore.getInstance(“Windows MY”、“SunMSCAPI”);
store.load(null);
字符串alias=“alias”;
证书cert=store.getCertificate(别名);
PublicKey pubKey=(PublicKey)证书getPublicKey();
PrivateKey privKey=(PrivateKey)store.getKey(别名“123456.toCharArray());
Cipher-ecipher=Cipher.getInstance(“RSA/ECB/PKCS1Padding”);
Cipher dcipher=Cipher.getInstance(“RSA/ECB/PKCS1Padding”);
ecipher.init(Cipher.ENCRYPT_模式,pubKey);
File userDir=新文件(“C:\\TestCryptoFiles”);
userDir.mkdir();
File tmpdestFile=新文件(userDir,“outFile.txt”);
File sourceFile=新文件(userDir,“infle.txt”);
int cipherMode=Cipher.ENCRYPT\u MODE;//Cipher.DECRYPT\u MODE
字节[]buf=cipherMode==Cipher.ENCRYPT_模式?新字节[100]:新字节[128];
int bufl;
FileOutputStream outputWriter=新的FileOutputStream(tmpdestFile);
FileInputStream inputReader=新的FileInputStream(sourceFile);
if(cipherMode==Cipher.ENCRYPT\u模式){
while((bufl=inputReader.read(buf))!=-1){
字节[]encText=null;
encText=ecipher.doFinal(copyBytes(buf,bufl));
System.out.println(新字符串(encText));
//encText=dcipher.doFinal(encText);//工作正常。。。
outputWriter.write(encText);
}
}否则{
while((bufl=inputReader.read(buf))!=-1){
字节[]encText=null;
encText=dcipher.doFinal(copyBytes(buf,bufl));//引发异常错误数据。。。
System.out.println(新字符串(encText));
outputWriter.write(encText);
}
}
}
公共静态字节[]复制字节(字节[]arr,整数长度){
字节[]newArr=null;
if(arr.length==长度)
newArr=arr;
否则{
newArr=新字节[长度];
for(int i=0;i
我的堆栈跟踪:

java.security.ProviderException: java.security.KeyException: Bad Data.    
        at sun.security.mscapi.RSACipher.doFinal(RSACipher.java:277)
        at sun.security.mscapi.RSACipher.engineDoFinal(RSACipher.java:301)
        at javax.crypto.Cipher.doFinal(DashoA13*..)
        at FileUploader.decrypt(FileUploader.java:223)
        at FileUploader$4.run(FileUploader.java:414)
        at java.security.AccessController.doPrivileged(Native Method)
        at FileUploader.encryptDecryptFile(FileUploader.java:371)
        at FileUploader.decryptFile(FileUploader.java:362)
        at FileUploader.openFileChooser(FileUploader.java:157)
        at FileUploader.<init>(FileUploader.java:115)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at java.lang.Class.newInstance0(Unknown Source)
        at java.lang.Class.newInstance(Unknown Source)
        at sun.applet.AppletPanel.createApplet(Unknown Source)
        at sun.applet.AppletPanel.runLoader(Unknown Source)
        at sun.applet.AppletPanel.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
    Caused by: java.security.KeyException: Bad Data.

        at sun.security.mscapi.RSACipher.encryptDecrypt(Native Method)
        at sun.security.mscapi.RSACipher.doFinal(RSACipher.java:269)
        ... 19 more
java.security.ProviderException:java.security.KeyException:错误数据。
位于sun.security.mscapi.rsaciper.doFinal(rsaciper.java:277)
位于sun.security.mscapi.rsaciper.engineDoFinal(rsaciper.java:301)
位于javax.crypto.Cipher.doFinal(DashoA13*)
在FileUploader.decrypt(FileUploader.java:223)
在FileUploader$4.run(FileUploader.java:414)
位于java.security.AccessController.doPrivileged(本机方法)
在FileUploader.encryptDecryptFile(FileUploader.java:371)中
在FileUploader.decryptFile(FileUploader.java:362)
在FileUploader.openFileChooser(FileUploader.java:157)
在FileUploader上。(FileUploader.java:115)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(未知源)
位于sun.reflect.delegatingConstructor或AccessorImpl.newInstance(未知源)
位于java.lang.reflect.Constructor.newInstance(未知源)
位于java.lang.Class.newInstance0(未知源)
位于java.lang.Class.newInstance(未知源)
位于sun.applet.AppletPanel.createApplet(未知源)
位于sun.applet.AppletPanel.runLoader(未知源)
位于sun.applet.AppletPanel.run(未知源)
位于java.lang.Thread.run(未知源)
原因:java.security.KeyException:错误数据。
位于sun.security.mscapi.rsaciper.encryptDecrypt(本机方法)
位于sun.security.mscapi.rsaciper.doFinal(rsaciper.java:269)
... 还有19个

查看注释代码以更好地理解。请告诉我哪里错了。

最后我找到了解决方案,实际上我有一个RSA 2048位密钥,使用256字节,因此,我只需修改我的代码,如下所示:

byte[] buf = cipherMode == Cipher.ENCRYPT_MODE ? new byte[100]: new byte[128];
替换为:

byte[] buf = cipherMode == Cipher.ENCRYPT_MODE ? new byte[100]: new byte[256];

128字节是由RSA 1024位密钥生成的,它对该密钥很有用。

最后我找到了解决方案,实际上我有一个RSA 2048位密钥,它使用256字节,因此,我只需修改我的代码,如下所示:

byte[] buf = cipherMode == Cipher.ENCRYPT_MODE ? new byte[100]: new byte[128];
替换为:

byte[] buf = cipherMode == Cipher.ENCRYPT_MODE ? new byte[100]: new byte[256];

128字节由RSA 1024位密钥生成,它对该密钥很有用。

您希望密钥采用什么格式?格式仅在您计划导出密钥以在Java之外使用时才起作用-有关您打算如何使用密钥的信息将很有帮助。@Duncan我可以使用公钥加密数据,但我需要私钥来解密相同的数据,因此每当我将私钥传递给以解密它时,都会抛出NullPointerException。有趣,你能将堆栈跟踪添加到问题中吗?@Duncan我添加了一个方法,在我编辑的问题中执行解密和堆栈跟踪。请帮助我。@Duncan嗨Duncan,我已经编辑了我的问题,因为我可以使用接收私钥解密数据。但是我上面提到的问题出了点问题。你希望钥匙的格式是什么?格式仅在您计划导出密钥以在Java之外使用时才起作用-有关您打算如何使用密钥的信息将很有帮助。@Duncan我可以使用公钥加密数据,但我需要私钥来解密相同的数据,因此每当我将私钥传递给以解密它时,都会抛出NullPointerException。有趣,你能将堆栈跟踪添加到问题中吗?@Duncan我添加了一个方法,在我编辑的问题中执行解密和堆栈跟踪。请帮帮我。@Duncan嗨,Duncan,我编辑了我的问题,因为我可以编辑