gpt4 book ai didi

java pgp在asc文件中使用公钥加密文件

转载 作者:行者123 更新时间:2023-12-05 02:51:06 49 4
gpt4 key购买 nike

我的客户使用 PGP 桌面进行文件加密。他们在 .asc 文件中向我发送了一个公钥,我必须用这个公钥用 java 加密一个 zip 文件。但是我找不到任何使用 asc 文件的 java 代码。有一些潜在的库,例如didisoft,但它们只有商业版。下面是一个 asc 示例。

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: PGP Desktop 10.1.1 (Build 10) - not licensed for commercial use: www.pgp.com

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
=bQJS
-----END PGP PUBLIC KEY BLOCK-----

最佳答案

您可以使用加密库“Bouncy CaSTLe”使用 Ascii 格式的 PGP 公钥加密文件。以下代码取自位于此处的 Bouncy CaSTLe 的示例部分:https://github.com/bcgit/bc-java/tree/master/pg/src/main/java/org/bouncycastle/openpgp/examples .

您确实需要这两个文件 KeyBasedLargeFileProcessor.java 和 PGPExampleUtil.java 加上库本身;在此处获取最新版本:https://www.bouncycastle.org/latest_releases.html (您需要 bcprov-xxx.jar 和 bcpg-xxx.jar 来运行示例)。

因为这个例子是一个命令行应用程序,你需要传递这样的信息

-e -a plaintext.txt java_pgp_encrypt_publickey.asc

其中 -e = 加密,-a = ascii 输出,plaintext.txt 是要加密的文件,java_pgp_encrypt_publickey.asc = 公钥。

还有一些其他选项,但它们取决于第三方请求。

请注意 KeyBasedLargeFileProcessor.java 中的注释 - 这只是一个工作示例。

通常没有额外的输出,但在当前目录中有一个新文件,文件名 plaintext.txt.asc 看起来像

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

hQEMAyr8BYmnLERrAQf/SaG7yIORewag0fziemyEmWq+sGJT3TiLIoVCEo+PjDfY
XyuXybIr/q5Q7tE3WcubkXzVIuShB2x2r8zaHP3rhtzDfuRS13S5QBM1LZ9KIcvg
+//OoeS1kfKfJnYfAQR1VCKWBkOQtSCIyMWGmqkrV2xEC8xzAo2cwXCBS2F7LYRE
vnmJGnr4ANFdbSlzRffBPJCcggk9RqDXXJjU31gCqFT+lpgc48Hf6OfRff7x5I2b
5++PH1UPKFIZhalnFE2UQ9DVbzJd2FaciUKhcM9nQSGKoNKy3o1wevrtive8VIuM
JjgV0ql+3MGCVVYL0tBnDdjdbmHV5pcZX9aI147esclPItwZQHTHTtaxTUKTJZeQ
4YgMas+o0faWLUilaeNvNa8PqxLy9gPGzMxUj2/P1narGs4bbivUooLJO73NKV4B
u3on8l/Es4vVLNoZpJv0kw==
=IZ8I
-----END PGP MESSAGE-----

编辑 2020 年 8 月 12 日:我重新下载了 PGP Desktop x64 版本 10.1.1,生成了一个示例 key 对和导出公钥(“-----BEGIN PGP PUBLIC KEY BLOCK-----...”)。我将此 key 与上述选项一起使用,并且创建了一个加密文件(“-----BEGIN PGP MESSAGE-----...”)。该文件用作 PGP 查看器的输入,它已按预期解密,因此您环境中的某些内容似乎无法按预期工作(或错误的公钥正在使用或或或):

enter image description here

由于链接可能会消失,所以这里还有源代码。

KeyBasedLargeFileProcessor.java 类

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPOnePassSignatureList;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
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.io.Streams;

/**
* A simple utility class that encrypts/decrypts public key based
* encryption large files.
* <p>
* To encrypt a file: KeyBasedLargeFileProcessor -e [-a|-ai] fileName publicKeyFile.<br>
* If -a is specified the output file will be "ascii-armored".
* If -i is specified the output file will be have integrity checking added.
* <p>
* To decrypt: KeyBasedLargeFileProcessor -d fileName secretKeyFile passPhrase.
* <p>
* Note 1: this example will silently overwrite files, nor does it pay any attention to
* the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
* will have been used.
* <p>
* Note 2: this example generates partial packets to encode the file, the output it generates
* will not be readable by older PGP products or products that don't support partial packet
* encoding.
* <p>
* Note 3: if an empty file name has been specified in the literal data object contained in the
* encrypted packet a file with the name filename.out will be generated in the current working directory.
*/
public class KeyBasedLargeFileProcessor
/*
file taken from https://github.com/bcgit/bc-java/tree/master/pg/src/main/java/org/bouncycastle/openpgp/examples
get bouncy castle here: https://www.bouncycastle.org/latest_releases.html
i used the bcprov-jdk15on-166.jar and bcpg-jdk15on-166.jar at the time of writing
*/
{
private static void decryptFile(
String inputFileName,
String keyFileName,
char[] passwd,
String defaultFileName)
throws IOException, NoSuchProviderException
{
InputStream in = new BufferedInputStream(new FileInputStream(inputFileName));
InputStream keyIn = new BufferedInputStream(new FileInputStream(keyFileName));
decryptFile(in, keyIn, passwd, defaultFileName);
keyIn.close();
in.close();
}

/**
* decrypt the passed in message stream
*/
private static void decryptFile(
InputStream in,
InputStream keyIn,
char[] passwd,
String defaultFileName)
throws IOException, NoSuchProviderException
{
in = PGPUtil.getDecoderStream(in);

try
{
JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
PGPEncryptedDataList enc;

Object o = pgpF.nextObject();
//
// the first object might be a PGP marker packet.
//
if (o instanceof PGPEncryptedDataList)
{
enc = (PGPEncryptedDataList)o;
}
else
{
enc = (PGPEncryptedDataList)pgpF.nextObject();
}

//
// find the secret key
//
Iterator it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());

while (sKey == null && it.hasNext())
{
pbe = (PGPPublicKeyEncryptedData)it.next();

sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), passwd);
}

if (sKey == null)
{
throw new IllegalArgumentException("secret key for message not found.");
}

InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));

JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);

PGPCompressedData cData = (PGPCompressedData)plainFact.nextObject();

InputStream compressedStream = new BufferedInputStream(cData.getDataStream());
JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(compressedStream);

Object message = pgpFact.nextObject();

if (message instanceof PGPLiteralData)
{
PGPLiteralData ld = (PGPLiteralData)message;

String outFileName = ld.getFileName();
if (outFileName.length() == 0)
{
outFileName = defaultFileName;
}

InputStream unc = ld.getInputStream();
OutputStream fOut = new BufferedOutputStream(new FileOutputStream(outFileName));

Streams.pipeAll(unc, fOut);

fOut.close();
}
else if (message instanceof PGPOnePassSignatureList)
{
throw new PGPException("encrypted message contains a signed message - not literal data.");
}
else
{
throw new PGPException("message is not a simple encrypted file - type unknown.");
}

if (pbe.isIntegrityProtected())
{
if (!pbe.verify())
{
System.err.println("message failed integrity check");
}
else
{
System.err.println("message integrity check passed");
}
}
else
{
System.err.println("no message integrity check");
}
}
catch (PGPException e)
{
System.err.println(e);
if (e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}

private static void encryptFile(
String outputFileName,
String inputFileName,
String encKeyFileName,
boolean armor,
boolean withIntegrityCheck)
throws IOException, NoSuchProviderException, PGPException
{
OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFileName));
PGPPublicKey encKey = PGPExampleUtil.readPublicKey(encKeyFileName);
encryptFile(out, inputFileName, encKey, armor, withIntegrityCheck);
out.close();
}

private static void encryptFile(
OutputStream out,
String fileName,
PGPPublicKey encKey,
boolean armor,
boolean withIntegrityCheck)
throws IOException, NoSuchProviderException
{
if (armor)
{
out = new ArmoredOutputStream(out);
}

try
{
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));

cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));

OutputStream cOut = cPk.open(out, new byte[1 << 16]);

PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
PGPCompressedData.ZIP);

PGPUtil.writeFileToLiteralData(comData.open(cOut), PGPLiteralData.BINARY, new File(fileName), new byte[1 << 16]);

comData.close();

cOut.close();

if (armor)
{
out.close();
}
}
catch (PGPException e)
{
System.err.println(e);
if (e.getUnderlyingException() != null)
{
e.getUnderlyingException().printStackTrace();
}
}
}

public static void main(
String[] args)
throws Exception
{
Security.addProvider(new BouncyCastleProvider());

if (args.length == 0)
{
System.err.println("usage: KeyBasedLargeFileProcessor -e|-d [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
return;
}

if (args[0].equals("-e"))
{
if (args[1].equals("-a") || args[1].equals("-ai") || args[1].equals("-ia"))
{
encryptFile(args[2] + ".asc", args[2], args[3], true, (args[1].indexOf('i') > 0));
}
else if (args[1].equals("-i"))
{
encryptFile(args[2] + ".bpg", args[2], args[3], false, true);
}
else
{
encryptFile(args[1] + ".bpg", args[1], args[2], false, false);
}
}
else if (args[0].equals("-d"))
{
decryptFile(args[1], args[2], args[3].toCharArray(), new File(args[1]).getName() + ".out");
}
else
{
System.err.println("usage: KeyBasedLargeFileProcessor -d|-e [-a|ai] file [secretKeyFile passPhrase|pubKeyFile]");
}
}
}

PGPExampleUtil.java 类

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchProviderException;
import java.util.Iterator;

import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;

class PGPExampleUtil
{
static byte[] compressFile(String fileName, int algorithm) throws IOException
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(algorithm);
PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY,
new File(fileName));
comData.close();
return bOut.toByteArray();
}

/**
* Search a secret key ring collection for a secret key corresponding to keyID if it
* exists.
*
* @param pgpSec a secret key ring collection.
* @param keyID keyID we want.
* @param pass passphrase to decrypt secret key with.
* @return the private key.
* @throws PGPException
* @throws NoSuchProviderException
*/
static PGPPrivateKey findSecretKey(PGPSecretKeyRingCollection pgpSec, long keyID, char[] pass)
throws PGPException, NoSuchProviderException
{
PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID);

if (pgpSecKey == null)
{
return null;
}

return pgpSecKey.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
}

static PGPPublicKey readPublicKey(String fileName) throws IOException, PGPException
{
InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
PGPPublicKey pubKey = readPublicKey(keyIn);
keyIn.close();
return pubKey;
}

/**
* A simple routine that opens a key ring file and loads the first available key
* suitable for encryption.
*
* @param input data stream containing the public key data
* @return the first public key found.
* @throws IOException
* @throws PGPException
*/
static PGPPublicKey readPublicKey(InputStream input) throws IOException, PGPException
{
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());

//
// we just loop through the collection till we find a key suitable for encryption, in the real
// world you would probably want to be a bit smarter about this.
//

Iterator keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext())
{
PGPPublicKeyRing keyRing = (PGPPublicKeyRing)keyRingIter.next();

Iterator keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext())
{
PGPPublicKey key = (PGPPublicKey)keyIter.next();

if (key.isEncryptionKey())
{
return key;
}
}
}

throw new IllegalArgumentException("Can't find encryption key in key ring.");
}

static PGPSecretKey readSecretKey(String fileName) throws IOException, PGPException
{
InputStream keyIn = new BufferedInputStream(new FileInputStream(fileName));
PGPSecretKey secKey = readSecretKey(keyIn);
keyIn.close();
return secKey;
}

/**
* A simple routine that opens a key ring file and loads the first available key
* suitable for signature generation.
*
* @param input stream to read the secret key ring collection from.
* @return a secret key.
* @throws IOException on a problem with using the input stream.
* @throws PGPException if there is an issue parsing the input stream.
*/
static PGPSecretKey readSecretKey(InputStream input) throws IOException, PGPException
{
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(input), new JcaKeyFingerprintCalculator());

//
// we just loop through the collection till we find a key suitable for encryption, in the real
// world you would probably want to be a bit smarter about this.
//

Iterator keyRingIter = pgpSec.getKeyRings();
while (keyRingIter.hasNext())
{
PGPSecretKeyRing keyRing = (PGPSecretKeyRing)keyRingIter.next();

Iterator keyIter = keyRing.getSecretKeys();
while (keyIter.hasNext())
{
PGPSecretKey key = (PGPSecretKey)keyIter.next();

if (key.isSigningKey())
{
return key;
}
}
}

throw new IllegalArgumentException("Can't find signing key in key ring.");
}
}

关于java pgp在asc文件中使用公钥加密文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63351345/

49 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com