java pgp异常,使用BouncyCastle PGP解密文件的异常

I was trying to decrypt this sample file given by the client, using a class called PgpDecrypt. But when the code comes to this line:

Stream clear = pbe.GetDataStream(privKey);

it returns an error: exception decrypting secret key

Here's my decryption code:

PgpDecrypt test = new PgpDecrypt(string.Concat(pathh, "TestDecryptionFile"),

string.Concat(pathh, "mypgpprivatekey.key"),

"mypassphrase",

@"d:/test/",

string.Concat(pathh, "clientpublickey.key"));

FileStream fs = File.Open(string.Concat(pathh, "TestDecryptionFile"), FileMode.Open);

test.Decrypt(fs, @"d:\test\");

I am using BouncyCastle as my third party library for .NET.

Any idea to solve this would be a great help. Thanks in advance!

解决方案

If you're following the BouncyCastle classes PGPEncrypt, PGPDecrypt and PGPEncryptionKeys...

Under the PGPEncryptionKeys class, add this method:

///

/// Return the last key we can use to decrypt.

/// Note: A file can contain multiple keys (stored in "key rings")

///

private PgpSecretKey GetLastSecretKey(PgpSecretKeyRingBundle secretKeyRingBundle)

{

return (from PgpSecretKeyRing kRing in secretKeyRingBundle.GetKeyRings()

select kRing.GetSecretKeys().Cast()

.LastOrDefault(k => k.IsSigningKey))

.LastOrDefault(key => key != null);

}

still inside the PgpEncryptionKeys class, make sure the ReadSecretKey method looks like this:

private PgpSecretKey ReadSecretKey(string privateKeyPath, bool toEncrypt)

{

using (Stream keyIn = File.OpenRead(privateKeyPath))

using (Stream inputStream = PgpUtilities.GetDecoderStream(keyIn))

{

PgpSecretKeyRingBundle secretKeyRingBundle = new PgpSecretKeyRingBundle(inputStream);

PgpSecretKey foundKey = toEncrypt ? GetFirstSecretKey(secretKeyRingBundle) : GetLastSecretKey(secretKeyRingBundle);

if (foundKey != null)

return foundKey;

}

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

}

^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BouncyCastleJava 平台上的一个加解密库,支持多种加密算法,包括 PGP解密。以下是使用 BouncyCastle 实现 PGP 加密解密文件的示例代码: 1. 加载 BouncyCastle Provider: ``` Security.addProvider(new BouncyCastleProvider()); ``` 2. 生成 PGP 密钥对: ``` PGPKeyPairGenerator kpg = new JcaPGPKeyPairGenerator().setProvider("BC").setAlgorithm(AsymmetricAlgorithmTags.RSA_GENERAL).setKeySize(2048); PGPKeyPair kp = kpg.generate(); ``` 3. 导出公钥和私钥: ``` PGPPublicKeyRing publicKeyRing = new PGPPublicKeyRing(kp.getPublicKey().getEncoded(), new JcaKeyFingerprintCalculator()); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPrivateKey privateKey = kp.getPrivateKey(); ``` 4. 加密文件: ``` // 创建加密器 PGPEncryptorBuilder builder = new JcePGPEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).setSecureRandom(new SecureRandom()); builder.setProvider("BC"); PGPEncryptor encryptor = builder.build(publicKey); // 创建输出流 File outputFile = new File("encrypted.pgp"); OutputStream outputStream = new FileOutputStream(outputFile); // 创建压缩器 PGPCompressedDataGenerator compressor = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP); OutputStream compressedOutputStream = compressor.open(outputStream); // 创建签名器 PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA256).setProvider("BC")); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey); signatureGenerator.generateOnePassVersion(false).encode(compressedOutputStream); // 创建字节流加密器 PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator(); OutputStream literalOutputStream = literalDataGenerator.open(compressedOutputStream, PGPLiteralData.BINARY, "filename", new Date(), new byte[1024]); // 加密文件内容 File inputFile = new File("input.txt"); InputStream inputStream = new FileInputStream(inputFile); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { literalOutputStream.write(buffer, 0, length); } inputStream.close(); // 关闭流 literalDataGenerator.close(); signatureGenerator.generate().encode(compressedOutputStream); compressor.close(); encryptor.close(); outputStream.close(); ``` 5. 解密文件: ``` // 创建解密PGPObjectFactory factory = new JcaPGPObjectFactory(new FileInputStream("encrypted.pgp")); PGPEncryptedDataList encryptedDataList = (PGPEncryptedDataList) factory.nextObject(); PGPPBEEncryptedData pbeEncryptedData = (PGPPBEEncryptedData) encryptedDataList.get(0); PGPPrivateKey privateKey = findPrivateKey("userid", "password".toCharArray()); InputStream decryptedInputStream = pbeEncryptedData.getDataStream(new JcePBEDataDecryptorFactoryBuilder(new JcaPGPDigestCalculatorProviderBuilder().setProvider("BC").build()).setProvider("BC").build(privateKey)); // 创建签名校验器 PGPObjectFactory plainFactory = new JcaPGPObjectFactory(decryptedInputStream); PGPOnePassSignatureList signatureList = (PGPOnePassSignatureList) plainFactory.nextObject(); PGPOnePassSignature signature = signatureList.get(0); PGPPublicKey publicKey = findPublicKey(signature.getKeyID()); signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey); PGPLiteralData literalData = (PGPLiteralData) plainFactory.nextObject(); InputStream literalInputStream = literalData.getInputStream(); // 校验签名 byte[] buffer = new byte[1024]; int length; while ((length = literalInputStream.read(buffer)) != -1) { signature.update(buffer, 0, length); } if (signature.verify(((PGPSignatureList) plainFactory.nextObject()).get(0))) { System.out.println("Signature verified"); } else { System.out.println("Signature not verified"); } // 读取文件内容 while ((length = literalInputStream.read(buffer)) != -1) { // 处理文件内容 } literalInputStream.close(); decryptedInputStream.close(); ``` 其中,`findPrivateKey` 和 `findPublicKey` 方法根据指定的用户 ID 查找对应的私钥和公钥。在实际使用时,需要将用户 ID 和密钥信息存储在合适的位置,例如文件或数据库中,然后在程序中进行读取。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值