【问题标题】:OpenPgp encryption using Bouncycastle very slow on Unix在 Unix 上使用 Bouncycastle 的 OpenPgp 加密非常慢
【发布时间】:2014-05-10 15:28:53
【问题描述】:

我正在使用 (bcpg-jdk16-145.jar , bcprov-jdk16-145.jar) jar 文件对 12 GB 的文本文件进行签名和加密。在 Windows Vista、jdk 1.6 中,文件将被加密和签名大约 18 分钟。但是当我尝试在 LINUX/UNIX 系统上加密它时,系统进程会变得非常慢,我需要 1 到 1:30 小时。请建议。

文件签名代码如下:

private static void signFile(String fileName, InputStream keyIn,
        OutputStream out, char[] pass, boolean armor, int bufferSize)
        throws IOException, NoSuchAlgorithmException,
        NoSuchProviderException, PGPException, SignatureException {
    if (armor) {
        out = new ArmoredOutputStream(out);
    }
    PGPSecretKey pgpSec = readSecretKey(keyIn);
    PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(pass, "BC");
    PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec
            .getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC");
    sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
    Iterator it = pgpSec.getPublicKey().getUserIDs();
    if (it.hasNext()) {
        PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
        spGen.setSignerUserID(false, (String) it.next());
        sGen.setHashedSubpackets(spGen.generate());
    }
    PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
            PGPCompressedData.ZLIB);
    BCPGOutputStream bOut = new BCPGOutputStream(cGen.open(out));
    sGen.generateOnePassVersion(false).encode(bOut);
    File file = new File(fileName);
    PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
    OutputStream lOut = lGen.open(bOut, PGPLiteralData.BINARY, file);
    FileInputStream fIn = new FileInputStream(file);
    byte[] byteArray = new byte[bufferSize];
    while (fIn.read(byteArray) >= 0) {
        lOut.write(byteArray);
        sGen.update(byteArray);
    }
    lGen.close();

    sGen.generate().encode(bOut);

    cGen.close();

    out.close();
}

【问题讨论】:

  • 请发布您正在使用的 -jmx 等标志/设置。两个系统的 IO/CPU/内存性能是否相同?
  • 两台机器都有默认的虚拟机设置。我要传递的缓冲区大小是 2000 字节。当我增加缓冲区大小时,Windows 7 系统的性能甚至会下降
  • 那么系统本身的性能呢?您是否运行了性能测试以比较两个系统(或者在同一台机器上比 linux 更好地启动第一个窗口)?
  • 您忽略了fIn.read(byteArray) 的返回值。忽略速度问题,该代码的结果很有可能是完全垃圾,因为不能保证对 fIn.read(byteArray) 的调用可以准确读取 byteArray.length 字节,但是您将整个数组传递给 lOut.write() 和 @987654326 @.
  • 除了来自 @OlegEstekhin 的 cmets 之外,尝试使用 BufferedInputStream 而不是 FileInputStream。

标签: java bouncycastle openpgp


【解决方案1】:

这是一个有根据的猜测,也许你的 /dev/random 有问题?

PGP 将使用安全哈希,在 Java 中可能依赖 SecureRandom。 Linux(但不是 Windows)中 SecureRandom 的默认来源是 /dev/random。

问题在于,如果 SecureRandom 当前无法满足请求的位数,则 SecureRandom 将阻止等待 /dev/random 收集更多熵。

尝试安装一个名为“haveged”的实用程序(apt-get install 或其他)。它将为您的 linux 系统收集更多熵并防止这种行为。

【讨论】:

  • 能否推荐一些不使用/dev/random的开源API
  • 使用 SecureRandom 您可以设置提供者和种子(例如:stackoverflow.com/questions/13923247/…)。但是,任何严肃的密码库都不会这样做,因为它不是生成随机性的可靠方法。安装 haveged 是您最简单的选择。
  • 谢谢你。不幸的是,haveged 不支持 Sun sparc 架构。还有其他选择吗
  • 可能有一种方法可以将 BouncyCastle 配置为使用 /dev/urandom,但我不是很熟悉。另一个选项是 rngd,它可以向 /dev/random 提供来自硬件设备的数据。如果您没有这样的硬件设备,您可以尝试滥用它来使用 urandom(类似于“rngd -r /dev/urandom”)。即使它现在是一个伪RNG,这也会增加你在 /dev/random 中的熵。
猜你喜欢
  • 2013-09-22
  • 2016-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2020-01-04
  • 1970-01-01
相关资源
最近更新 更多