尝试使用导出的公共密钥进行加密时,bouncy-gpg BouncyCastle PGP GPG Java API NullPointerException

时间:2020-09-11 19:04:44

标签: java bouncycastle gnupg pgp

我正在尝试将Bouncy-gpg库与BouncyCastle一起用于Java程序中的PGP加密。我不断得到以下NPE。 我们在Linux机器上有一个名为gpg的shell脚本,我想将该逻辑移到Windows上的Java应用程序中。我从Linux上的密钥环中导出了公共密钥,并尝试在Windows上使用它,但是我总是收到以下错误。我尝试了各种不同的密钥,格式和API选项的各种变体,但无法使用此密钥进行加密。我生成的密钥对可以正常工作。

这是我根据https://github.com/neuhalje/bouncy-gpg/blob/master/examples/encrypt/src/main/java/name/neuhalfen/projects/crypto/bouncycastle/openpgp/example/EncryptMain.java

编写的方法
  /**
   * Encypt the output file using gpg
   */
  public void encryptFile() {
    Path sourceFile = Paths.get(this.filePath());
    Path destFile = Paths.get(this.encryptedFilePath());
    try {
      BouncyGPG.registerProvider();

      int bufferSize = 8 * 1024;

      InMemoryKeyring keyringConfig = KeyringConfigs.forGpgExportedKeys(KeyringConfigCallbacks.withUnprotectedKeys());

      try {
      
 
 keyringConfig.addPublicKey(Files.readAllBytes(Paths.get("c:/path/to/my/exported.key"));
      } catch ( Exception e ) {
        throw new RuntimeException(e);
      }
      try (
          OutputStream fileOutput = Files.newOutputStream(destFile);
          BufferedOutputStream bufferedOut = new BufferedOutputStream(fileOutput, bufferSize);

          OutputStream outputStream = BouncyGPG
              .encryptToStream()
              .withConfig(keyringConfig)
              .withStrongAlgorithms()
              .toRecipient(recipient)
              .andDoNotSign()
              .binaryOutput()
              .andWriteTo(bufferedOut);

          InputStream is = Files.newInputStream(sourceFile)
          ) {
        Streams.pipeAll(is, outputStream);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

这是异常的堆栈跟踪:

Caused by: java.lang.NullPointerException
    at name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.generation.KeyFlag.extractPublicKeyFlags(KeyFlag.java:106)
    at name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.callbacks.Rfc4880KeySelectionStrategy.isEncryptionKey(Rfc4880KeySelectionStrategy.java:228)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
    at java.util.ArrayList$Itr.forEachRemaining(ArrayList.java:891)
    at java.util.Collections$UnmodifiableCollection$1.forEachRemaining(Collections.java:1049)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
    at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1548)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
    at name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.callbacks.Rfc4880KeySelectionStrategy.selectPublicKey(Rfc4880KeySelectionStrategy.java:156)
    at name.neuhalfen.projects.crypto.bouncycastle.openpgp.BuildEncryptionOutputStreamAPI$WithAlgorithmSuiteImpl$ToImpl.extractValidKey(BuildEncryptionOutputStreamAPI.java:411)
    at name.neuhalfen.projects.crypto.bouncycastle.openpgp.BuildEncryptionOutputStreamAPI$WithAlgorithmSuiteImpl$ToImpl.toRecipient(BuildEncryptionOutputStreamAPI.java:431) ...

发生NPE的bouncy-gpg中的代码块。 hashedSubPackets变量为空:

    while (directKeySignatures.hasNext()) {
      final PGPSignature signature = directKeySignatures.next();
      final PGPSignatureSubpacketVector hashedSubPackets = signature.getHashedSubPackets();

      final int keyFlags = hashedSubPackets.getKeyFlags(); // <- NPE HERE
      aggregatedKeyFlags |= keyFlags;
    }

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

带有https://github.com/neuhalje/bouncy-gpg/issues/48修复程序的最新Bouncy-gpg源代码解决了此问题。我使用导出的公共密钥重试了我的加密方法,并且有效。