【问题标题】:BadPaddingException in RSA EncrryptionRSA 加密中的 BadPaddingException
【发布时间】:2020-07-14 19:48:25
【问题描述】:

我在我的 RSA 加密程序中遇到了 BadPaddingException。 我不知道它为什么会发生。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;


public class Crypter
{


    private static final String text="Hallo";


    public static byte[] encryptObject(Nachricht msg,PublicKey pubkey) //verschlüsselt das Objekt im CipherStream
    {
        Cipher cipher;
        try
        {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubkey);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            CipherOutputStream cos = new CipherOutputStream(bos, cipher); 
            ObjectOutputStream oos = new ObjectOutputStream(cos); 
            oos.writeObject(msg); 
            oos.flush();

            byte[] encryptedBytes = bos.toByteArray();  
            return encryptedBytes;

            //weiss nicht was ich zurückgeben soll 
            //den ObjectOutputStream
            //oder die verschlüsselten Bytes


            //byte[] encryptedBytes = bos.toByteArray();  

        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;

    }

    public static Nachricht decryptObject(PrivateKey privKey,byte[] encryptedBytes) //entschlüsselt das Object
    {
        Nachricht  msg=null;
        try
        {
            Cipher cipher = Cipher.getInstance("RSA");

            cipher.init(Cipher.DECRYPT_MODE, privKey);
            ByteArrayInputStream bin = new ByteArrayInputStream(encryptedBytes);
            CipherInputStream cin = new CipherInputStream(bin, cipher);
            ObjectInputStream in = new ObjectInputStream(cin);
            return (Nachricht) in.readObject();


        } catch (InvalidKeyException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }



        return null;
    }




    //verschlüsselt Text
    public static byte[] encryptBytes(PublicKey key, byte[] plain)
    {
        byte[] chiffre=null;

        try
        {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            chiffre= cipher.doFinal(plain);

            return chiffre; //verschlüsseltes byte[]

        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException 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();
        }

        return null; 

    }
    //entschlüsselt Text
    public static byte[] decryptBytes(PrivateKey key, byte[] chiffre)
    {

        try
        {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(cipher.DECRYPT_MODE,key);

            byte[] btext= cipher.doFinal(chiffre);
            return btext;


        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeyException 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();
        }

        return null; //er meckert sonst....
    }



    public static void main(String [] args)
    {


        try
        {


            //KeyPair und Keys managen
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(1024);
            KeyPair keypair=keyPairGen.generateKeyPair();
            PrivateKey privKey=keypair.getPrivate();
            PublicKey pubKey=keypair.getPublic();

            //Text->Byte
            //Byte->Text
            System.out.println("\n\nTest");
            String testtext= "h";
            byte[] testbyte=testtext.getBytes();
            System.out.println(testbyte);
            testtext=new String(testbyte);
            System.out.println(testtext);
            System.out.println("\n\n");

            //Text->Byte[] text
            //byte[] text->encrypt
            //byte[]encrypt-> decrypt
            //byte[] decrypt->String
            System.out.println("Ausgangstext:");
            System.out.println(text);
            System.out.println("1)Text als byte[] unverschlüsselt");
            byte[] bytetext=text.getBytes(); //in byte[] umgewandelt
            System.out.println( bytetext); //bytetext anzeigen lassen
            System.out.println("2) byte[] verschlüsselt");
            byte[] encrypt=encryptBytes(pubKey,bytetext); //verschlüsseln des byte[]
            System.out.println( encrypt); //ausgeben lassen
            System.out.println("3) byte[] entschlüsselt");
            byte[]decrypt=decryptBytes(privKey,encrypt); //entschlüsseln lassen
            String text=new String(decrypt);
            System.out.println(text);
            //String s = new String(bytes);

            //Object->byte[]
            //byte[] object-> byte[] encrypt
            //byte[] encrypt -> byte[]decrypt
            //byte[] decrypt -> object
            System.out.println("Ausgangsobjekt:");
            Nachricht  msg=new Nachricht();
            msg.setNachricht("Hallo");
            //verschlüsseln des Objekts
            byte[] vObject=encryptObject(msg,pubKey);
            System.out.println("Test ");
            Nachricht neuemsg=decryptObject(privKey,vObject);
            System.out.println("Test2");
            String nachricht=neuemsg.getNachricht();
            System.out.println(nachricht);










        } catch (NoSuchAlgorithmException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }






    }

}




感谢任何帮助或提示! 我编写的处理字符串加密的函数工作正常,如主函数中所示。 我不知道要添加什么。 该代码通过了“测试”系统输出,但也引发了一些异常。 我希望您知道缺少什么或我必须添加什么才能使其正常工作。

【问题讨论】:

  • 你能发布堆栈跟踪吗?哪种方法给了你例外?

标签: java encryption rsa badpaddingexception


【解决方案1】:

嗯,问题的直接原因是您忘记在 ObjectOutputStream(它关闭所有其他流,包括 CipherOutputStream)上调用此方法:

oos.close();

来自CipherOutputStream.close 的 JavaDocs:

此方法调用封装密码对象的 doFinal 方法,该方法会处理封装密码缓冲的所有字节。

所以对于某些密码,flush 可能会导致某些字节加密,但不会在末尾添加填充。

但还有很多其他事情也会导致悲伤:

  1. 您没有指定应该使用哪个填充,所以这在其他 Java 安装中可能会有所不同,请参阅一些建议:JavaDoc for Cipher 或例如 this question
  2. 如果您的对象变得稍大一些(或者您使用了占用更多空间的不同填充),则加密的结果是一个 0 字节的数组,不会引发任何异常。另请参阅:this question 建议使用 AES 等对称密码进行加密,并且仅使用 RSA 加密 AES 密钥。 (或者将密钥大小加倍并准备每次密钥大小翻倍时 CPU 时间增加 7 或 8 倍,请参阅:this question for a little more info
  3. 您应该知道 String.toBytes() 和 String(byte[]) 都使用默认编码,在其他计算机上可能会有所不同,请确保指定例如java.nio.charset.StandardCharSets.UTF_8

免费建议:如果您要将“Nachricht”(消息)交换到另一台计算机,并且想要真正安全、快速、简单(在一定程度上)和万无一失的东西,我建议您使用 TLS(或 DTLS),它基于 25 年的研究和实践。

【讨论】:

    猜你喜欢
    • 2011-02-24
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2021-07-28
    • 1970-01-01
    • 2015-08-04
    相关资源
    最近更新 更多