2013-02-21 43 views
10

私はこのすべてに非常に新しいと言って始めましょう。私がやろうとしているのは、暗号化されたファイルを解読するためにJavaの中からgpgを使うことです。Javaで動作するGPG復号化を取得する(Bouncy Castle)

私が正常にやった:

  • は、同僚が私の公開鍵と自分の秘密鍵を使用してファイルを暗号化していたし、正常に復号化されました。 (予想通り)

私のキーは、このように生成された失敗...:

  • は、別の同僚が彼のためではなかったファイルを復号化しようとしていた他の方法に
  • を行ってきました

    (GPGの--version私は1.4.5を使用していると私は弾む城1.47を使用していますと言われます)

    のgpg --gen-レイ

    オプション「DSAとElgamal(デフォルト)」を選択

    他のフィールドに入力してキーを生成します。

    ファイルは、自分の公開鍵と別の秘密鍵を使用して暗号化されています。私はそれを解読したい。私はこれを達成するために次のJavaコードを書いています。私は廃止予定のメソッドをいくつか使用していますが、非推奨バージョンを使用するために必要なファクトリメソッドを適切に実装する方法を理解できません。素晴らしいボーナス。

    Security.addProvider(new BouncyCastleProvider()); 
    
         PGPSecretKeyRingCollection secretKeyRing = new PGPSecretKeyRingCollection(new FileInputStream(new File("test-files/secring.gpg"))); 
         PGPSecretKeyRing pgpSecretKeyRing = (PGPSecretKeyRing) secretKeyRing.getKeyRings().next(); 
         PGPSecretKey secretKey = pgpSecretKeyRing.getSecretKey(); 
         PGPPrivateKey privateKey = secretKey.extractPrivateKey("mypassword".toCharArray(), "BC"); 
    
         System.out.println(privateKey.getKey().getAlgorithm()); 
         System.out.println(privateKey.getKey().getFormat()); 
    
         PGPObjectFactory pgpF = new PGPObjectFactory(
        new FileInputStream(new File("test-files/test-file.txt.gpg"))); 
         Object pgpObj = pgpF.nextObject(); 
         PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList) pgpObj; 
    
         Iterator objectsIterator = encryptedDataList.getEncryptedDataObjects(); 
    
         PGPPublicKeyEncryptedData publicKeyEncryptedData = (PGPPublicKeyEncryptedData) objectsIterator.next(); 
         InputStream inputStream = publicKeyEncryptedData.getDataStream(privateKey, "BC"); 
    

    だから私は、私は自分の秘密鍵のために、次のように私のアルゴリズムとフォーマットがあることを学び、このコードを実行する場合:

    アルゴリズム:DSA フォーマット:PKCS#8

    をそしてそれが壊れます最後の行:

    Exception in thread "main" org.bouncycastle.openpgp.PGPException: error setting asymmetric cipher 
    at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder.decryptSessionData(Unknown Source) 
    at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder.access$000(Unknown Source) 
    at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder$2.recoverSessionData(Unknown Source) 
    at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source) 
    at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source) 
    at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source) 
    at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source) 
    at TestBouncyCastle.main(TestBouncyCastle.java:74) 
    

    によって引き起こさ:java.security.InvalidKeyException:org.bouncycでエルガマル に渡された未知のキータイプ(未知のソース) at org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(不明なソース) at javax.crypto.Cipher.init(DashoA13 * ... javax.crypto.Cipher.initで) (DashoA13 * ...) ... 8以上

    私は、GPGを使用していない」から、ここでの提案の多くに開いている代わりにXを使用""弾力のある城を使用しないで、代わりにxを使用する "との間には何かがあります。ありがとう!

  • 答えて

    2

    は、私はあなたが(また、secretKeyRingはおそらくsecretKeyRingCollectionに名前を変更しなければならない)、このような何かをしたいと思います単純にランタイムプロセスを使用するだけです。私にとっては、このソリューションが動作し、完全に弾む城を取り巻く複雑さを削除している:

    String[] gpgCommands = new String[] { 
         "gpg", 
         "--passphrase", 
         "password", 
         "--decrypt", 
         "test-files/accounts.txt.gpg" 
    }; 
    
    Process gpgProcess = Runtime.getRuntime().exec(gpgCommands); 
    BufferedReader gpgOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream())); 
    BufferedReader gpgError = new BufferedReader(new InputStreamReader(gpgProcess.getErrorStream())); 
    

    あなたのプロセスがexecingされたり、あなたのプログラムは、おそらくどのくらいに応じて、ハングアップしますと、あなたの入力ストリームを排出するために覚えておく必要があることを行った後出力しています。 Calling GnuPG in Java via a Runtime Process to encrypt and decrypt files - Decrypt always hangs

    +1

    +1 Ewwwwwwwwww;) –

    +9

    -1明らかな理由から。また、あなたのパスフレーズは、通話中にアクティブなプロセスのリストを見ている人に見えることがあり、システムログにも終わることがあります。 – user359996

    1

    最初のGoogleの結果はthisです。 ElGamalデータを解読しようとしているように見えますが、ElGamalキーを渡すことはありません。

    • 鍵リングコレクションは、複数のキーリングを持っています

      は、2つの簡単な可能性があります。

    • キーリングにはサブキーがあります。

    あなたはElGamal暗号化でDSAを選んだので、少なくとも後者は疑いがあります。サブキーはマスターキーで署名されています。 ElGamalは署名アルゴリズムではありません(DSAとElGamalが同じキーを使用できるかどうかはわかりませんが、異なる目的で異なるキーを使用するのが一般的です)。私が弾むの使用を控えることです多くの異なるアプローチ、一緒に行くことにしました

    PGPSecretKey secretKey = secretKeyRing.getSecretKey(publicKeyEncryptedData.getKeyID()); 
    
    +0

    お返事ありがとうございます。私は命名に同意します。私の鍵は間違いなくサブ鍵を持っています(少なくともgpg --list-keysを使って見ると鍵です)。しかし、私は確かにコマンドラインでそれを使用して解読することができます。私はここで何をしゃべっていますか? – Craig

    +0

    ElGamalキーはサブキーですか? –

    +0

    こんにちは。私はjavaでgpgの解読のための別のアプローチに行くことに決めました。私は本当に応答を感謝しますが、私のために、私は以下の答えで詳しく述べる簡単な解決策があります。 – Craig

    7

    バネを使ってgpgファイルを暗号化して解読する方法を知りたい人は誰でも(私の答えは適切なパスで私を得たCameron SkinnerとMatthew Wilsonの私の答えを参照してください)あなたが必要として4つの方法があり、以下の

    :城OpenPGPのライブラリには、以下のJavaコードをチェックし

    以下の方法が読むと.ASCファイルから秘密鍵をインポートします:

    public static PGPSecretKey readSecretKeyFromCol(InputStream in, long keyId) throws IOException, PGPException { 
        in = PGPUtil.getDecoderStream(in); 
        PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in, new BcKeyFingerprintCalculator()); 
    
        PGPSecretKey key = pgpSec.getSecretKey(keyId); 
    
        if (key == null) { 
         throw new IllegalArgumentException("Can't find encryption key in key ring."); 
        } 
        return key; 
    } 
    

    ベルOW方法は.ASCファイルから公開鍵を読み、インポートします:ザ・2つの方法下記

    @SuppressWarnings("rawtypes") 
        public static PGPPublicKey readPublicKeyFromCol(InputStream in) throws IOException, PGPException { 
         in = PGPUtil.getDecoderStream(in); 
         PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in, new BcKeyFingerprintCalculator()); 
         PGPPublicKey key = null; 
         Iterator rIt = pgpPub.getKeyRings(); 
         while (key == null && rIt.hasNext()) { 
          PGPPublicKeyRing kRing = (PGPPublicKeyRing) rIt.next(); 
          Iterator kIt = kRing.getPublicKeys(); 
          while (key == null && kIt.hasNext()) { 
           PGPPublicKey k = (PGPPublicKey) kIt.next(); 
           if (k.isEncryptionKey()) { 
            key = k; 
           } 
          } 
         } 
         if (key == null) { 
          throw new IllegalArgumentException("Can't find encryption key in key ring."); 
         } 
         return key; 
        } 
    

    をGPGファイルを復号化し、暗号化するには:今ここに

    public void decryptFile(InputStream in, InputStream secKeyIn, InputStream pubKeyIn, char[] pass) throws IOException, PGPException, InvalidCipherTextException { 
         Security.addProvider(new BouncyCastleProvider()); 
    
         PGPPublicKey pubKey = readPublicKeyFromCol(pubKeyIn); 
    
         PGPSecretKey secKey = readSecretKeyFromCol(secKeyIn, pubKey.getKeyID()); 
    
         in = PGPUtil.getDecoderStream(in); 
    
         JcaPGPObjectFactory pgpFact; 
    
    
         PGPObjectFactory pgpF = new PGPObjectFactory(in, new BcKeyFingerprintCalculator()); 
    
         Object o = pgpF.nextObject(); 
         PGPEncryptedDataList encList; 
    
         if (o instanceof PGPEncryptedDataList) { 
    
          encList = (PGPEncryptedDataList) o; 
    
         } else { 
    
          encList = (PGPEncryptedDataList) pgpF.nextObject(); 
    
         } 
    
         Iterator<PGPPublicKeyEncryptedData> itt = encList.getEncryptedDataObjects(); 
         PGPPrivateKey sKey = null; 
         PGPPublicKeyEncryptedData encP = null; 
         while (sKey == null && itt.hasNext()) { 
          encP = itt.next(); 
          secKey = readSecretKeyFromCol(new FileInputStream("PrivateKey.asc"), encP.getKeyID()); 
          sKey = secKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass)); 
         } 
         if (sKey == null) { 
          throw new IllegalArgumentException("Secret key for message not found."); 
         } 
    
         InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey)); 
    
         pgpFact = new JcaPGPObjectFactory(clear); 
    
         PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject(); 
    
         pgpFact = new JcaPGPObjectFactory(c1.getDataStream()); 
    
         PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); 
         ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 
    
         InputStream inLd = ld.getDataStream(); 
    
         int ch; 
         while ((ch = inLd.read()) >= 0) { 
          bOut.write(ch); 
         } 
    
         //System.out.println(bOut.toString()); 
    
         bOut.writeTo(new FileOutputStream(ld.getFileName())); 
         //return bOut; 
    
        } 
    
        public static void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey) throws IOException, NoSuchProviderException, PGPException { 
         Security.addProvider(new BouncyCastleProvider()); 
    
         ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 
    
         PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); 
    
         PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName)); 
    
         comData.close(); 
    
         PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES).setSecureRandom(new SecureRandom())); 
    
         cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey)); 
    
         byte[] bytes = bOut.toByteArray(); 
    
         OutputStream cOut = cPk.open(out, bytes.length); 
    
         cOut.write(bytes); 
    
         cOut.close(); 
    
         out.close(); 
        } 
    

    は、上記を実行する/起動する方法です。別の解決策を探しているいずれかに

    try { 
          decryptFile(new FileInputStream("encryptedFile.gpg"), new FileInputStream("PrivateKey.asc"), new FileInputStream("PublicKey.asc"), "yourKeyPassword".toCharArray()); 
    
          PGPPublicKey pubKey = readPublicKeyFromCol(new FileInputStream("PublicKey.asc")); 
    
          encryptFile(new FileOutputStream("encryptedFileOutput.gpg"), "fileToEncrypt.txt", pubKey); 
    
    
    
    
         } catch (PGPException e) { 
          fail("exception: " + e.getMessage(), e.getUnderlyingException()); 
         } 
    
    関連する問題