title: How to use bouncycastle opengpg encryptFile,sign and decrypt
body: <p>At First,please forgive my poor English level。And thanks for your solution!</p>
  
  <p>I am new with bouncycastle。 I have succssed used it creating PGPkeypair ，get PGPPublickKey and secretKey 。I also use  secretKey to encrypt a txt file，but I can't signed and decrypt it 。My codes are almost from the org.bouncycastle.openpgp.example and I dont know where the problem is
  Here is my codes:</p>
  
  <p>1,Create PGPKeyPair and get PGPPublickey,secretKey and save them:</p>
  
  <pre><code>public static PGPPublicKey generateKeyPair() throws Exception {
  
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "BC");
      keyGen.initialize(1024, new SecureRandom());
      int algorithm = PGPPublicKey.RSA_GENERAL;
      PGPKeyPair pkp=new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), new Date());
  
  
      Security.addProvider(new BouncyCastleProvider());
      Security.addProvider(new BouncyCastlePQCProvider());
      // 生成RSA密钥对
      KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
      kpg.initialize(4096);
      KeyPair kp = kpg.generateKeyPair();
      // 转为PGP密钥对
      JcaPGPKeyPair pgpKeyPair = new JcaPGPKeyPair(PGPPublicKey.RSA_GENERAL,
              kp, new Date());
      // 用户标识一般使用email
      String identity = "fad@163.com";
      // 用来保护密钥的密码
      char[] passPhrase = "123456".toCharArray();
      PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder()
              .build().get(HashAlgorithmTags.SHA1);
      PGPContentSignerBuilder certSignerBuilder = new JcaPGPContentSignerBuilder(
              pgpKeyPair.getPublicKey().getAlgorithm(),
              HashAlgorithmTags.SHA1);
      PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
              SymmetricKeyAlgorithmTags.AES_256, sha1Calc,0x90).setProvider("BC").build(
              passPhrase);
      // 生成PGP密钥
      PGPSecretKey secretKey = new PGPSecretKey(
              PGPSignature.DEFAULT_CERTIFICATION, pgpKeyPair, identity,
              sha1Calc, null, null, certSignerBuilder, keyEncryptor);
  
      // 保存PGP密钥到asc文件
      File externalStorageDirectory = Environment
              .getExternalStorageDirectory();
      String path = externalStorageDirectory.toString();
      OutputStream secretOut = new ArmoredOutputStream(new FileOutputStream(
              path + "/SecretKey.asc"));
      secretKey.encode(secretOut);
      secretOut.close();
      // 保存PGP公钥到asc文件
      OutputStream publicOut = new ArmoredOutputStream(new FileOutputStream(
              path + "/PublicKey.asc"));
      PGPPublicKey key = secretKey.getPublicKey();
      key.encode(publicOut);
      publicOut.close();
      return key;
  }
  </code></pre>
  
  <p>2,Use SignedFileProcessor.java to encrypt file and decryptfile:</p>
  
  <pre><code>public class KeyBasedLargeFileProcessor{
  public static void decryptFile(
      String inputFileName,
      String keyFileName,
      char[] passwd,
      String defaultFileName)
      throws IOException, NoSuchProviderException
  {
      InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
      InputStream keyIn = new BufferedInputStream(new                                         FileInputStream(keyFileName));
      decryptFile(in, keyIn, passwd, defaultFileName);
      keyIn.close();
      in.close();
  }
  
  /**
   * decrypt the passed in message stream
   */
  public static void decryptFile(
      InputStream in,
      InputStream keyIn,
      char[]      passwd,
      String      defaultFileName)
      throws IOException, NoSuchProviderException
  {    
      in = PGPUtil.getDecoderStream(in);
  
      try
      {
          PGPObjectFactory        pgpF = new PGPObjectFactory(in);
          PGPEncryptedDataList    enc;
  
          Object                  o = pgpF.nextObject();
          //
          // the first object might be a PGP marker packet.
          //
          if (o instanceof PGPEncryptedDataList)
          {
              enc = (PGPEncryptedDataList)o;
          }
          else
          {
              enc = (PGPEncryptedDataList)pgpF.nextObject();
          }
  
          //
          // find the secret key
          //
          Iterator                    it = enc.getEncryptedDataObjects();
          PGPPrivateKey               sKey = null;
          PGPPublicKeyEncryptedData   pbe = null;
          PGPSecretKeyRingCollection  pgpSec = new PGPSecretKeyRingCollection(
              PGPUtil.getDecoderStream(keyIn));                                                                 
  
          while (sKey == null &amp;&amp; it.hasNext())
          {
              pbe = (PGPPublicKeyEncryptedData)it.next();
  
              sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
          }
  
          if (sKey == null)
          {
              throw new IllegalArgumentException("secret key for message not found.");
          }
  
          InputStream         clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
  
          PGPObjectFactory    plainFact = new PGPObjectFactory(clear);
  
          PGPCompressedData   cData = (PGPCompressedData)plainFact.nextObject();
  
          InputStream         compressedStream = new BufferedInputStream(cData.getDataStream());
          PGPObjectFactory    pgpFact = new PGPObjectFactory(compressedStream);
  
          Object              message = pgpFact.nextObject();
  
          if (message instanceof PGPLiteralData)
          {
              PGPLiteralData ld = (PGPLiteralData)message;
  
              String outFileName = ld.getFileName();
              if (outFileName.length() == 0)
              {
                  outFileName = defaultFileName;
              }
  
              InputStream unc = ld.getInputStream();
              OutputStream fOut =  new BufferedOutputStream(new FileOutputStream(outFileName));
  
              Streams.pipeAll(unc, fOut);
  
              fOut.close();
          }
          else if (message instanceof PGPOnePassSignatureList)
          {
              throw new PGPException("encrypted message contains a signed message - not literal data.");
          }
          else
          {
              throw new PGPException("message is not a simple encrypted file - type unknown.");
          }
  
          if (pbe.isIntegrityProtected())
          {
              if (!pbe.verify())
              {
                  System.err.println("message failed integrity check");
              }
              else
              {
                  System.err.println("message integrity check passed");
              }
          }
          else
          {
              System.err.println("no message integrity check");
          }
      }
      catch (PGPException e)
      {
          System.err.println(e);
          if (e.getUnderlyingException() != null)
          {
              e.getUnderlyingException().printStackTrace();
          }
      }
  }
  
  public static void encryptFile(
      String          outputFileName,
      String          inputFileName,
      String          encKeyFileName,
      boolean         armor,
      boolean         withIntegrityCheck)
      throws IOException, NoSuchProviderException, PGPException
  {
      OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
      PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);
      encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
      out.close();
  }
  
  public static void encryptFile(
      OutputStream    out,
      String          fileName,
      PGPPublicKey    encKey,
      boolean         armor,
      boolean         withIntegrityCheck)
      throws IOException, NoSuchProviderException
  {    
      if (armor)
      {
          out = new ArmoredOutputStream(out);
      }
  
      try
      {    
          PGPEncryptedDataGenerator   cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_256).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
  
          cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
  
          OutputStream                cOut = cPk.open(out, new byte[1 &lt;&lt; 16]);
  
          PGPCompressedDataGenerator  comData = new PGPCompressedDataGenerator(
                                                                  PGPCompressedData.ZIP);
  
          PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 &lt;&lt; 16]);
  
          comData.close();
  
          cOut.close();
  
          if (armor)
          {
              out.close();
          }
      }
      catch (PGPException e)
      {
          System.err.println(e);
          if (e.getUnderlyingException() != null)
          {
              e.getUnderlyingException().printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>3,Here are my test code:
      private void test() {</p>
  
  <pre><code>    File storageDirectory = Environment.getExternalStorageDirectory();
      final String opath = storageDirectory.toString();
      final File publcKeyFile = new File(storageDirectory, "PublicKey.asc");
      if(!publcKeyFile.exists()){
          try {
              OpenGPGUtil.generateKeyPair();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }else {
          System.out.println("密钥存在");
      }
      final File secretKeyFile = new File(storageDirectory, "SecretKey.asc");
      final File enFile = new File(storageDirectory, "s.txt");
      final File file = new File(storageDirectory, "x.txt");
      final File deFile = new File(storageDirectory, "ss.txt");
      final String publcKeyfilePath = publcKeyFile.toString();
      final String secretKeyFilePath = secretKeyFile.toString();
      final String enFilePath = enFile.toString();
      final String filePath = file.toString();
      final String deFilePath = deFile.toString();
  
      new Thread(new Runnable() {
  
          @Override
          public void run() {
              try {
                  KeyBasedLargeFileProcessor.encryptFile(enFilePath,
                          filePath, publcKeyfilePath, true, true);
  //                  KeyBasedLargeFileProcessor.decryptFile(enFilePath,
  //                          secretKeyFilePath, "123456".toCharArray(),
  //                          deFilePath);
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }).start();
  }
  </code></pre>
  
  <p>Here are three line annotation，if I erase them Eclipse's logcat will show:</p>
  
  <pre><code>/System.err(7498): java.io.FileNotFoundException: 
  /x.txt: open failed: EROFS (Read-only file system)
  System.err(7498):   at libcore.io.IoBridge.open(IoBridge.java:409)
  System.err(7498):   at java.io.FileOutputStream
  &lt;init(FileOutputStream.java:88)
  System.err(7498):   at java.io.FileOutputStream
  .&lt;init&gt; (FileOutputStream.java:128)
  System.err(7498):   at java.io.FileOutputStream
  .&lt;init&gt;(FileOutputStream.java:117)
  System.err(7498):   at com.example.opengpgs.KeyBasedLargeFileProcessor.
  decryptFile(KeyBasedLargeFileProcessor.java:147)
  System.err(7498):   at  com.example.opengpgs.KeyBasedLargeFileProcessor
  .decryptFile(KeyBasedLargeFileProcessor.java:69)
  System.err(7498):   at com.example.opengpgs.MainActivity$1.
  run(MainActivity.java:62)
  System.err(7498):   at java.lang.Thread.run(Thread.java:841)
  System.err(7498): Caused by: libcore.io.ErrnoException: 
  open failed:  EROFS (Read-only file system)
  System.err(7498):   at libcore.io.Posix.open(Native Method)
  System.err(7498):   at libcore.io.BlockGuardOs.
  open(BlockGuardOs.java:110)
  System.err(7498):   at libcore.io.IoBridge.open(IoBridge.java:393)
  System.err(7498):   ... 7 more
  IInputConnectionWrapper(7498): getCursorCapsMode on 
  inactive   InputConnection
  </code></pre>