Проблема с Java-шифром, когда я хочу расшифровать его - PullRequest
0 голосов
/ 31 августа 2018

Я создал приложение с javafx, которое я могу написать и сохранить в базе данных. моя база данных sqlite. это очень простое приложение. хотя я добавил приложение для входа в свое приложение для записи, все же sqlite можно открыть любым программным обеспечением. вместо того, чтобы зашифровать базу данных sqlite (чего я не знал, и мне показалось, что это очень смущает :)), я решил зашифровать текст в Java, а позже, когда захочу его прочитать, я верну его в нормальное состояние и покажу.

Я научился делать это по этой ссылке и изменил ее, чтобы печатать строку вместо записи в файл. поэтому мой окончательный код выглядит так:

public static void main(String[] args) throws Exception {

    String textA = "";
    String textB="";

    byte[] thisismykey = "Hello How manyBytes are in@hts A".getBytes();
    SecretKey secKey = new SecretKeySpec(thisismykey, "AES");


    Cipher aesCipher = Cipher.getInstance("AES");

    //turn your original text to byte
    byte[] myoriginaltexttobyte = "Your Plain Text Here".getBytes();
    //activate the encrypt method
    aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
    //encrypt the text and assign the encrypted text to a byte array
    byte[] bytecipheredoforgtext = aesCipher.doFinal(myoriginaltexttobyte);
    //change it to string with new string
    textA = new String(bytecipheredoforgtext);
    System.out.println(textA);

    //get the bytes of encrypted text and assign it to a byte array
    byte[] byteofencryptedtext = textA.getBytes();
    //activate the decrypt mode of the cipher
    aesCipher.init(Cipher.DECRYPT_MODE, secKey);
    //decrypt the encrypted text and assign it to a byte array
    byte[] byteofencryptedbacktonormaltext = aesCipher.doFinal(byteofencryptedtext);
    //change it to string with new string
    textB = new String(byteofencryptedbacktonormaltext);
    System.out.println(textB);
}

Теперь, когда шифрование и дешифрование выполняются одним и тем же методом, оно работает отлично, но я хочу изменить его на класс с другими методами, чтобы я мог зашифровать текст одним методом и расшифровать его другим. но когда я разделяю вещи, расшифровка не работает хорошо. Шифрование работает хорошо. это код сейчас:

public class CipherFinalB {

//from https://stackoverflow.com/questions/20796042/aes-encryption-and-decryption-with-java/20796446#20796446
private final byte[] thisismykey;
private final SecretKey secKey;
private final Cipher aesCipher;
public CipherFinalB() throws NoSuchPaddingException, NoSuchAlgorithmException {
    thisismykey = "HellodHowfmanyBytesgarehin@htseA".getBytes();
    secKey = new SecretKeySpec(thisismykey, "AES");

    aesCipher = Cipher.getInstance("AES");

}public String encrypt (String originaltext) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    byte[] myoriginaltexttobyte =originaltext.getBytes();
    aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
    byte[] bytecipheredoforgtext = aesCipher.doFinal(myoriginaltexttobyte);
    String textA = new String(bytecipheredoforgtext);
    System.out.println(textA);
    return new String(bytecipheredoforgtext);
}

public String decrypt (String encryptedtext) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    byte[] byteofencryptedtext = encryptedtext.getBytes();
    aesCipher.init(Cipher.DECRYPT_MODE, secKey);
    byte[] byteofencryptedbacktonormaltext = aesCipher.doFinal(byteofencryptedtext);
    return new String(byteofencryptedbacktonormaltext);
}

}

когда я использую метод шифрования, он возвращает мне строку. и когда я посылаю ту же строку в метод дешифрования, она не работает и выдает мне следующую ошибку:

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:936)
    at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847)
    at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
    at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2191)
    at main.CipherFinalB.decrypt(CipherFinalB.java:66)
    at main.CipherTest.main(CipherTest.java:16)

Что мне делать?

ОБНОВЛЕНИЕ ОТВЕТ:

как сказал @Juan, проблема заключалась в том, что «при шифровании данных в массиве может быть любой байт, а не только печатные символы». Поэтому я изменил метод, чтобы возвращать байт для метода шифрования и метода дешифрования. Метод decrypt теперь получает байт в качестве параметра вместо строки, и теперь все работает нормально.

обновленный код выглядит так:

 public byte[] encrypt (String originaltext) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    byte[] myoriginaltexttobyte =originaltext.getBytes();
    aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
    byte[] bytecipheredoforgtext = aesCipher.doFinal(myoriginaltexttobyte);
    String textA = new String(bytecipheredoforgtext);
    System.out.println(textA);
    return bytecipheredoforgtext;
}

public byte[] decrypt (byte[] encryptedtext) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    byte[] byteofencryptedtext = encryptedtext;
    aesCipher.init(Cipher.DECRYPT_MODE, secKey);
    byte[] byteofencryptedbacktonormaltext = aesCipher.doFinal(byteofencryptedtext);
    return byteofencryptedbacktonormaltext;
}

1 Ответ

0 голосов
/ 31 августа 2018

Я не уверен, что ошибка вызвана этим, но преобразование между String и byte [], которое вы выполняете, может работать с байтами в диапазоне набора символов, но когда данные зашифрованы, у вас может быть любой байт в массиве, не только печатные символы.

После того, как вы получите байт [] с зашифрованным текстом, закодируйте его как Base64 и сохраните строковое представление.

При дешифровании сначала декодируйте Base64 в байт [], а затем расшифруйте его.

См. Base64 класс

...