【问题标题】:Decrypt with jasypt after retrieving the encrypted value in Http RequestHttp Request 中检索到加密值后使用 jasypt 解密
【发布时间】:2014-12-08 17:05:54
【问题描述】:

在这种情况下我无法使用 jaspyt:

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

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

当我收到回调 url 并尝试使用请求中使用的相同 STRONGTEXTENCRYPTOR 解密 url 中提供的参数“myParam”时,会引发异常:

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 的情况下测试加密/解密过程,就可以了。

【问题讨论】:

    标签: java http url encryption jasypt


    【解决方案1】:

    问题在于StrongTextEncryptor 使用StandardPBEStringEncryptor,而StandardPBEStringEncryptor 又使用Base64 对密文进行编码。问题是 Base64 有一个 / 字符,它不是 URL 安全的。当您尝试解密时,您使用的参数解析器可能会丢弃那些使密文不完整的/ 字符。

    最简单的解决方案可能是用全部替换来更改有问题的字符:

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

    在尝试解密之前再返回:

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

    这会将编码从普通的 Base64 编码转换为 "URL and Filename safe" Base 64 alphabet

    【讨论】:

      【解决方案2】:

      基于 Artjom 的回答,这里有一个 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++;
              }
      
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 2014-11-30
        • 2021-07-13
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        相关资源
        最近更新 更多