2014-01-15 11 views
5

私はPGPとそれが動作する方法にはかなり精通しています。私はプロジェクトにいくつかの機能を追加したいと思っていますが、これまでの私の研究では頭が回転していました。私がしたいのは、定義されたプライベートパスフレーズを持つ公開鍵を作成することです。そこから、公開鍵を誰かと共有し、鍵を使ってメッセージを暗号化し、解読できる場所に戻します。私はこのようなコードを考えています。PGPをプロジェクトに統合するAndroid

私のプライベートPGP鍵を生成するには:私に戻って送信された後、暗号化された文字列を復号化するに

String encryptedText = PGPTools.Encrypt("Text to encrypt", getSharedKey()); 

:私は友人に私の共有キーを与えると思い暗号化するには

PGPKey key = new PGPKey(); 
key.setPassPhrase("MySecretPassword!!!1"); 
key.generateRandomSharedKey(); 
key.build(); 

を:

String decryptedText = PGPTools.Decrypt(encryptedText, key, "MySecretPassword!!!1") 

明らかに、私は1トンの細部をスキップしています。私の研究を通して、私はBouncy CastleやSpongy Castleのような図書館への参照を見てきました。どんな助けでも大いに感謝します!

+0

は良い、何のトラブルを検索しますあなたは持っていますか? –

+0

それは聞こえるほど悪いですが、私は正確なコードを多かれ少なかれ探していると思います。私がオンラインで探しているすべてのコード例は、ある方法や別の方法で異なっているか、重要な部分を一切排除しています。 –

+0

OSSの世界へようこそ

答えて

8

A.それはすることは極めて困難であったので、私は私の解決策を投稿したいですこの作業をしてください。B.暗号プロが私のコードを監査したい場合、私は永遠に感謝しています。

私が4つの以下のライブラリが含まれていました。

compile 'com.madgag.spongycastle:core:1.50.0.0' 
compile 'com.madgag.spongycastle:pg:1.50.0.0' 
compile 'com.madgag.spongycastle:pkix:1.50.0.0' 
compile 'com.madgag.spongycastle:prov:1.50.0.0' 

弾む城は、セキュリティプロバイダとして追加する必要があります。私は、このコードを、アプリケーションがロードされるときに他のオブジェクトを初期化するクラスに含めました。

static { 
    Security.addProvider(new BouncyCastleProvider()); 
} 

私が作成したutilsクラスは、実際にナットとボルトが入っています。わずかに編集:

final PGPKeyRingGenerator krgen = PgpUtils.generateKeyRingGenerator("password".toCharArray()); 
String pgpPublicKey = PgpUtils.genPGPPublicKey(krgen); 
String pgpSecretKey = PgpUtils.genPGPPrivKey(krgen); 

そして最後に、あなた自身の公開鍵を使って暗号化と復号化:ここで

import com.example.Device; 

import org.spongycastle.bcpg.ArmoredInputStream; 
import org.spongycastle.bcpg.ArmoredOutputStream; 
import org.spongycastle.bcpg.HashAlgorithmTags; 
import org.spongycastle.bcpg.SymmetricKeyAlgorithmTags; 
import org.spongycastle.bcpg.sig.Features; 
import org.spongycastle.bcpg.sig.KeyFlags; 
import org.spongycastle.crypto.generators.RSAKeyPairGenerator; 
import org.spongycastle.crypto.params.RSAKeyGenerationParameters; 
import org.spongycastle.openpgp.PGPCompressedData; 
import org.spongycastle.openpgp.PGPCompressedDataGenerator; 
import org.spongycastle.openpgp.PGPEncryptedData; 
import org.spongycastle.openpgp.PGPEncryptedDataGenerator; 
import org.spongycastle.openpgp.PGPEncryptedDataList; 
import org.spongycastle.openpgp.PGPException; 
import org.spongycastle.openpgp.PGPKeyPair; 
import org.spongycastle.openpgp.PGPKeyRingGenerator; 
import org.spongycastle.openpgp.PGPLiteralData; 
import org.spongycastle.openpgp.PGPLiteralDataGenerator; 
import org.spongycastle.openpgp.PGPObjectFactory; 
import org.spongycastle.openpgp.PGPPrivateKey; 
import org.spongycastle.openpgp.PGPPublicKey; 
import org.spongycastle.openpgp.PGPPublicKeyEncryptedData; 
import org.spongycastle.openpgp.PGPPublicKeyRing; 
import org.spongycastle.openpgp.PGPSecretKey; 
import org.spongycastle.openpgp.PGPSecretKeyRing; 
import org.spongycastle.openpgp.PGPSignature; 
import org.spongycastle.openpgp.PGPSignatureSubpacketGenerator; 
import org.spongycastle.openpgp.PGPUtil; 
import org.spongycastle.openpgp.operator.PBESecretKeyDecryptor; 
import org.spongycastle.openpgp.operator.PBESecretKeyEncryptor; 
import org.spongycastle.openpgp.operator.PGPDigestCalculator; 
import org.spongycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; 
import org.spongycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder; 
import org.spongycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; 
import org.spongycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; 
import org.spongycastle.openpgp.operator.bc.BcPGPKeyPair; 
import org.spongycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory; 
import org.spongycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; 
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator; 

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.math.BigInteger; 
import java.nio.charset.Charset; 
import java.security.SecureRandom; 
import java.util.Date; 
import java.util.Iterator; 

public class PgpUtils { 
    private static final String PROVIDER = "SC"; 
    private static final String KEY_RING_ID = "[email protected]"; 

    public static String decrypt(String encryptedText, String password) throws Exception { 
     byte[] encrypted = encryptedText.getBytes(); 
     InputStream in = new ByteArrayInputStream(encrypted); 
     in = PGPUtil.getDecoderStream(in); 
     PGPObjectFactory pgpF = new PGPObjectFactory(in); 
     PGPEncryptedDataList enc; 
     Object o = pgpF.nextObject(); 
     if (o instanceof PGPEncryptedDataList) { 
      enc = (PGPEncryptedDataList) o; 
     } else { 
      enc = (PGPEncryptedDataList) pgpF.nextObject(); 
     } 
     PGPPrivateKey sKey = null; 
     PGPPublicKeyEncryptedData pbe = null; 
     while (sKey == null && enc.getEncryptedDataObjects().hasNext()) { 
      pbe = (PGPPublicKeyEncryptedData)enc.getEncryptedDataObjects().next(); 
      sKey = getPrivateKey(getPGPSecretKeyRing(), pbe.getKeyID(), password.toCharArray()); 
     } 
     if (pbe != null) { 
      InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey)); 
      PGPObjectFactory pgpFact = new PGPObjectFactory(clear); 
      PGPCompressedData cData = (PGPCompressedData) pgpFact.nextObject(); 
      pgpFact = new PGPObjectFactory(cData.getDataStream()); 
      PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); 
      InputStream unc = ld.getInputStream(); 
      ByteArrayOutputStream out = new ByteArrayOutputStream(); 
      int ch; 
      while ((ch = unc.read()) >= 0) { 
       out.write(ch); 
      } 
      byte[] returnBytes = out.toByteArray(); 
      out.close(); 
      return new String(returnBytes); 
     } 
     return null; 
    } 

    private static PGPPublicKey getPublicKey(PGPPublicKeyRing publicKeyRing) { 
     Iterator<?> kIt = publicKeyRing.getPublicKeys(); 
     while (kIt.hasNext()) { 
      PGPPublicKey k = (PGPPublicKey) kIt.next(); 
      if (k.isEncryptionKey()) { 
       return k; 
      } 
     } 
     return null; 
    } 

    private static PGPPrivateKey getPrivateKey(PGPSecretKeyRing keyRing, long keyID, char[] pass) throws PGPException { 
     PGPSecretKey secretKey = keyRing.getSecretKey(keyID); 
     PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass); 
     return secretKey.extractPrivateKey(decryptor); 
    } 

    public static String encrypt(String msgText) throws IOException, PGPException { 
     byte[] clearData = msgText.getBytes(); 
     PGPPublicKey encKey = getPublicKey(getPGPPublicKeyRing()); 
     ByteArrayOutputStream encOut = new ByteArrayOutputStream(); 
     OutputStream out = new ArmoredOutputStream(encOut); 
     ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 
     PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP); 
     OutputStream cos = comData.open(bOut); 
     PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator(); 
     OutputStream pOut = lData.open(cos, PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, clearData.length, new Date()); 
     pOut.write(clearData); 
     lData.close(); 
     comData.close(); 
     PGPEncryptedDataGenerator encGen = 
       new PGPEncryptedDataGenerator(
         new JcePGPDataEncryptorBuilder(PGPEncryptedData.AES_256).setWithIntegrityPacket(true).setSecureRandom(
           new SecureRandom()).setProvider(PROVIDER)); 
     if (encKey != null) { 
      encGen.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider(PROVIDER)); 
      byte[] bytes = bOut.toByteArray(); 
      OutputStream cOut = encGen.open(out, bytes.length); 
      cOut.write(bytes); 
      cOut.close(); 
     } 
     out.close(); 
     return new String(encOut.toByteArray()); 
    } 

    public final static PGPKeyRingGenerator generateKeyRingGenerator (char[] pass) throws PGPException{ 
     RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); 
     kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), new SecureRandom(), 2048, 12)); 
     PGPKeyPair rsakp_sign = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpg.generateKeyPair(), new Date()); 
     PGPKeyPair rsakp_enc = new BcPGPKeyPair(PGPPublicKey.RSA_ENCRYPT, kpg.generateKeyPair(), new Date()); 
     PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator(); 
     signhashgen.setKeyFlags(false, KeyFlags.SIGN_DATA|KeyFlags.CERTIFY_OTHER|KeyFlags.SHARED); 
     signhashgen.setPreferredSymmetricAlgorithms(false, new int[]{SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128}); 
     signhashgen.setPreferredHashAlgorithms(false, new int[]{HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA224}); 
     signhashgen.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); 
     PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator(); 
     enchashgen.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); 
     PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); 
     PGPDigestCalculator sha256Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA256); 
     PBESecretKeyEncryptor pske = (new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha256Calc, 0xc0)).build(pass); 
     PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator (PGPSignature.POSITIVE_CERTIFICATION, rsakp_sign, 
       KEY_RING_ID, sha1Calc, signhashgen.generate(), null, new BcPGPContentSignerBuilder(rsakp_sign.getPublicKey().getAlgorithm(), 
       HashAlgorithmTags.SHA1), pske); 
     keyRingGen.addSubKey(rsakp_enc, enchashgen.generate(), null); 
     return keyRingGen; 
    } 

    private static PGPPublicKeyRing getPGPPublicKeyRing() throws IOException { 
     ArmoredInputStream ais = new ArmoredInputStream(new ByteArrayInputStream(Device.getDevice().getPgpPublicKey().getBytes())); 
     return (PGPPublicKeyRing) new PGPObjectFactory(ais).nextObject(); 
    } 

    private static PGPSecretKeyRing getPGPSecretKeyRing() throws IOException { 
     ArmoredInputStream ais = new ArmoredInputStream(new ByteArrayInputStream(Device.getDevice().getPgpSecretKey().getBytes())); 
     return (PGPSecretKeyRing) new PGPObjectFactory(ais).nextObject(); 
    } 

    public final static String genPGPPublicKey (PGPKeyRingGenerator krgen) throws IOException { 
     ByteArrayOutputStream baosPkr = new ByteArrayOutputStream(); 
     PGPPublicKeyRing pkr = krgen.generatePublicKeyRing(); 
     ArmoredOutputStream armoredStreamPkr = new ArmoredOutputStream(baosPkr); 
     pkr.encode(armoredStreamPkr); 
     armoredStreamPkr.close(); 
     return new String(baosPkr.toByteArray(), Charset.defaultCharset()); 
    } 

    public final static String genPGPPrivKey (PGPKeyRingGenerator krgen) throws IOException { 
     ByteArrayOutputStream baosPriv = new ByteArrayOutputStream(); 
     PGPSecretKeyRing skr = krgen.generateSecretKeyRing(); 
     ArmoredOutputStream armoredStreamPriv = new ArmoredOutputStream(baosPriv); 
     skr.encode(armoredStreamPriv); 
     armoredStreamPriv.close(); 
     return new String(baosPriv.toByteArray(), Charset.defaultCharset()); 
    } 
} 

は、私は秘密鍵と公開鍵を作成する方法です

String encrypted = PgpUtils.encrypt("message text"); 
String decrypted = PgpUtils.decrypt(encrypted, "Password"); 
+0

素晴らしい仕事ジョー。それは私のために完全に働いています。あなたは私の時間を救った.... – Hareesh

+0

ありがとう、それは働いた。暗号化されたメッセージはサーバー側で圧縮されないので、復号化のための小さな変更を行うだけでした。 – Fenil

+0

オープンソースであるiOSと同様の機能を実装する方法はありますか? – Fenil

1

BouncyCastleを使用して公開鍵ペアを生成するようですか?

この1つは、パスワードなしでそれを行う方法を尋ねていますが、あまりにもパスワードでそれを行う方法を見てみることができます。 How to generate OpenPGP KeyPair without passphrase using BouncyCastle?

+1

ええ、それは非常に近いです。パスワードを定義する方法のコード例を見つけることは、私にとっては不可能です。 –

+0

@JoeGoble助けになるのはうれしい! – Dannie

+0

BCは大規模なライブラリであり、あなたのアプリへの統合は最後の手段になるはずです。 –

関連する問題