我们正在将一些加密合并到我们的URL生成器中,在测试过程中,我注意到以下步骤使程序挂起了一段时间。
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
这是调用该函数的一部分,一旦到达该行,它就会挂起,并可能需要2分钟以上的时间才能通过。想知道是否有人知道原因或解决方案。
public static String encrypt(String toEncrypt) throws Exception
{
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
byte[] encryptedValue = Base64.encodeBase64(encrypted);
return new String(encryptedValue);
}
谢谢,
最佳答案
Security.addProvider(new BouncyCastleProvider());
因此,对于每个要加密的字符串,您都需要创建一个新的安全提供程序。您会为每个Web请求启动一个新的Web服务器吗?要编辑文件时,您会购买一台新计算机吗?
我并不是说这行是罪魁祸首,但是每次都进行所有初始化都是不对的。
删除静态(*),使用单例(最好是来自Guice或类似工具),将其初始化一次。您的加密应如下所示
根据@apangin和@IlmariKaronen的评论进行修复。
static {
// This really should be done just once.
// Moreover, you most probably don't need it.
Security.addProvider(new BouncyCastleProvider());
}
Encryptor() {
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IVBytes));
}
public synchronized String encrypt(String toEncrypt) throws Exception {
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes("UTF-8"));
byte[] encryptedValue = Base64.encodeBase64(encrypted);
return new String(encryptedValue);
}
由于加密本身非常快,而且您只加密短字符串,因此使用
synchronized
应该可以很好地工作。另外,也可以使用线程本地cipher
或类似名称。请注意,重用
IV
使其不安全。但这是另一个故事。(*)与性能无关,但这是一件好事。
关于java - 密码加密明显很慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39798728/