获取GPG解密在Java(Bouncy Castle)中工作

让我开始说我对这一切非常新鲜.我想要做的是使用 Java中的gpg来解密加密文件.

我成功完成了什么

>如果某位同事使用我的公钥和他的私钥对文件进行加密,并成功解密.
>另一方面
>如果另一个同事尝试解密一个不适合他的文件:失败(如预期)

我的钥匙是这样生成

(gpg –version告诉我我正在使用1.4.5,我正在使用Bouncy Castle 1.47)

gpg –gen-ley

选择选项“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:传递给ElGamal的未知密钥类型
在org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(未知来源)
在org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(未知来源)
在javax.crypto.Cipher.init(DashoA13 * ..)
在javax.crypto.Cipher.init(DashoA13 * ..)
… 8更多

在这里开放了很多建议,从“不要使用gpg,使用x”来“不要使用弹性城堡,使用x”来代替它之间的任何东西.谢谢!

解决方法

如果有兴趣知道如何使用bouncy castle openPGP库对gpg文件进行加密和解密,请查看以下java代码

以下是您需要的4种方法

以下方法将从.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;
}

以下方法将从.asc文件读取和导入您的公钥:

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

以下2种解密和加密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());
        }

相关文章

Linux中的ARP防火墙主要用于防御ARP欺骗攻击,其效果取决于多...
insmod和modprobe加-f参数导致Invalid module format错误 这...
将ArchLinux安装到U盘 几个月前入门Arch的时候上网搜了不少安...
1、安装Apache。 1)执行如下命令,安装Apache服务及其扩展包...
一、先说一下用ansible批量采集机器信息的实现办法: 1、先把...
安装配置 1. 安装vsftpd 检查是否安装了vsftpd # rpm -qa | ...