Расшифровать с помощью jasypt после получения зашифрованного значения в Http-запросе

У меня возникла проблема с работой jaspyt в этом сценарии:

StrongTextEncryptor textEncryptor = new StrongTextEncryptor();      
textEncryptor.setPassword("myPassword");
String myEncryptedParam = textEncryptor.encrypt("myClearMessage");

myObject.setCallbackUrl("http://myhost/notification?myparam="+myEncryptedParam);

Когда я получаю URL-адрес обратного вызова и пытаюсь расшифровать параметр «myParam», указанный в URL-адресе, С ТЕМ ЖЕ СИЛЬНЫМ ТЕКСТЕНКРИПТОРОМ, который используется в запросе, возникает исключение:

org.jasypt.exceptions.EncryptionOperationNotPossibleException
at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.decrypt(StandardPBEByteEncryptor.java:1055)
at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:725)
at org.jasypt.util.text.StrongTextEncryptor.decrypt(StrongTextEncryptor.java:118)
at com.softlysoftware.caligraph.util.Util.decryptMessage(Util.java:30)

Копая немного больше в исключении, я получаю:

BadPaddingException: Given final block not properly padded

Если я тестирую процесс шифрования/дешифрования без httprequest, работает нормально.


person Antonio Acevedo    schedule 08.12.2014    source источник


Ответы (2)


Проблема в том, что StrongTextEncryptor использует StandardPBEStringEncryptor, который, в свою очередь, использует Base64 для кодирования зашифрованных текстов. Проблема в том, что в Base64 есть символ /, который не является безопасным для URL. Когда вы пытаетесь расшифровать, используемый вами анализатор параметров, вероятно, отбрасывает эти / символа, что делает зашифрованный текст неполным.

Самое простое решение, вероятно, состоит в том, чтобы заменить оскорбительные символы, заменив все:

myEncryptedParam.replaceAll("/", "_").replaceAll("\\+", "-");

и обратно, прежде чем пытаться расшифровать:

receivedParam.replaceAll("_", "/").replaceAll("-", "\\+");

Это преобразует кодировку из обычной кодировки Base64 в "URL и имя файла безопасный" алфавит Base 64.

person Artjom B.    schedule 08.12.2014

Основываясь на ответе Артёма, вот оболочка текстового шифратора Jasypt.

import org.jasypt.util.text.TextEncryptor;

public class UrlSafeTextEncryptor implements TextEncryptor {

    private TextEncryptor textEncryptor; // thread safe

    public UrlSafeTextEncryptor(TextEncryptor textEncryptor) {
        this.textEncryptor = textEncryptor;
    }

    public String encrypt(String string) {
        String encrypted = textEncryptor.encrypt(string);

        return encrypted.replaceAll("/", "_").replaceAll("\\+", "-");
    }

    public String decrypt(String encrypted) {

        encrypted = encrypted.replaceAll("_", "/").replaceAll("-", "\\+");

        return textEncryptor.decrypt(encrypted);
    }
}

и соответствующий тестовый пример

import org.jasypt.util.text.StrongTextEncryptor;
import org.jasypt.util.text.TextEncryptor;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class UrlSafeTextEncryptorTest {

    private String password = "12345678";

    protected TextEncryptor encryptor;
    protected UrlSafeTextEncryptor urlSafeEncryptor;

    @Before
    public void init() {
        StrongTextEncryptor encryptor = new StrongTextEncryptor(); // your implementation here
        encryptor.setPassword(password);

        this.encryptor = encryptor;

        this.urlSafeEncryptor = new UrlSafeTextEncryptor(encryptor);
    }

    @Test
    public void scramble_roundtrip_urlSafe() {

        int i = 0;
        while(true) {
            String key = Integer.toString(i);

            String urlSafeEncrypted = urlSafeEncryptor.encrypt(key);

            Assert.assertFalse(urlSafeEncrypted, urlSafeEncrypted.contains("/"));

            Assert.assertEquals(key, urlSafeEncryptor.decrypt(urlSafeEncrypted));

            if(urlSafeEncrypted.contains("_")) {
                break;
            }

            i++;
        }

    }
}
person ThomasRS    schedule 05.01.2016