2013-02-21 17 views
10

Tüm bunlara son derece yeni olduğumu söyleyerek başlayayım. Yapmaya çalıştığım, şifrelenmiş bir dosyanın şifresini çözmek için Java içinden gpg kullanmaktır.GPG Şifre Çözmeyi Alma Java'da Çalışmak İçin (Bouncy Castle)

başarıyla yaptık Ne:

  • bir meslektaşım benim ortak anahtar ve onun gizli anahtarını kullanarak bir dosyayı şifrelemek Had ve başarıyla çözdük. (Beklendiği gibi)

Anahtarım böyle oluşturulduğu başarısız ...:

  • başka meslektaşım onun için değildi bir dosyanın şifresini deneyin olsaydı başka bir yol
  • gitti

    gpg --gen-ley

    (gpg version Ben 1.4.5 kullanıyorum ve Bouncy Castle 1.47 kullanıyorum söylüyor)

    "DSA ve Elgamal (varsayılan)" seçeneğini seçin.

    Diğer alanları doldurun ve bir anahtar oluşturun.

    Dosya, ortak anahtarım ve başka bir gizli anahtar kullanılarak şifrelenmiştir. Şifresini çözmek istiyorum. Bunu gerçekleştirmek için aşağıdaki Java kodunu yazdım. Bazı kullanım dışı yöntemleri kullanıyorum, ancak kullanım dışı sürümleri kullanmak için gereken fabrika yöntemlerini düzgün bir şekilde nasıl uygulayacağımı anlayamıyorum. güzel bonus.

    Algoritma: DSA Biçimi: Bu kodu çalıştırdığınızda

    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"); 
    

    Yani benim gizli anahtar için aşağıdaki gibi benim algoritma ve format olduğunu öğrenmek PKCS 8.

    Ve sonra üzerine kırılır son satır:

    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) 
    

    neden Olduğu: java.security.InvalidKeyException: org.bouncyc de ElGamal'ın geçirilen bilinmeyen anahtar türü org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit (Bilinmeyen Kaynak) at javax.crypto.Cipher.init (DashoA13 *) ..) javax.crypto.Cipher.init (DashoA13 * ..) ... en 8 daha

    gpg kullanmayın" dan ben, burada önerilerden bir çok açığım x yerine kullanılacak "Kaleye" kale kullanmayın, yerine x yerine "kullanın. Teşekkürler!

  • cevap

    2

    :

    Sana (ayrıca, secretKeyRing muhtemelen secretKeyRingCollection olarak yeniden adlandırıldı olmalıdır) böyle bir şey istediğini düşünüyorum Kale tamamen ve sadece bir çalışma zamanı işlemi kullanın. Benim için bu çözüm çalışıyor ve tamamen kabarık kale çevresindeki karmaşıklığını kaldırır: bağlı olarak işlem execing veya program muhtemelen asmak gibi ne kadar üzerinde giriş akışı boşalmasına hatırlamak gerektiğini yaptıktan sonra

    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())); 
    

    sen Çıkıyor. Biraz daha bağlam için bu konudaki cevabımı (ve aynı zamanda beni doğru yola çıkaran Cameron Wilson'ınki gibi) bakın: Calling GnuPG in Java via a Runtime Process to encrypt and decrypt files - Decrypt always hangs

    +1

    +1 Ewwwwwwwwww;) –

    +9

    -1 Açık nedenlerle. Ayrıca, parolanız, arama sırasında etkin işlemler listesine bakan herkes tarafından görülebilir ve sistem günlüğüne de girebilir. – user359996

    1

    İlk Google sonucu this'dir. ElGamal verilerini deşifre etmeye çalışıyorsunuz gibi görünüyor, ancak bir ElGamal anahtarında geçmiyorsunuz.

    • Sizin anahtarlık koleksiyonu birden anahtarlıklar vardır:

      İki kolay olasılık vardır.

    • Anahtarlığınızda alt anahtarlar var.

    ElGamal şifrelemesiyle DSA'yı seçtiniz, en azından ikincisinden şüpheleniyorum: Alt anahtarlar ana anahtar tarafından imzalanır; ElGamal bir imzalama algoritması değildir (DSA ve ElGamal'ın aynı anahtarı kullanıp kullanamayacağını bilmiyorum, ancak genellikle farklı amaçlarla farklı anahtarlar kullanmak iyi bir fikir olarak görülüyor). Ben bouncy kullanımını vazgeçmek için çok daha farklı bir yaklaşım ile gitmeye karar verdik

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

    Yanıt için teşekkürler. Adlandırmaya katılıyorum. Anahtarımın kesinlikle bir alt anahtarı var (en azından gpg - liste tuşlarını kullanarak baktığımda). Ama kesinlikle komut satırında kullanarak şifresini çözebilirim. Burada ne var? – Craig

    +0

    ElGamal anahtar alt anahtar mı? –

    +0

    Merhaba tc. Java'da gpg şifre çözme için farklı bir yaklaşımla gitmeye karar verdim. Yanıtı gerçekten takdir ediyorum ama benim için aşağıda bir cevapta detaylandırdığım daha kolay bir çözüm var. – Craig

    7

    Herhangi biri, gpg dosyalarını nasıl boğularak şifrelemeyi ve şifresini çözmeyi öğrenmek istiyorsa ihtiyacınız olacak 4 yöntemlerdir aşağıda

    : kale openpgp kütüphane, aşağıdaki java kodunu kontrol

    aşağıda yöntem okuyup .asc dosyasından gizli anahtarınızı ithal edecek:

    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; 
    } 
    

    The bel

    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(); 
        } 
    
    Şimdi burada

    /çağırmak yukarıda açıklandığı gibi çalıştırılabilir: 2 şifresini çözmek için yöntem ve şifrelemek gpg dosyaların altında

    @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; 
        } 
    

    : ow yöntem okuyup .asc dosyadan ortak anahtarınızı ithal edecek: alternatif bir çözüm arayan birine için

    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()); 
         } 
    
    İlgili konular