Java 在Unix上使用Bouncycastle的OpenPgp加密速度非常慢

Java 在Unix上使用Bouncycastle的OpenPgp加密速度非常慢,java,bouncycastle,openpgp,Java,Bouncycastle,Openpgp,我正在使用(bcpg-jdk16-145.jar、bcprov-jdk16-145.jar)jar文件对一个12GB的文本文件进行签名和加密。文件将在Windows Vista jdk 1.6中加密和签名大约18分钟。但当我尝试在LINUX/UNIX系统上加密它时,进程将变得非常缓慢,我需要1到1:30小时。请建议 签署文件的代码如下所示: private static void signFile(String fileName, InputStream keyIn, Outpu

我正在使用(bcpg-jdk16-145.jar、bcprov-jdk16-145.jar)jar文件对一个12GB的文本文件进行签名和加密。文件将在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();
}

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

PGP将使用一个安全散列,在Java中它可能依赖于SecureRandom。Linux(而不是Windows)中SecureRandom的默认源是/dev/random

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


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

请发布您正在使用的-jmx等标志/设置。两个系统的IO/CPU/内存性能是否相同?两台机器都有默认的VM设置。我要传递的缓冲区大小是2000字节。当我增加缓冲区大小时,Windows 7系统的性能甚至下降,那么系统本身的性能又如何呢?您是否运行了性能测试来比较两个系统(或者在同一台机器上比linux更好地启动windows)?您忽略了
fIn.read(byteArray)
的返回值。忽略速度问题,该代码的结果很可能完全是垃圾,因为对
fIn.read(byteArray)
的调用不能保证准确读取
byteArray.length
字节,但将整个数组传递给
lOut.write()
sGen.update()
。除了@OlegEstekhin的注释之外,尝试使用BufferedInputStream而不是FileInputStream。请推荐一些不使用/dev/random和SecureRandom的开源API。您可以设置提供程序和种子(例如:)。然而,任何严肃的加密库都不会这样做,因为它不是生成随机性的可靠方法。安装haveged是您最简单的选择。谢谢您完成。不幸的是,haveged不支持Sun sparc体系结构。是否有其他选项可能有一种方法可以将BouncyCastle配置为使用/dev/uradom,但我对它不太熟悉。另一个选项是rngd,它可以从硬件设备向/dev/random提供数据。如果您没有这样的硬件设备,您可以尝试滥用它来使用urandom(类似于“rngd-r/dev/urandom”)。这将增加/dev/random中的熵,即使它现在是伪RNG。