BadPaddingException в шифровании RSA - PullRequest
0 голосов
/ 02 апреля 2020

Я получил BadPaddingException в моей программе шифрования RSA. Я не знаю, почему это происходит, хотя.

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






    }

}




Я благодарен за любую помощь или советы! Функция, которую я написал, которая обрабатывает шифрование строк, работает правильно, как показано в главной функции. Я не знаю, что добавить. Код проходит системные тесты «Test», но также выдает некоторые исключения. Я надеюсь, что вы знаете, чего не хватает или что я должен добавить, чтобы это сработало.

1 Ответ

2 голосов
/ 03 апреля 2020

Ну, прямая причина вашей проблемы в том, что вы забыли вызвать этот метод для ObjectOutputStream (который закрывает все другие потоки, включая CipherOutputStream) с:

oos.close();

From JavaDocs для CipherOutputStream.close :

Этот метод вызывает метод doFinal инкапсулированного объекта шифрования, который вызывает обработку любых байтов, буферизованных инкапсулированным шифром.

поэтому с некоторыми шифрами, возможно, грипп sh вызывает шифрование некоторых байтов, но не добавляет заполнение в конце.

Но есть много других вещей, которые также могут вызвать горе:

  1. Вы не указываете, какой отступ должен использоваться, поэтому он может отличаться в других Java установках, см. Некоторые предложения: JavaDo c для Cipher или для пример этот вопрос
  2. Если ваш объект становится немного больше (или вы используете другой отступ, который занимает больше места), результат шифрования n - это массив из 0 байтов, без каких-либо исключений. См. Также: этот вопрос , который предлагает шифровать с помощью симметричного c шифра, такого как AES, и шифровать только ключ AES с помощью RSA. (Или удвойте размер ключа и подготовьте для 7 или 8 раз больше процессорного времени каждый раз, когда размер ключа удваивается, см. этот вопрос для получения дополнительной информации )
  3. Вы должны знать, что String. toBytes () и String (byte []) используют кодировку по умолчанию, которая может отличаться на других компьютерах. Обязательно укажите, например, java.nio.charset.StandardCharSets.UTF_8

Бесплатный совет : Если вы собираетесь обменять свое «сообщение» на другой компьютер и хотите что-то действительно безопасное, быстрое, простое (в определенной степени) и надежное, я рекомендую вам использовать TLS (или DTLS), оно основано на 25 годы исследований и практики.

...