Java:使用Bouncy Castle进行PGP加密

未命名的用户

我正在尝试使用PGP进行加密,并且我的crypto方法成功地加密了输入字符串,但是当我尝试解密它以验证加密是否正确完成时,该字符串不会被解密。

我尝试了2种方法:

第一种方法使用FileOutputStream写入加密的字符串,第二种方法使用ByteArrayOutputStreamFileOutputStream创建一个文件,我可以使用Kleopatra对其进行解密。但是我的要求是只获取一个加密的字符串(不写在文件中)。因此,当我尝试解密加密的字符串(使用ByteArrayOutputStream后收到)时,它不起作用。我尝试复制字符串并通过Kleopatra中的tools >> clipboard对其进行解密,但是禁用了crypto / verify选项。我尝试通过FileWriter类手动将字符串写入文件,但是由于文件包含证书且无法解密或验证的错误而导致解密失败

我假设只有由OutputStream直接创建的文件才能成功解密。但是我必须真正检查加密的字符串。

任何帮助将不胜感激。

迈克尔·菲尔

以下完整示例摘自《 David Cook&Jon Eaves的Java密码学:工具和技术》一书的源代码。包含所有示例的完整源代码可以在这里找到:https : //www.bouncycastle.org/java-crypto-tools-src.zip

这些示例显示了使用El Gamal或Elliptic Curves创建私钥/公钥以及使用AES-256进行加密的过程。在ecExample方法中,我添加了两行以将加密的字符串保存到文件“ pgp-encrypted-string.dat”,然后重新加载数据以解密文件并显示解密的字符串。

import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.io.Streams;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import java.util.Date;

public class PGPEncryptionExampleForSO
{
     /**
     * Create an encrypted data blob using an AES-256 session key and the
     * passed in public key.
     *
     * @param encryptionKey the public key to use.
     * @param data the data to be encrypted.
     * @return a PGP binary encoded version of the encrypted data.
     */
    public static byte[] createEncryptedData(
        PGPPublicKey encryptionKey,
        byte[] data)
        throws PGPException, IOException
    {
        PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(
            new JcePGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256)
                .setWithIntegrityPacket(true)
                .setSecureRandom(new SecureRandom()).setProvider("BC"));
        encGen.addMethod(
            new JcePublicKeyKeyEncryptionMethodGenerator(encryptionKey)
                .setProvider("BC"));
        ByteArrayOutputStream encOut = new ByteArrayOutputStream();
        // create an indefinite length encrypted stream
        OutputStream cOut = encGen.open(encOut, new byte[4096]);
        // write out the literal data
        PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
        OutputStream pOut = lData.open(
            cOut, PGPLiteralData.BINARY,
            PGPLiteralData.CONSOLE, data.length, new Date());
        pOut.write(data);
        pOut.close();
        // finish the encryption
        cOut.close();
        return encOut.toByteArray();
    }

    /**
     * Extract the plain text data from the passed in encoding of PGP
     * encrypted data. The routine assumes the passed in private key
     * is the one that matches the first encrypted data object in the
     * encoding.
     *
     * @param privateKey the private key to decrypt the session key with.
     * @param pgpEncryptedData the encoding of the PGP encrypted data.
     * @return a byte array containing the decrypted data.
     */
    public static byte[] extractPlainTextData(
        PGPPrivateKey privateKey,
        byte[] pgpEncryptedData)
        throws PGPException, IOException
    {
        PGPObjectFactory pgpFact = new JcaPGPObjectFactory(pgpEncryptedData);
        PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpFact.nextObject();
        // find the matching public key encrypted data packet.
        PGPPublicKeyEncryptedData encData = null;
        for (PGPEncryptedData pgpEnc: encList)
        {
            PGPPublicKeyEncryptedData pkEnc
                = (PGPPublicKeyEncryptedData)pgpEnc;
            if (pkEnc.getKeyID() == privateKey.getKeyID())
            {
                encData = pkEnc;
                break;
            }
        }
        if (encData == null)
        {
            throw new IllegalStateException("matching encrypted data not found");
        }
        // build decryptor factory
        PublicKeyDataDecryptorFactory dataDecryptorFactory =
            new JcePublicKeyDataDecryptorFactoryBuilder()
                .setProvider("BC")
                .build(privateKey);
        InputStream clear = encData.getDataStream(dataDecryptorFactory);
        byte[] literalData = Streams.readAll(clear);
        clear.close();
        // check data decrypts okay
        if (encData.verify())
        {
            // parse out literal data
            PGPObjectFactory litFact = new JcaPGPObjectFactory(literalData);
            PGPLiteralData litData = (PGPLiteralData)litFact.nextObject();
            byte[] data = Streams.readAll(litData.getInputStream());
            return data;
        }
        throw new IllegalStateException("modification check failed");
    }

    private static void elgamalExample()
        throws Exception
    {
        byte[] msg = Strings.toByteArray("Hello, world!");
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH", "BC");
        kpGen.initialize(2048);
        KeyPair kp = kpGen.generateKeyPair();
        PGPKeyPair elgKp = new JcaPGPKeyPair(
            PGPPublicKey.ELGAMAL_ENCRYPT, kp, new Date());
        byte[] encData = createEncryptedData(elgKp.getPublicKey(), msg);
        byte[] decData = extractPlainTextData(elgKp.getPrivateKey(), encData);
        System.out.println("elgamal encryption msg length: " + msg.length + " enc.length: " + encData.length + " dec.length: " + decData.length);
        System.out.println(Strings.fromByteArray(decData));
    }

    private static void ecExample()
        throws Exception
    {
        byte[] msg = Strings.toByteArray("Hello, world!");
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("EC", "BC");
        kpGen.initialize(new ECGenParameterSpec("P-256"));
        KeyPair kp = kpGen.generateKeyPair();
        PGPKeyPair ecdhKp = new JcaPGPKeyPair(PGPPublicKey.ECDH, kp, new Date());
        byte[] encData = createEncryptedData(ecdhKp.getPublicKey(), msg);
        // save encrypted string
        Files.write(Paths.get("pgp-encrypted-string.dat"), encData);
        // load encrypted string
        byte[] encDataLoad = Files.readAllBytes(Paths.get("pgp-encrypted-string.dat"));
        byte[] decData = extractPlainTextData(ecdhKp.getPrivateKey(), encDataLoad);
        System.out.println("ec encryption msg length: " + msg.length + " enc.length: " + encData.length + " dec.length: " + decData.length);
        System.out.println(Strings.fromByteArray(decData));
    }

    public static void main(String[] args)
        throws Exception
    {
        Security.addProvider(new BouncyCastleProvider());
        // you need the two files bcpg-jdk15on-165.jar and bcprov-jdk15to18-165.jar to run the example
        System.out.println("Example from Java Cryptography: Tools and Techniques by David Hook & Jon Eaves");
        System.out.println("get source files: https://www.bouncycastle.org/java-crypto-tools-src.zip");
        elgamalExample();
        ecExample();
    }
}

这是简短的输出:

Example from Java Cryptography: Tools and Techniques by David Hook & Jon Eaves
get source files: https://www.bouncycastle.org/java-crypto-tools-src.zip
elgamal encryption msg length: 13 enc.length: 601 dec.length: 13
Hello, world!
ec encryption msg length: 13 enc.length: 200 dec.length: 13
Hello, world!

补充:据我了解,您正在使用类似String的字符串

This string needs an encryption

并且您想使用rsa pgp公钥对其进行加密:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.65

mI0EXr/nDgEEAKhB6ufAB954aBIlNjPCsryzUVLu0qkC/1RtnFHf+J6IVegV8Wi7
28V074inQcw6o6FTLtFTaLRP4+3eXNATdjGSjrvcP7k+nu50vydugHv43fPuCiZ7
6gbbMTE9gPiLPA2pS+SmQJnr9hOrD5rzwYP1yNNIsRJ9qmU5NeZyu+szABEBAAG0
DHRlc3RpZGVudGl0eYicBBABAgAGBQJev+cOAAoJEPBDuyqTbz/gY0YD/R+gDkfe
qPgNuk6iI2wLSGEeZRXr6Ru1cyG73CRvz7BjCpwWx039AdQzP9gkeo6MEj8Z0c73
obqEP8NtvvOcwC7+/QiGLTR2mgCsNhk54+iCGsvNbkpkr/rRoYZGyvb+rxui0A61
DCB1w5hdnyMg2OglFNrkaPfpNjMsTebfF5eS
=h1+m
-----END PGP PUBLIC KEY BLOCK-----

并获取加密的字符串

-----BEGIN PGP MESSAGE-----
Version: BCPG v1.65

hIwD8EO7KpNvP+ABA/9JkOE9PDyS/kr/lZ1Uz+NCSe1JiNcKCXjbsUbvP8CT7Tf1
cKlgzIz1mQjdpkBtVpVhEnEjmUzFy2UCRKr4b4Wx7/1UL+370CICW5HgMoi5TgTg
MYRy5I9Uba/+JxcusjWB1JJHP4ofULziXRKLWAoSPLlglZDzSmV88hNo19rl39JZ
AbMhIS2edM9hHICefL/Yaiq90hGjKMRReVopu2tPUjNLGYP7QABAvWb3WQJMZoYT
HEsyjHxeyYQylAdYB7pWQA0++Z803iclvM3skN8FBt64ebDkqfxgbhs=
=je0r
-----END PGP MESSAGE-----

现在,您想使用Kleoptatra,在线(例如https://sela.io/pgp-en/)或Java中的RSA pgp私钥和密码123456来解密此消息

-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: BCPG v1.65

lQH+BF6/5w4BBACoQernwAfeeGgSJTYzwrK8s1FS7tKpAv9UbZxR3/ieiFXoFfFo
u9vFdO+Ip0HMOqOhUy7RU2i0T+Pt3lzQE3Yxko673D+5Pp7udL8nboB7+N3z7gom
e+oG2zExPYD4izwNqUvkpkCZ6/YTqw+a88GD9cjTSLESfaplOTXmcrvrMwARAQAB
/gMDAhhcE1oF/u8YYExKGLgriK5JpUUSsMFU0AOHP9/zZQr09437V0f/F4J87+9s
G30lDRikGwynEGRnAvIVwqq2F+iarKGGHCZCRgbyufXS7VK6wE/43lR0kSwA2VIM
ll/KbQKP1cSZv0rqtJ1tGL7cDHFEwq10gM4Bn75HOKyBzE9oERRKz37noAECsAZn
xuXGlEB5noqTT00RxsHjBA5Os04CtEz9N+OMrg47IR7AzSQUe90lG2F6W71dhJ6V
jQaf7D6JFU3dOWPW1eBb5FQhgYF92CFRizJ42lDCiTfl2FQU49MlwLd2ofNneuPo
aVuPoYUNKwbasyx4fo2vh6rrMyxmncCizMExvh6GIVgYd7EK9s6Gxq/duuOvly4O
ZAyIY2MOon0bDXxAYR2q/wdQLamnP7rAR4uMu24m/iOuBj6wwTR8v8hhsFFTp/4u
tebwWzLnPyyBYStnTF5IZ9ZJeVl5S3zdzNcrP9g8yXtItAx0ZXN0aWRlbnRpdHmI
nAQQAQIABgUCXr/nDgAKCRDwQ7sqk28/4GNGA/0foA5H3qj4DbpOoiNsC0hhHmUV
6+kbtXMhu9wkb8+wYwqcFsdN/QHUMz/YJHqOjBI/GdHO96G6hD/Dbb7znMAu/v0I
hi00dpoArDYZOePoghrLzW5KZK/60aGGRsr2/q8botAOtQwgdcOYXZ8jINjoJRTa
5Gj36TYzLE3m3xeXkg==
=y/tQ
-----END PGP PRIVATE KEY BLOCK-----

并获取解密的字符串:

This string needs an encryption

幸运的是,要在Java中进行加密/解密,可以在BouncyCastle Github-Repo中找到示例文件:https : //github.com/bcgit/bc-java/blob/master/pg/src/main/java/org/bouncycastle/openpgp / examples /您可能需要使用RSA(RSAKeyPairGenerator.java)或ElGamal(DSAElGamalKeyRingGenerator.java)创建新的PGP密钥对。使用生成的密钥,您可以使用KeyBasedFileProcessor.java和必要的PGPExampleUtil.java进行加密或解密。

我使用“ -a testidentity 123456”作为参数创建了RSA密钥文件,使用“ -e -ai plaintext.txt rsa_pub.asc”完成了加密,使用“ -d plaintext.txt.asc rsa_secret.asc 123456”进行了解密。 ”。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用 Bouncy Castle 获取 PGP 加密和登录的字符串输出

来自分类Dev

使用Bouncy Castle PGP从单个文件加载多个公共密钥

来自分类Dev

使用ED25519键和Bouncy Castle(Java)对Json进行签名/验证

来自分类Dev

如何使用Bouncy Castle编辑Java中的密码套件列表

来自分类Dev

Bouncy Castle API如何知道使用哪个密钥加密?

来自分类Dev

使用Bouncy Castle生成keyPair

来自分类Dev

如何在Java密钥库中存储Bouncy Castle PGP密钥?

来自分类Dev

PGP密钥服务器和Bouncy Castle OpenPGP API Java

来自分类Dev

PGP密钥服务器和Bouncy Castle OpenPGP API Java

来自分类Dev

使用Bouncy Castle在C#中加密和使用AES在Python中解密的问题(EAX模式)

来自分类Dev

如何使用Java中的Bouncy Castle从CSR文件确定公钥大小?

来自分类Dev

如何使用Java中的Bouncy Castle从CSR文件确定公钥大小?

来自分类Dev

Java Bouncy Castle TLS协议版本顺序?

来自分类Dev

Bouncy Castle AES加密-以块形式提供输入

来自分类Dev

如何在不使用Bouncy Castle的情况下从Java的X509Certificate中提取CN?

来自分类Dev

为什么使用断点(Eclipse)跳过 SCrypt.generate()(Bouncy Castle Java API)行会阻止调试过程?

来自分类Dev

使用javamail发送pgp加密邮件+附件

来自分类Dev

Bouncy Castle中可以使用哪些“安全” ECC曲线?

来自分类Dev

使用Bouncy Castle提供程序创建SSLContext实例

来自分类Dev

通过Bouncy Castle提取GPG密钥使用标志

来自分类Dev

Bouncy Castle中可以使用哪些“安全” ECC曲线?

来自分类Dev

通过Bouncy Castle提取GPG密钥使用标志

来自分类Dev

使用 Bouncy-Castle 库从证书中读取 SubjectAlternativeNames

来自分类Dev

如何使用PFX(Bouncy Castle或其他)以编程方式对可执行文件进行代码签名

来自分类Dev

VBA CBC 256和Java Bouncy城堡加密

来自分类Dev

Bouncy Castle加密的有效负载已从SAP PI破坏

来自分类Dev

使用PGP加密的发送端口中的文件名

来自分类Dev

如何使用openssl命令执行PGP加密和解密方法

来自分类Dev

pgp_sym_encrypt 函数使用的加密机制

Related 相关文章

  1. 1

    使用 Bouncy Castle 获取 PGP 加密和登录的字符串输出

  2. 2

    使用Bouncy Castle PGP从单个文件加载多个公共密钥

  3. 3

    使用ED25519键和Bouncy Castle(Java)对Json进行签名/验证

  4. 4

    如何使用Bouncy Castle编辑Java中的密码套件列表

  5. 5

    Bouncy Castle API如何知道使用哪个密钥加密?

  6. 6

    使用Bouncy Castle生成keyPair

  7. 7

    如何在Java密钥库中存储Bouncy Castle PGP密钥?

  8. 8

    PGP密钥服务器和Bouncy Castle OpenPGP API Java

  9. 9

    PGP密钥服务器和Bouncy Castle OpenPGP API Java

  10. 10

    使用Bouncy Castle在C#中加密和使用AES在Python中解密的问题(EAX模式)

  11. 11

    如何使用Java中的Bouncy Castle从CSR文件确定公钥大小?

  12. 12

    如何使用Java中的Bouncy Castle从CSR文件确定公钥大小?

  13. 13

    Java Bouncy Castle TLS协议版本顺序?

  14. 14

    Bouncy Castle AES加密-以块形式提供输入

  15. 15

    如何在不使用Bouncy Castle的情况下从Java的X509Certificate中提取CN?

  16. 16

    为什么使用断点(Eclipse)跳过 SCrypt.generate()(Bouncy Castle Java API)行会阻止调试过程?

  17. 17

    使用javamail发送pgp加密邮件+附件

  18. 18

    Bouncy Castle中可以使用哪些“安全” ECC曲线?

  19. 19

    使用Bouncy Castle提供程序创建SSLContext实例

  20. 20

    通过Bouncy Castle提取GPG密钥使用标志

  21. 21

    Bouncy Castle中可以使用哪些“安全” ECC曲线?

  22. 22

    通过Bouncy Castle提取GPG密钥使用标志

  23. 23

    使用 Bouncy-Castle 库从证书中读取 SubjectAlternativeNames

  24. 24

    如何使用PFX(Bouncy Castle或其他)以编程方式对可执行文件进行代码签名

  25. 25

    VBA CBC 256和Java Bouncy城堡加密

  26. 26

    Bouncy Castle加密的有效负载已从SAP PI破坏

  27. 27

    使用PGP加密的发送端口中的文件名

  28. 28

    如何使用openssl命令执行PGP加密和解密方法

  29. 29

    pgp_sym_encrypt 函数使用的加密机制

热门标签

归档