问题描述
我有以下非常标准的代码,用于在 PGP 中使用 BouncyCastle 库加密文件。
String publicKeyString = Files.readString(Paths.get(PUBLIC_KEY_PATH),StandardCharsets.UTF_8);
String privateKeyString = Files.readString(Paths.get(PRIVATE_KEY_PATH),StandardCharsets.UTF_8);
Security.addProvider(new BouncyCastleProvider());
File plainFile = new File(PLAIN_FILE);
File encryptedFile = new File(ENCRYPTED_FILE);
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(CAST5)
.setWithIntegrityPacket(true)
.setSecureRandom(new SecureRandom())
.setProvider("BC"));
final PGPPublicKey publicKey = readPublicKey(IoUtils.toInputStream(publicKeyString,StandardCharsets.UTF_8));
encryptedDataGenerator.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(publicKey).setProvider("BC"));
OutputStream encOutStream = encryptedDataGenerator.open(new FileOutputStream(encryptedFile),new byte[BUFFER_SIZE]);
PGPCompressedDataGenerator cData = new PGPCompressedDataGenerator(ZIP,BEST_SPEED);
OutputStream cDataOut = cData.open(encOutStream,new byte[BUFFER_SIZE]);
PGPV3SignatureGenerator sGen = getPgpSignatureGenerator(privateKeyString,PASSWORD.tochararray());
BCPGOutputStream bOut = new BCPGOutputStream(cDataOut);
sGen.generateOnePassversion(false).encode(bOut);
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
OutputStream lOut = lGen.open(bOut,BINARY,"plain.txt.unencrypted",new Date(),new byte[BUFFER_SIZE]);
copy(new FileInputStream(plainFile),lOut,sGen);
lGen.close();
sGen.generate().encode(bOut);
cData.close();
encOutStream.close();
encryptedDataGenerator.close();
public static PGPPublicKey readPublicKey(InputStream input) throws IOException,PGPException {
final PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(getDecoderStream(input),new JcaKeyFingerprintCalculator());
final Iterator keyRingIter = pgpPub.getKeyRings();
while (keyRingIter.hasNext()) {
final PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next();
final Iterator keyIter = keyRing.getPublicKeys();
while (keyIter.hasNext()) {
final PGPPublicKey key = (PGPPublicKey) keyIter.next();
if (key.isEncryptionKey()) {
System.out.println("found " + key.getBitStrength() + " bit public key");
return key;
}
}
}
throw new IllegalArgumentException("Can't find encryption key in key ring.");
}
public static PGPV3SignatureGenerator getPgpSignatureGenerator(String keyIn,char[] pass) throws IOException,PGPException {
PGPSecretKey pgpSec = readSecretKey(keyIn);
PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass));
PGPV3SignatureGenerator sGen = new PGPV3SignatureGenerator(new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(),PGPUtil.SHA256).setProvider("BC"));
sGen.init(PGPSignature.BINARY_DOCUMENT,pgpPrivKey);
Iterator it = pgpSec.getPublicKey().getUserIDs();
if (it.hasNext())
{
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false,(String)it.next());
}
return sGen;
}
public static void copy(InputStream in,OutputStream out,PGPV3SignatureGenerator sGen) throws IOException,NoSuchAlgorithmException {
try(out) {
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer,bytesRead);
sGen.update(buffer,bytesRead);
}
out.flush();
}
}
同一个源文件,每次生成的加密文件大小都不一样。这会导致在验证外部分发的校验和时出现问题。
我已尝试更改 BUFFER_SIZE
,但仍然存在相同的问题。此外,尝试更改标志 WithIntegrityPacket
并使用 SecureRandom
删除 JcePGPDataEncryptorBuilder
。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)