我在PGP桌面上有两个PGP密钥。
现在我使用以上两个密钥加密文件。我可以使用PGP Desktop成功解密文件。
但我无法使用Java API解密文件。
public static void decryptFile(File input, File key, char[] passwd, File destDir) throws Exception {
File destFile = null;
InputStream keyIn = new FileInputStream(key);
Security.addProvider(new BouncyCastleProvider());
InputStream is = new FileInputStream(input);
InputStream in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(is);
try {
PGPObjectFactory pgpF = new PGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
Iterator<PGPPublicKeyEncryptedData> encDataObjects = enc.getEncryptedDataObjects();
PGPPublicKeyEncryptedData encryptedData = null;
List<Long> keyIds = new LinkedList<Long>();
while (encDataObjects.hasNext()) {
encryptedData = (PGPPublicKeyEncryptedData) encDataObjects.next();
long decipheringKeyID = encryptedData.getKeyID();
System.out.println("****** Key ID ****** "+decipheringKeyID);
keyIds.add(decipheringKeyID);
}
PGPSecretKey decipheringKey = readSecretKey(keyIn, keyIds);
if (decipheringKey == null) {
throw new IllegalArgumentException("Secret key for message not found.");
}
PGPPrivateKey decryptionKey = findPrivateKey(decipheringKey, passwd);
if (decryptionKey == null) {
throw new IllegalArgumentException("Private key for message not found.");
}
PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(decryptionKey);
InputStream clear = encryptedData.getDataStream(dataDecryptorFactory);
PGPObjectFactory plainFact = new PGPObjectFactory(clear);
Object message = plainFact.nextObject();
if (message instanceof PGPCompressedData) {
PGPCompressedData cData = (PGPCompressedData) message;
PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());
message = pgpFact.nextObject();
}
if (message instanceof PGPOnePassSignatureList) {
// TODO: Verify file
message = plainFact.nextObject();
}
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
int ch;
ByteArrayOutputStream out = new ByteArrayOutputStream();
if(ld.getFileName().toString() == null || ld.getFileName().toString().equals(""))
{
String[] fname = input.getAbsolutePath().split("\\\\");
destFile = new File(destDir,fname[fname.length-1].replace(".pgp", ""));
}
else
{
destFile = new File(destDir, ld.getFileName());
}
FileOutputStream fos = new FileOutputStream(destFile);
while ((ch = unc.read()) >= 0) {
out.write(ch);
}
byte[] returnBytes = out.toByteArray();
out.close();
fos.write(returnBytes);
fos.close();
} else {
throw new PGPException("Message is not a simple encrypted file - type unknown.");
}
} catch (Exception ex) {
ex.printStackTrace();
throw new Exception(ex.getMessage());
} finally {
if (keyIn != null) {
keyIn.close();
}
if (in != null) {
in.close();
}
if (is != null) {
is.close();
}
}
}
我收到以下错误
org.bouncycastle.openpgp.PGPException: exception encrypting session info: unknown block type
at org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory.recoverSessionData(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at com.pgp.util.PGPUtils.decryptFile(PGPUtils.java:312)
at com.pgp.util.PGPUtils.main(PGPUtils.java:576)
Caused by: org.bouncycastle.crypto.InvalidCipherTextException: unknown block type
at org.bouncycastle.crypto.encodings.PKCS1Encoding.decodeBlock(Unknown Source)
at org.bouncycastle.crypto.encodings.PKCS1Encoding.processBlock(Unknown Source)
at org.bouncycastle.crypto.BufferedAsymmetricBlockCipher.doFinal(Unknown Source)
... 4 more
Exception in thread "main" java.lang.Exception: exception encrypting session info: unknown block type
at com.pgp.util.PGPUtils.decryptFile(PGPUtils.java:373)
at com.pgp.util.PGPUtils.main(PGPUtils.java:576)