2013-02-21 1 views
10

나는이 모든 것을 극도로 새로운 것이라고 말함으로써 시작하겠습니다. 내가 뭘하려는 건 암호화 된 파일을 해독하기 위해 Java에서 gpg를 사용하는 것입니다.Java (Bouncy Castle)에서 작업하려면 GPG 암호 해독 받기

내가 성공적으로 완료 한 것 :

  • 가 동료가 내 공개 키와 자신의 개인 키를 사용하여 파일을 암호화했고 성공적으로 해독. (예상대로)

내 키는 다음과 같이 생성 된 실패 ... :

  • 다른 동료가 그를 위해 아니었다 파일의 암호를 해독하려고했던 다른 방법을
  • 갔다

    GPG --gen-지맥

    을 (GPG의 --version 내가 1.4.5를 사용하고 있는데 나는 탄력이 성 1.47를 사용하고 알려줍니다)

    "DSA 및 엘가 말 (기본값)"옵션 선택

    다른 필드를 채우고 키를 생성하십시오.

    파일이 내 공개 키와 다른 사람의 비밀 키를 사용하여 암호화되었습니다. 나는 그것을 해독하고 싶다. 이를 수행하기 위해 다음 Java 코드를 작성했습니다. 몇 가지 사용되지 않는 메소드를 사용하고 있지만, 비 deprecated 버전을 사용하는 데 필요한 팩토리 메소드를 올바르게 구현하는 방법을 알 수 없으므로 누구나 사용할 수 있어야하는 구현에 대한 아이디어가 있다면 좋은 보너스.

    알고리즘 : DSA 형식 :이 코드를 실행하면

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

    그래서 나는 나의 비밀 키에 대해 다음과 같이 내 알고리즘과 형식이라는 것을 배울 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에서 엘가 에 전달 알 수없는 키 유형 astle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit (알 수없는 소스) org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit (알 수없는 소스) at javax.crypto.Cipher.init (DashoA13 * ..) javax.crypto.Cipher.init (DashoA13 * ..) ...에서 8 개

    GPG를 사용하지 않는 "에서 내가 여기에서 많은 추천을 열려있어, 배 대신 사용 "성기사를 사용하지 말고 대신 x를 사용하십시오. 감사!

  • 답변

    2

    :

    나는 당신이 (또한, secretKeyRing 아마 secretKeyRingCollection로 변경한다)이 같은 뭔가를 원한다고 생각 성을 모두 사용하고 단순히 런타임 프로세스를 대신 사용하십시오. 나를 위해이 솔루션은 작동하고 완전히 탄력이 성 주변의 복잡성을 제거합니다 따라 프로세스가 execing 또는 프로그램이 아마도 중단됩니다 당신이 얼마나 당신의 입력 스트림을 배출하는 것을 기억 할 필요가 수행 한 후

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

    당신 다시 출력하고있어. 좀 더 문맥 (또한 적절한 경로에 저를 얻었다 카메론 스키너와 매튜 윌슨의 그것과)이 스레드에서 내 대답을 참조하십시오 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 키를 전달하지 않는 것 같습니다.

    • 귀하의 열쇠 고리 수집 여러 열쇠 고리를 가지고 :

      두 쉽게 가능성이 있습니다.

    • 키링에 하위 키가 있습니다.

    ElGamal 암호화로 DSA를 선택 했으므로 적어도 후자는 의심 스럽습니다. 하위 키는 마스터 키로 서명됩니다. ElGamal은 서명 알고리즘이 아닙니다 (DSA와 ElGamal이 동일한 키를 사용할 수 있는지는 모르겠지만 일반적으로 다른 용도로 다른 키를 사용하는 것이 좋습니다). 나는 탄력의 사용을 포기하는 것입니다 매우 다른 접근 방식으로 이동하기로 결정했습니다

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

    응답 해 주셔서 감사합니다. 명명에 동의합니다. 내 열쇠에는 분명히 하위 키가 있습니다 (적어도 gpg --list-keys를 사용할 때). 하지만 명령 행에서 확실히 해독 할 수 있습니다. 여기에 무슨 상관이야? – Craig

    +0

    ElGamal 키가 하위 키입니까? –

    +0

    안녕하세요. 나는 자바에서 gpg 암호 해독을위한 다른 접근법을 선택하기로 결정했다. 나는 정말로 응답을 바르게 평가한다. 그러나 나를 위해 아래 대답에서 자세히 설명 할 더 쉬운 해결책이있다. – Craig

    7

    을 누군가가 암호화하고 탄력을 이용하여 GPG 파일의 암호를 해독하는 방법을 알고 관심이 있다면 당신이 필요로하는 것 4 가지 방법은 아래

    : 성 OpenPGP를 라이브러리는, 아래의 자바 코드를 확인

    아래의 방법을 읽고는 .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; 
    } 
    

    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(); 
        } 
    
    지금 여기

    /호출 위를 실행하는 방법입니다 : 2 개 해독하는 방법과 암호화 GPG 파일 아래

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

    을 : 아야 방법은 읽고는 .asc 파일에서 공개 키를 가져옵니다 : 대안 솔루션을 찾고 어느 한

    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()); 
         } 
    
    관련 문제