我们正在将一些加密合并到我们的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/

10-16 21:37