javax.crypto.BadPaddingException: неизвестный тип блока

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

    private static SecureRandom random = new SecureRandom();

    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    protected synchronized void generateKeys() throws InvalidKeyException, IllegalBlockSizeException, 
            BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, 
                NoSuchPaddingException {

        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");

        generator.initialize(256, random);

        KeyPair pair = generator.generateKeyPair();
        Key pubKey = pair.getPublic();
        Key privKey = pair.getPrivate();

        //store public key
        try {
            storeKey(pubKey, Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-publickey")));
        } catch (Exception e) {
            e.printStackTrace();
            DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
        } 

        //store private key
        try {
            storeKey(privKey, Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-privatekey")));
        } catch (Exception e) {
            e.printStackTrace();
            DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
        } 
    }

    protected synchronized String encryptUsingPublicKey(String plainText) throws IllegalBlockSizeException, BadPaddingException, 
        NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, 
            FileNotFoundException, IOException, ClassNotFoundException {

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, readKey(Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-publickey"))), random);
        byte[] cipherText = cipher.doFinal(plainText.getBytes());
        System.out.println("cipher: " + new String(cipherText));    

        return new String(cipherText);
    }

    protected synchronized String decryptUsingPrivatekey(String cipherText) throws NoSuchAlgorithmException, 
        NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, FileNotFoundException, 
            IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException {

        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, readKey(Constants.KEY_PATH.concat(Constants.SERVER_PREFIX.concat("-privatekey"))));
        byte[] plainText = cipher.doFinal(cipherText.getBytes());
        System.out.println("plain : " + new String(plainText));

        return new String(plainText);
    }
    public static void main(String[] args) {
        KeyGenerator keyGenerator = new KeyGenerator();
        try {
            keyGenerator.deleteAllKeys(Constants.KEY_PATH);
            keyGenerator.generateKeys();

            String cipherText = keyGenerator.encryptUsingPrivateKey("dilshan");
            keyGenerator.decryptUsingPublickey(cipherText);

//          String cipherText = keyGenerator.encryptUsingPublicKey("dilshan1");
//          keyGenerator.decryptUsingPrivatekey(cipherText);
        } catch (Exception e) {
            e.printStackTrace();
            DBLogger.logMessage(e.toString(), Status.KEY_GENERATION_ERROR);
        }
    }

Это отлично работает в большинстве случаев. Но иногда выдает следующую ошибку. Это случается время от времени. В большинстве случаев это работает, поэтому у меня нет проблем с кодом. Я считаю, что это как-то связано с процессом сериализации/сериализации в файловой системе. Помощь приветствуется.

Примечание. Я использую bouncycastle.

Ошибка следующая,

javax.crypto.BadPaddingException: unknown block type
    at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
    at javax.crypto.Cipher.doFinal(DashoA13*..)
    at com.dilshan.ttp.web.KeyGenerator.decryptUsingPublickey(KeyGenerator.java:105)
    at com.dilshan.ttp.web.KeyGenerator.main(KeyGenerator.java:150)

Бывает в,

byte[] plainText = cipher.doFinal(cipherText.getBytes());

в методе decryptUsingPrivatekey.


person Dilshan    schedule 01.01.2013    source источник
comment
В дополнение к комментариям @Henry строка plainText.getBytes() вызовет у вас огорчение в будущем. Он использует кодировку по умолчанию для платформы, на которой он работает. Это может варьироваться, и это не то, что вы хотите. Вы всегда должны указывать кодировку. UTF-8 будет работать всегда, т.е. plainText.getBytes("UTF-8"). Чтобы вернуться к строке из байтов, используйте new String(plaintext, "UTF-8")   -  person President James K. Polk    schedule 01.01.2013
comment
Хорошо, конечно, я изменю это. Спасибо @GregS   -  person Dilshan    schedule 01.01.2013


Ответы (1)


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

Чтобы решить эту проблему, не преобразовывайте зашифрованный текст в строку, а носите с собой byte[].

person Henry    schedule 01.01.2013
comment
Ты прав. Проблема с сигнатурой метода. decryptUsingPrivatekey(byte[] cipherText). Вместо создания строки я изменил ее на массив байтов, который работал у меня. Спасибо. - person Dilshan; 01.01.2013