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

Мое приложение работает в 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

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

 CodesInChaos20 сент. 2012 г., 11:41
Вы'повторяю, чтоSecureRandom ведет себя одинаково на всех платформах. Ява гарантирует это? Используйте KDF для получения ключа, а не PRNG.
 Makoto27 сент. 2012 г., 19:43
 axtavt20 сент. 2012 г., 13:28
Вы уверены, чтоraw содержит одинаковые данные на обеих платформах? Я'Подозреваю, что перед передачей данныхdecodeKey()хотя этомаловероятно, если вы используете base64.
 CodesInChaos20 сент. 2012 г., 11:39
Я надеюсь ты нене заботится о безопасности. И DES, и ECB - сомнительный выбор.
 rossum20 сент. 2012 г., 13:54
Ваша ошибка может быть вызвана несоответствием заполнения или неправильным ключом. Похоже, вы не указываете заполнение, которое вы ожидаете при декодировании. Лучше явно указать PKCS5. Также не надот использоватьsun.misc.* так как библиотека не стандартная и не поддерживается. Вокруг множество кодеров / декодеров Base64.

Ответы на вопрос(3)

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

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

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

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

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

 user168536409 окт. 2012 г., 08:12
Оно работает!! Спасибо!!
 Maarten Bodewes24 сент. 2012 г., 20:28
Есть кто там? Это помогло? Вы решили свою проблему? Пожалуйста, сообщите!
 Maarten Bodewes09 окт. 2012 г., 18:17
Здорово, что это решило вашу проблему, было бы неплохо, если бы вы приняли ответ.

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

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 Bodewes25 февр. 2015 г., 19:59
Фантастика, но неЖаловаться, когда генератор случайных чисел фактически генерирует случайные числа.

Ваш ответ на вопрос