我试图制作一个加密工具,我想加密字符串,保存在数据库中然后解密,我正在使用TextEncryptor可查询的弹簧安全加密模块,因为我想使用其余的apiKey,但是我不能可以。
这是我的代码:
import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.security.crypto.keygen.KeyGenerators;
public class CryptoUtil {
public static String encrypt(String plain, String password) {
String salt = KeyGenerators.string().generateKey();
TextEncryptor textEncryptor = Encryptors.queryableText(password, salt);
return textEncryptor.encrypt(plain);
}
public static String decrypt(String encrypted, String password) {
String salt = KeyGenerators.string().generateKey();
TextEncryptor textEncryptor = Encryptors.queryableText(password, salt);
return textEncryptor.decrypt(encrypted);
}
}
----------------------------------------------------
public static void main(String[] args) {
String password = "password";
String plain = "hello";
String encrypted = CryptoUtil.encrypt(plain,password);`enter code here`
String decrypted = CryptoUtil.decrypt(encrypted, password);
}
----------------------------------------------------
Exception in thread "main" java.lang.IllegalStateException: Unable to invoke Cipher due to bad padding
at org.springframework.security.crypto.encrypt.CipherUtils.doFinal(CipherUtils.java:142)
at org.springframework.security.crypto.encrypt.AesBytesEncryptor.decrypt(AesBytesEncryptor.java:128)
at org.springframework.security.crypto.encrypt.HexEncodingTextEncryptor.decrypt(HexEncodingTextEncryptor.java:40)
at com.ind.app.util.CryptoUtil.decrypt(CryptoUtil.java:18)
at com.ind.app.Test.main(UsuarioTest.java:11)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:966)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:824)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:436)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at org.springframework.security.crypto.encrypt.CipherUtils.doFinal(CipherUtils.java:135)
... 4 more
答案 0 :(得分:0)
对于有同样问题的任何人:
字符串盐= KeyGenerators.string()。generateKey();
每次根据文档调用此行:
创建一个StringKeyGenerator,对长度为8个字节的SecureRandom密钥进行十六进制编码。十六进制编码的字符串是keyLength * 2个字符的长度。
因此盐是随机的,例如: plain :“你好” 密码:“密码” 盐:“ e606bfd5cf9f198e”
已加密:“ 60e0e953841ca708b74ac657735a2236076f0a614ec85548d163fadf91e2be8f”
然后,当我尝试解密并得到纯文本时,该方法会生成另一种(随机)盐,因此 TextEncryptor.decrypt(字符串加密)无法正确解密,因为盐不是一样。
Encryptors.queryableText(字符序列密码,字符序列盐)
为使用标准格式的可查询文本字符串创建加密器 基于密码的加密。使用16字节全零初始化 向量,因此加密相同的数据会导致相同的加密 结果。这样做是为了允许查询加密的数据。 加密的文本是十六进制编码的。
CryptoUtil用于加密和解密纯字符串, 不建议用于密码 ,但是对于api密钥很有用。
public class CryptoUtil {
private static final String salt = "e606bfd5cf9f198e"; //any random generated salt
public static String encrypt(String plain, String password) {
TextEncryptor textEncryptor = Encryptors.queryableText(password, salt);
return textEncryptor.encrypt(plain);
}
public static String decrypt(String encrypted, String password) {
TextEncryptor textEncryptor = Encryptors.queryableText(password, salt);
return textEncryptor.decrypt(encrypted);
}
}