gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 07:09:00 24 4
gpt4 key购买 nike

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

错误

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)

这是我的加解密代码

//secret key 8 
private static String strkey ="Blowfish";

已更新

 //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);

}

最佳答案

如果您在 main 方法中运行加密和解密方法,它将起作用。但是如果把encrypt的结果放到一个url中,再对url参数进行解密,就会失败。

加密后,字节数组包含了 URLS 字符集之外的值(非 ascii),所以这个值在被填充到 url 中时会被编码。你会收到一个损坏的解密版本。

例如,当我从一个加密的字节数组创建一个字符串时,它看起来像这样 Ž ¹Qêz¦ 但如果我把它放到一个 URL 中,它就会变成 Ž%0B¹Qêz¦

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

这里有一些关于实现的注释。

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

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

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

  4. 所以你的加密的最后一行会变成类似return base64.encodeToString(cipher.doFinal(Data.getBytes("UTF8")));你现在可以安全地通过url 中的加密值

  5. 在解密时,第一步是解码。所以第一行会变成类似 byte[] encryptedData = base64.decodeBase64(encrypted);

我刚刚使用了您的代码并添加了一些 base 64 的内容,结果如下所示:

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;


public class Test {

private static String strkey ="Blowfish";
private static Base64 base64 = new Base64(true);

//encrypt using blowfish algorithm
public static String 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 base64.encodeToString(cipher.doFinal(Data.getBytes("UTF8")));

}

//decrypt using blow fish algorithm
public static String decrypt(String encrypted)throws Exception{
byte[] encryptedData = base64.decodeBase64(encrypted);
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);

}

public static void main(String[] args) throws Exception {
String data = "will this work?";
String encoded = encrypt(data);
System.out.println(encoded);
String decoded = decrypt(encoded);
System.out.println(decoded);
}
}

希望这能回答您的问题。

关于java - 使用 Blowfish 错误的加密和解密 - 使用填充密码解密时输入长度必须是 8 的倍数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16259118/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com