使用 Blowfish 进行加密和解密错误 - 使用填充密码解密时输入长度必须是 8 的倍数

dev*_*dar 2 java encryption blowfish

我能够加密数据,但是在解密时出现以下错误:

错误

HTTP Status 500 - Request processing failed; nested exception is javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
Run Code Online (Sandbox Code Playgroud)

这是我的加密和解密代码

//secret key 8 
    private static String strkey ="Blowfish";
Run Code Online (Sandbox Code Playgroud)

更新

 //encrypt using blowfish algorithm
    public static byte[] encrypt(String Data)throws Exception{

        SecretKeySpec key = new SecretKeySpec(strkey.getBytes("UTF8"), "Blowfish");
         Cipher cipher = Cipher.getInstance("Blowfish");
         cipher.init(Cipher.ENCRYPT_MODE, key);

         return (cipher.doFinal(Data.getBytes("UTF8")));

    }

    //decrypt using blow fish algorithm
    public static String decrypt(byte[] encryptedData)throws Exception{
         SecretKeySpec key = new SecretKeySpec(strkey.getBytes("UTF8"), "Blowfish");
         Cipher cipher = Cipher.getInstance("Blowfish");
         cipher.init(Cipher.DECRYPT_MODE, key);
         byte[] decrypted = cipher.doFinal(encryptedData);
         return new String(decrypted); 

    }
Run Code Online (Sandbox Code Playgroud)

Aks*_*hay 6

如果您在主方法中运行加密和解密方法,它将起作用。但如果将加密的结果放入url中,然后对url参数进行解密,则会失败。

\n\n

加密后,字节数组包含 URL 字符集之外的值(非 ascii),因此该值在填充到 url 中时会被编码。您会收到一个损坏的解密版本。

\n\n

举个例子,当我从加密的字节数组创建一个字符串时,它看起来像这样\xc5\xbd\xc2\xb9Q\xc3\xaaz\xc2\xa6,但如果我将它放入 URL 中,它就会变成\xc5\xbd%0B\xc2\xb9Q\xc3\xaaz\xc2\xa6.

\n\n

正如其他评论中所建议的,修复方法是添加编码/解码步骤。加密后,该值应编码为包含 ascii 字符的格式。Base 64 是一个很好的选择。因此,您在 url 中返回加密和编码的值。当你收到参数时,先解码然后解密,你将得到原始数据。

\n\n

以下是有关实施的一些注意事项。

\n\n
    \n
  1. 使用像 commons 编解码器这样的库。这是我选择的武器,这个类特别是http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64.html

  2. \n
  3. 在进行加密和解密的类中,有一个共享实例Base64。要实例化它,请使用new Base64(true);它生成 url 安全字符串。

  4. \n
  5. 您的加密和解密方法签名应该接受并返回字符串,而不是字节数组。

  6. \n
  7. 所以你的加密的最后一行会变成这样return base64.encodeToString(cipher.doFinal(Data.getBytes("UTF8")));你现在可以安全地在 url 中传递加密值

  8. \n
  9. 在解密过程中,第一步是解码。所以第一行会变成这样byte[] encryptedData = base64.decodeBase64(encrypted);

  10. \n
\n\n

我只是拿了你的代码并添加了一些 base 64 的东西,结果如下所示:

\n\n
import javax.crypto.Cipher;\nimport javax.crypto.spec.SecretKeySpec;\n\nimport org.apache.commons.codec.binary.Base64;\n\n\npublic class Test {\n\n    private static String strkey ="Blowfish";\n    private static Base64 base64 = new Base64(true);\n\n     //encrypt using blowfish algorithm\n    public static String encrypt(String Data)throws Exception{\n\n        SecretKeySpec key = new SecretKeySpec(strkey.getBytes("UTF8"), "Blowfish");\n         Cipher cipher = Cipher.getInstance("Blowfish");\n         cipher.init(Cipher.ENCRYPT_MODE, key);\n\n         return base64.encodeToString(cipher.doFinal(Data.getBytes("UTF8")));\n\n    }\n\n    //decrypt using blow fish algorithm\n    public static String decrypt(String encrypted)throws Exception{\n        byte[] encryptedData = base64.decodeBase64(encrypted);\n         SecretKeySpec key = new SecretKeySpec(strkey.getBytes("UTF8"), "Blowfish");\n         Cipher cipher = Cipher.getInstance("Blowfish");\n         cipher.init(Cipher.DECRYPT_MODE, key);\n         byte[] decrypted = cipher.doFinal(encryptedData);\n         return new String(decrypted); \n\n    }\n\n    public static void main(String[] args) throws Exception {\n        String data = "will this work?";\n        String encoded = encrypt(data);\n        System.out.println(encoded);\n        String decoded = decrypt(encoded);\n        System.out.println(decoded);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这能回答您的问题。

\n