密码加密明显缓慢

时间:2016-09-30 19:24:45

标签: java performance encryption

我们正在将一些加密技术加入到我们的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);
  }

谢谢,

1 个答案:

答案 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会使其不安全。但这是另一个故事。

(*)这与表现无关,但是一件好事。