我们正在将一些加密技术加入到我们的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);
}
谢谢,
答案 0 :(得分:3)
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
会使其不安全。但这是另一个故事。
(*)这与表现无关,但是一件好事。