Вопрос по java, encryption – Исключение: «Данный последний блок не заполнен должным образом» в Linux, но работает в Windows

10

Мое приложение работает в Windows, но не работает в Linux сGiven final block not properly padded исключение.

Конфигурация:

Версия JDK: 1.6Windows: версия 7Linux: CentOS 5.8 64bit

Мой код ниже:

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class SecurityKey {
    private static Key key = null;
    private static String encode = "UTF-8";
    private static String cipherKey = "DES/ECB/PKCS5Padding";

    static  {
        try {
            KeyGenerator generator = KeyGenerator.getInstance("DES");
            String seedStr = "test";
            generator.init(new SecureRandom(seedStr.getBytes()));
            key = generator.generateKey();
        } catch(Exception e) {
        }
    }

    // SecurityKey.decodeKey("password")
    public static String decodeKey(String str) throws Exception  {
        if(str == null)
            return str;

        Cipher cipher = null;
        byte[] raw = null;
        BASE64Decoder decoder = new BASE64Decoder();
        String result = null;
        cipher = Cipher.getInstance(cipherKey);
        cipher.init(Cipher.DECRYPT_MODE, key);
        raw = decoder.decodeBuffer(str);
        byte[] stringBytes = null;
        stringBytes = cipher.doFinal(raw); // Exception!!!!
        result = new String(stringBytes, encode);

        return result;
    }
}

На линии:

   ciper.doFilnal(raw);

выдается следующее исключение:

   javax.crypto.BadPaddingException: Given final block not properly padded

Как я могу исправить эту проблему?

Ваша ошибка может быть вызвана несоответствием заполнения или неправильным ключом. Похоже, вы не указываете заполнение, которое вы ожидаете при декодировании. Лучше явно указать PKCS5. Также не надот использоватьsun.misc.* так как библиотека не стандартная и не поддерживается. Вокруг множество кодеров / декодеров Base64. rossum
Вы'повторяю, чтоSecureRandom ведет себя одинаково на всех платформах. Ява гарантирует это? Используйте KDF для получения ключа, а не PRNG. CodesInChaos
Вы уверены, чтоraw содержит одинаковые данные на обеих платформах? Я'Подозреваю, что перед передачей данныхdecodeKey()хотя этомаловероятно, если вы используете base64. axtavt
Я надеюсь ты нене заботится о безопасности. И DES, и ECB - сомнительный выбор. CodesInChaos

Ваш Ответ

3   ответа
2

SecureRandom Посев может быть разным для определенных сроков. Большую часть времени вы получите"SHA1PRNG", который выигралсразу посеян. Вместо этого вы можете позвонитьsetSeed() перед запросом любого случайного, и в этом случае это семя используется в качестве единственного источника энтропии. В этом случае ваш ключ всегда будет одинаковым.

Проблема в том, что не определено, какойSecureRandom возвращается Вы можете получить совершенно другую, специфичную для платформы реализацию, для которой вышеприведенное неверно. Вы можете не получить услуги поставщика Sun, если приоритет имеет другой поставщик.

Тогда есть проблема с семенем. Семя использовало кодировку платформы по умолчанию дляseedStr переменная во время вызоваgetBytes(), Поскольку кодировки могут отличаться, семена могут отличаться, и, следовательно, результат будет отличаться.

Попробуйте использовать такую функцию, как PBKDF2, вместо этого для получения ключа; на stackoverflow достаточно о том, как продолжить.

Есть кто там? Это помогло? Вы решили свою проблему? Пожалуйста, сообщите! Maarten Bodewes
Здорово, что это решило вашу проблему, было бы неплохо, если бы вы приняли ответ. Maarten Bodewes
Оно работает!! Спасибо!! user1685364
0

BASE64Decoder вернет кратные 4, а шифр ожидает кратные 8.

0

Как следует: я должен был изменить содержание.}

static{
    try {
    KeyGenerator generator = KeyGenerator.getInstance("DES");
    String seedStr = "test";
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    random.setSeed(seedStr.getBytes());
    generator.init(random);
    key = generator.generateKey();
} catch(Exception e) {
}

Это работаетs !! Спасибо!!!

Фантастика, но неЖаловаться, когда генератор случайных чисел фактически генерирует случайные числа. Maarten Bodewes

Похожие вопросы