http://sloanseaman.com/wordpress/2012/05/13/revisited-pgp-encryptiondecryption-in-java/
Please note that if you are using Bouncy Castles libraries < 1.47 you should use the code in this post
I have a requirement where I need to decrypt a file that is PGP encrypted for a project I am working on. At the same time I need a unit test for my code so I need to encrypt a file as well.
I started digging around and found that there is really no documentation I could find that covered the whole process. Some postings only covered encryption, some decryption, but none covered both as well as how to make the public/private keys. So, here you go 🙂The Downloads/Installs
Before you even start coding we need to discuss Java Security. The JRE by default ships with security for cryptography called Java Cryptography Extension (JCE). The JCE will support PGP but because import/export of cryptography can be sketchy, it only supports weak keys by default (think keys that wouldn’t be too hard to crack). PGP won’t work under this environment so you need to first address this.
JCE Update
Credit where due: This part is taken mainly from this article on jce policy files
Go to the Java download page and go all the way to the bottom and download the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. The number at the end (currently 6 or 7) is just the JRE version.
PGP Tools
Next you need to create you public and private key files. Since Symantec bought PGP in 2010 most of the freeware stuff has disappeared and most links lead to Symantec’s website. I found an old freeware version of PGP (Windows only) at http://www.pgpi.org/products/pgp/versions/freeware/win32/6.5.8/. Please note that newer version don’t work on Windows 7 or are owned by Symantac.
Install the program and then launch it by running PGPKeys.exe. To use it:- Select Keys -> New Key
- Click Next
- Enter your information
- Click Next
- Use the Diffie-Hellman/DSS key Pair Type
- Click Next
- Select your Key Pair Size (I just used 1024 since I’m not that worried about it for now)
- Click Next
- Leave your Key Expiration as never expires
- Click Next
- Enter the passphrase (password) you want to use
- Click Next
- If you entered less than 8 characters you will be warned. Click Next
- Key will be generated
- Click Next
- Click Finish
The files that were generated and that you will need to use in your code can be found by going to Edit -> Options -> Files.
Find these files and copy them to someplace where your code can reach them.
BouncyCastle’s PGP Libraries
I’m using the PGP library from Bouncy Castle. Honestly it’s poorly documented and rather complex but it’s the best and most common one that I could find.
Either download the latest from http://www.bouncycastle.org/latest_releases.html or use maven like so:
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk16</artifactId> <version>1.45</version> </dependency>
You are now (finally) ready to actually code something!
The Code
First lets write a general util that will handle any InputStreams (shouldn’t we all be using Readers by now?) and then lets write one that wraps the first one and will handle files for us.
Here is the first util which will handle any type of InputStream:import java.io.ByteArrayOutputStream; import java.io.File; 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.PGPObjectFactory; import org.bouncycastle.openpgp.PGPOnePassSignatureList; import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; import org.bouncycastle.openpgp.PGPSecretKey; import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; /** * Taken from org.bouncycastle.openpgp.examples * * @author seamans * */ public class PGPUtil { @SuppressWarnings("unchecked") public static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException { in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in); PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(in); // // 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. // PGPPublicKey key = null; // // iterate through the key rings. // Iterator<PGPPublicKeyRing> rIt = pgpPub.getKeyRings(); while (key == null && rIt.hasNext()) { PGPPublicKeyRing kRing = rIt.next(); Iterator<PGPPublicKey> kIt = kRing.getPublicKeys(); while (key == null && kIt.hasNext()) { PGPPublicKey k = kIt.next(); if (k.isEncryptionKey()) { key = k; } } } if (key == null) { throw new IllegalArgumentException("Can't find encryption key in key ring."); } return key; } /** * Load a secret key ring collection from keyIn and find the secret key corresponding to * keyID if it exists. * * @param keyIn input stream representing a key ring collection. * @param keyID keyID we want. * @param pass passphrase to decrypt secret key with. * @return * @throws IOException * @throws PGPException * @throws NoSuchProviderException */ private static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID, char[] pass) throws IOException, PGPException, NoSuchProviderException { PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( org.bouncycastle.openpgp.PGPUtil.getDecoderStream(keyIn)); PGPSecretKey pgpSecKey = pgpSec.getSecretKey(keyID); if (pgpSecKey == null) { return null; } return pgpSecKey.extractPrivateKey(pass, "BC"); } /** * decrypt the passed in message stream */ @SuppressWarnings("unchecked") public static void decryptFile(InputStream in, OutputStream out, InputStream keyIn, char[] passwd) throws Exception { Security.addProvider(new BouncyCastleProvider()); in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in); PGPObjectFactory pgpF = new PGPObjectFactory(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<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects(); PGPPrivateKey sKey = null; PGPPublicKeyEncryptedData pbe = null; while (sKey == null && it.hasNext()) { pbe = it.next(); sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd); } if (sKey == null) { throw new IllegalArgumentException("Secret key for message not found."); } InputStream clear = pbe.getDataStream(sKey, "BC"); 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 PGPLiteralData) { PGPLiteralData ld = (PGPLiteralData) message; InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { out.write(ch); } } 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()) { throw new PGPException("Message failed integrity check"); } } } public static void encryptFile(OutputStream out, String fileName, PGPPublicKey encKey, boolean armor, boolean withIntegrityCheck) throws IOException, NoSuchProviderException, PGPException { Security.addProvider(new BouncyCastleProvider()); if (armor) { out = new ArmoredOutputStream(out); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator( PGPCompressedData.ZIP); org.bouncycastle.openpgp.PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName)); comData.close(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator( PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(), "BC"); cPk.addMethod(encKey); byte[] bytes = bOut.toByteArray(); OutputStream cOut = cPk.open(out, bytes.length); cOut.write(bytes); cOut.close(); out.close(); } }
I’m not going to go over it line-by-line because, honestly, I haven’t looked at it that hard so I’m not sure what it’s all doing 😉 Sorry.
Next let’s write a util that allows us to easily work with files (and Spring, if you are into that sort of thing :))
import java.io.FileInputStream; import java.io.FileOutputStream; public class PGPFileProcessor { private String passphrase; private String keyFile; private String inputFile; private String outputFile; private boolean asciiArmored = false; private boolean integrityCheck = true; public boolean encrypt() throws Exception { FileInputStream keyIn = new FileInputStream(keyFile); FileOutputStream out = new FileOutputStream(outputFile); PGPUtil.encryptFile(out, inputFile, PGPUtil.readPublicKey(keyIn), asciiArmored, integrityCheck); out.close(); keyIn.close(); return true; } public boolean decrypt() throws Exception { FileInputStream in = new FileInputStream(inputFile); FileInputStream keyIn = new FileInputStream(keyFile); FileOutputStream out = new FileOutputStream(outputFile); PGPUtil.decryptFile(in, out, keyIn, passphrase.toCharArray()); in.close(); out.close(); keyIn.close(); return true; } public boolean isAsciiArmored() { return asciiArmored; } public void setAsciiArmored(boolean asciiArmored) { this.asciiArmored = asciiArmored; } public boolean isIntegrityCheck() { return integrityCheck; } public void setIntegrityCheck(boolean integrityCheck) { this.integrityCheck = integrityCheck; } public String getPassphrase() { return passphrase; } public void setPassphrase(String passphrase) { this.passphrase = passphrase; } public String getKeyFile() { return keyFile; } public void setKeyFile(String keyFile) { this.keyFile = keyFile; } public String getInputFile() { return inputFile; } public void setInputFile(String inputFile) { this.inputFile = inputFile; } public String getOutputFile() { return outputFile; } public void setOutputFile(String outputFile) { this.outputFile = outputFile; } }Remember that if you use the PGPFileProcessor in Spring and intend on changing things programmatically via the get/sets you need to make the scope of the bean “prototype” otherwise you will have issues in a multi-threaded environment. That should do it! You should be able to encrypt and decrypt files (streams really) using PGP!
Support for signed files
If you wish to support signed files, Mateusz Klos posted an excellent comment below that modifies the above code to support signed files.
I didn’t incorporate it into my code because I think he should get full credit for the modifications 🙂Common Errors
Illegal key size or default parameters
It’s yelling at you because the default JRE security can’t handle PGP.
You didn’t follow the instructions (above) on updating the JCE jars in your JRE’s lib/security directory.
Secret key for message not found
Regenerate you pubring and secring using the PGP tool. Odds are something is wrong with them
The Comments
(Note: Added 4/2/2010)
There had been a lot of great activity in the comments as well as some very kind readers who have posted code snippets to do things that my initial library did not do. I highly suggest you dig through the comments if what you are looking for is not in my original post.
Hi, how can i prove the code above?
Jaime, I’m not sure what you mean by ‘prove the code’. If you copy it into a class, run it from your code, that should be it.
Could you expand on what you mean?
Great post. Thank you for the source code.
Do you also happen to have a source code of a method for digitally signing the file using PGP private key?
I have a requirement where I need to digitally sign the file (using my private PGP key) and then encrypt it (using PGP public key). Any help will be appreciated.
Regards
Mateusz Klos
Mateusz,
Sorry, but I haven’t signed a file before.
From some quick searching (looking for ‘bouncy castle sign’) I found this article:
http://jopinblog.wordpress.com/2008/06/23/pgp-single-pass-sign-and-encrypt-with-bouncy-castle/
From the looks of it, the code you will be most interested in would be:
Good luck and if you come up with a nice solution please post it for others here for others to use!
I have implemented the single pass PGP Sign-and-Encrypt logic.
The code is based on your example – I have added a new method called signEncryptFile(). The code is tested and is working fine. Feel free to use/enhance it.
PGPUtils.java:
PGPFileProcessor.java:
I hope you will find it useful.
Mateusz Klos
I keep getting the “Secret key for message not found” message. I have a key already made (private/public) and I can’t change or re-make them. The key works with a dotnet component already, but we wanted to use Java. When I started to look at this solution, it seemed great, but I keep getting the same error message.
I kept the public and private keys in the same file and also tried keeping them in seprate files as solution, but nothing worked.
Any other suggestion? Anyone? Thanks a bunch.
Sorry for the delay in responding.
Have you tried using your own key to generate a file and decrypt it with your java code? Perhaps validating your code with something you know will work might point you to the underlying issue because if it doesn’t work for something you generated then you know you have something else going on.
Other than that I’m not sure. Did they perhaps sign the file as well?
Hi,
Thanks for the very nice post
I have seen many post on net but can not understand how ” passphrase” ( an additional parameter in decryption) is generated for decryption.While looking with encryption code I did not get any passphrase key which can be used in decryption.
Is there any relation between encryption mecahnism and passphrase? I have used “https://www.igolder.com/pgp/generate-key” to generate private and public keys but how this passpharse is generated ,please explain.
Thanks
Sumit
I got the answer.It is the password for key.
Hi,
thank you very much for useful post.
How about the reverse process of signing the message, i.e. *extracting* the content of signed message.
I was able to decrypt message with bouncy castle but I am unable to get plain content of signed message.
I would be very greatful for posting some code that do this part of job.
PS: I was googling quite extensively and tried following options:
http://bouncy-castle.1462172.n4.nabble.com/Getting-error-while-decrypting-a-signed-PGP-message-file-td1465973.html
http://wiki.service-now.com/index.php?title=Sample_Java_BouncyCastle_Algorithm_for_Encryption
http://boncode.blogspot.com/2012/01/java-implementing-pgp-single-pass-sign.html
Finally,
I’ve found one valid solution using org.bouncycastle.openpgp.examples.SignedFileProcessor#verifyFile.
The only needed modification is to add copying of data InputStream to the output file
Final result (search for IOUtils.copy):
Thanks for posting the solution!
Hi,
Kindly post the same kind of solution for Sign-in and encrypt a file.As most of the solution on net are confusing.
Thanks
Sumit
Hi,
I have the below piece of code for sign-in and encrypt.I have few doubt in the parameter passed to the signEncryptFile().Please clarify so that I can test the code.
Thanks
Sumit
Thanks for the great example! Exactly what I wanted. Concise and to the point. 🙂
Awesome work man! Keep it up 🙂
I am not able to decrypt a file. i getting the below exception .
I had given a private key(secring.skr) and passphrase key(Password for key) in my program. But still i am getting above exception.
please help me in resolving this. I have been trying for past 3 days but could not get to its bottom.
I have used the same code of yours.
Verify that the private key actually work (use it in another program or attempt to decrypt an encrypted file with it in another program).
I’m betting that you find that the key has an error or is not valid (your keyId could be invalid as well)
I am able to decrypt file using the pgp 6.5.8 using the passphrase. Also the content is decrypted properly. But I am not sure how to test private key(secring.skr) is invalid or not.
Hi
I am still not able to decrypt using java.
I am getting the following exception.
org.bouncycastle.openpgp.PGPException: error setting asymmetric cipher
at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder.decryptSessionData(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder.access$000(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactoryBuilder$2.recoverSessionData(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at com.tecnotree.PGPDecryption.decryptFile(PGPDecryption.java:52)
at com.tecnotree.PGPDecryption.main(PGPDecryption.java:23)
Caused by: java.security.InvalidKeyException: unknown key type passed to ElGamal
at org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.elgamal.CipherSpi.engineInit(Unknown Source)
at javax.crypto.Cipher.init(DashoA12275)
at javax.crypto.Cipher.init(DashoA12275)
... 9 more
Please find code I have written for decrypting.
package com.test;
import java.security.Security;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.*;
import java.util.Iterator;
import java.security.NoSuchProviderException;
public class PGPDecryption {
public static void main(String[] args) {
try {
Security.addProvider(new BouncyCastleProvider());
FileInputStream privKey = new FileInputStream(
"C:\\Program Files\\Network Associates\\PGPNT\\PGP Keyrings\\secring.skr");
InputStream file = new BufferedInputStream(new FileInputStream(
"C:\\testfiles\\BackUp\\MTNUGPO504.inp"));
decryptFile(file, privKey, "passphrase".toCharArray());
} catch (Exception ex) {
ex.printStackTrace();
}
}
@SuppressWarnings({"deprecation", "rawtypes"})
private static String decryptFile(InputStream in, InputStream keyIn,
char[] passwd) throws Exception {
try {
PGPObjectFactory pgpF = new PGPObjectFactory(
PGPUtil.getDecoderStream(in));
Object o = pgpF.nextObject();
PGPEncryptedDataList enc = o instanceof PGPEncryptedDataList ? (PGPEncryptedDataList) o
: (PGPEncryptedDataList) pgpF.nextObject();
Iterator it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
sKey = findSecretKey(keyIn, pbe.getKeyID(), passwd);
}
if (sKey == null) {
throw new IllegalArgumentException(
"secret key for message not found.");
}
InputStream clear = pbe.getDataStream(sKey, "BC");
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();
}
File outputfile = new File("decrypttest.out");
FileWriter writer = new FileWriter(outputfile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (message instanceof PGPLiteralData) {
PGPLiteralData ld = (PGPLiteralData) message;
InputStream unc = ld.getInputStream();
int ch;
while ((ch = unc.read()) >= 0) {
baos.write(ch);
writer.write(ch);
}
} 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("no message integrity check");
}
return baos.toString();
} catch (PGPException e) {
e.printStackTrace();
}
return null;
}
private static PGPPrivateKey findSecretKey(InputStream keyIn, long keyID,
char[] pass) throws IOException, PGPException,
NoSuchProviderException {
PGPSecretKey pgpSecKey = readSecretKey(keyIn);
return pgpSecKey != null ? pgpSecKey.extractPrivateKey(pass, "BC") : null;
}
public static PGPSecretKey readSecretKey(InputStream in)
throws IOException, PGPException {
PGPSecretKeyRingCollection keyRingCollection = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(in));
PGPSecretKey secretKey = null;
Iterator rIt = keyRingCollection.getKeyRings();
while (secretKey == null && rIt.hasNext()) {
PGPSecretKeyRing keyRing = (PGPSecretKeyRing) rIt.next();
Iterator kIt = keyRing.getSecretKeys();
while (secretKey == null && kIt.hasNext()) {
PGPSecretKey key = (PGPSecretKey) kIt.next();
if (key.isSigningKey()) {
secretKey = key;
}
}
}
// Validate secret key
if (secretKey == null) {
throw new IllegalArgumentException("Can't find private key in the key ring.");
}
if (!secretKey.isSigningKey()) {
throw new IllegalArgumentException("Private key does not allow signing.");
}
if (secretKey.getPublicKey().isRevoked()) {
throw new IllegalArgumentException("Private key has been revoked.");
}
if (!hasKeyFlags(secretKey.getPublicKey(), KeyFlags.SIGN_DATA)) {
throw new IllegalArgumentException("Key cannot be used for signing.");
}
return secretKey;
}
private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[] {
PGPSignature.POSITIVE_CERTIFICATION,
PGPSignature.CASUAL_CERTIFICATION, PGPSignature.NO_CERTIFICATION,
PGPSignature.DEFAULT_CERTIFICATION };
private static boolean hasKeyFlags(PGPPublicKey encKey, int keyUsage) {
if (encKey.isMasterKey()) {
for (int i = 0; i != MASTER_KEY_CERTIFICATION_TYPES.length; i++) {
for (Iterator eIt = encKey.getSignaturesOfType(MASTER_KEY_CERTIFICATION_TYPES[i]); eIt.hasNext();) {
PGPSignature sig = (PGPSignature) eIt.next();
if (!isMatchingUsage(sig, keyUsage)) {
return false;
}
}
}
}else {
for (Iterator eIt = encKey.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); eIt.hasNext();) {
PGPSignature sig = (PGPSignature) eIt.next();
if (!isMatchingUsage(sig, keyUsage)) {
return false;
}
}
}
return true;
}
private static final int KEY_FLAGS = 27;
private static boolean isMatchingUsage(PGPSignature sig, int keyUsage) {
if (sig.hasSubpackets()) {
PGPSignatureSubpacketVector sv = sig.getHashedSubPackets();
if (sv.hasSubpacket(KEY_FLAGS)) {
if ((sv.getKeyFlags() & keyUsage) == 0) {
return false;
}
}
}
return true;
}
}
I need to create a PGP encrypted fie without writing to a temp file.
Does anyone have suggestions?
I would think that if you just pass in a ByteArrayInputStream it might do it.
Hi,
I used PGP command line 6.5.8 to generate public key(pubring.pkr) and private key(secring.skr). I able to encrypt file with public key, but when try to decrypt file getting following PGPException:
This usually means that something is wrong with the key you are using. I would re-generate your keys and see if that fixes things.
Hi,
I am facing the same issue as Chenlei while extracting the private key:
Have you figured out the problem?
Chenlei never responded with a solution and I have not been able to investigate, sorry.
Does Bouncycastle supports DSS key to encrypt file.
I have keys both RSA and DSS in my pubring file but for RSA I am able to encrypt file but for DSS key bc readPublicKey() method then –>getPublicKey() method there is a check isEncryptionKey() which returning false for DSS.. n bouncycastle code works with this check true only.
So, not able to encrypt file using DSS key in pubring.Can I get solution and workaround for this?
Hi Ricky,
A quick google for “bouncycastle dss” shows quite a bit of chatter around this. You might want to try that.
I able to encrypt using Java. But while using java decrypt I am getting following error.
java.lang.IllegalArgumentException: Secret key for message not found.
But I able encrypt and decrypt using PGPTray {tool} Using PGP 6.5 Version.
Please help me debug this issue.
thanks,
Srini.
This is a pretty common error and I think it is covered in some of the other comments. There is usually something wrong with the way you are processing the secret key file.
I re-generated my keys and it fixed the errors. Now I able to Encrypt and Decrypt PGP file using Java.
Hi
encrypting the file by using globalscape tool and generating publickey and private key and passphrase.
While I am trying to decrypt the file by using private key and passphrase I am getting the below error.
I am getting error while reading the key at the below line
PGPSecretKeyRingCollection collection = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(new FileInputStream(“D:\\Thulasiram\\MFT\\INputs\\AES256\\IPM_AES256.asc”)) );
error:
java.io.IOException: unknown object in stream: 21
at org.bouncycastle.openpgp.PGPObjectFactory.nextObject(Unknown Source)
at org.bouncycastle.openpgp.PGPSecretKeyRingCollection.(Unknown Source)
I need urgent help . please help me in this
The file is correct or of an incorrect format. Make sure the file you are passing in is good.
HI,
I am using the correct file(pgp private key used RSA algorithm). with the global space tool they are successfully able to decrypt the file using the key. But when iam trying to decrypt the file in java iam getting the above error while reading the key. after debugging i got the below doubt.
Can we decrypt any file if we have pgp private key in java using the above code? I mean do we need use same vendor’s (the tool which is generating keys and encryptinh)jdk to decrypt ? Can i use above code to decrypt any encyted file if i have the privatekey and passphrase. and if i know the algorithm used.
As long as the vendor is following the PGP standard you should be able to. The code above only works for PGP however, no other algorithm.
it is run into an android application?
Does ti run in Android? It should since it is Java.
I am using the .Net C# solution from Bouncy castle. I was able to create private and public keys in ascii armor format with no issues. A client enrypted a file for us using our public pgp key and sent us the file which has the .asc file ext which seems correct.
When I call the Decryption method the code throws a casting exception which I noted about 3/4 down in the code block. Any ideas would be appreciated. I understand what a casting error is but I am not sure where to look upstream of the error for why the cast blew up. I am using the code verbatim from the C# zipped solution, but it may be a very simple thing that I am missing.
The exception is:
Unable to cast object of type ‘Org.BouncyCastle.Bcpg.OpenPgp.PgpOnePassSignatureList’ to type ‘Org.BouncyCastle.Bcpg.OpenPgp.PgpCompressedData’.
The code block that I am using from the BC KeyBasedFileProcessor class:
Usually this means there is something wrong with the file that is being processed. In this case it appears to be looking for compressed data when instead it is finding something else. I’d first verify that you can encrypt/decrypt correctly with another tool. If you can then I’d start digging into the source code for BC to see exactly what is happening.
I am using your code for decryption which is not encrypted my us. All files works fine however one of the file which large data of around 1GB doesn’t decrypt fully and gives following error
Unexpected end of ZIP input stream
Can you please help
A file that big may be blowing our the buffer. Make sure you have enough memory allocated via the jvm cmd line arguments.
Hello,
If I use pgptools, I can pick which key to use to encrypt. How do I do the same with the encrypt function you list?
Feed the key in via the InputStream and it will use that key
Hi
I am new to bouncy castle api. I was able to encrypt the file using your solution. but cannot able to decrypt it.
i have key file abc.gpgkey , which i have exported to my linux system. it gave me “abc.asc”.
using that i was able to do encrypt.
but it does not have any password or paraphrase. so what should i send while invoking decrypt .
help would be appreciated.
You’ll need to set something. Even if it is a password like “test”, you should have some type of seed.
Hi ,
I am new to bouncy castle api. I am able to encrypt the file but I am not getting –BEGIN PGP—- & the —END PGP— markers in the encrypted file. And manually adding these markers to the files the files gets encrypted successfully.
–really don’t know what I am missing in the code.
Any help would be appreciated
Regards,
Sumit
Are you encrypting via the API or some other tool?
this code give NullPointerException.
my requirement is
1)take simple text file to encrypted file using public key.
2)again decrypt same encrypted file using private key and passphrase.
please give me jar with all required lib file.
thanks
Um.. wow. No.
Part of being a computer scientist is the “science” part. Do your research, read online, EXPERIMENT!
ok
but please help me
i have done some thing its working in eclipse but when i create executable jar its give me below error.
output :—–
Encryption jar Error
—————————————
Reading public key………
Public Key found………..
File Encrypting…………
Exception in thread “main” java.lang.NoSuchMethodError: org.bouncycastle.openpgp
.PGPEncryptedDataGenerator.(IZLjava/security/SecureRandom;Ljava/lang/Strin
g;)V
at org.pgp.util.KeyBasedFileProcessorUtil.encryptFile(KeyBasedFi
leProcessorUtil.java:389)
at org.pgp.encrypt.PGPEncryption.main(PGPEncryptio
n.java:69)
—————————————-
Decryption jar error
—————————-
File Decrypting
secret key…………..
Exception in thread “main” java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoa
der.java:58)
Caused by: java.lang.NoSuchMethodError: org.bouncycastle.openpgp.PGPSecretKey.ex
tractPrivateKey([CLjava/lang/String;)Lorg/bouncycastle/openpgp/PGPPrivateKey;
at org.pgp.util.KeyBasedFileProcessorUtil.findSecretKey(KeyBased
FileProcessorUtil.java:124)
at org.pgp.util.KeyBasedFileProcessorUtil.decryptFile(KeyBasedFi
leProcessorUtil.java:172)
at org.pgp.encrypt.PGPDecryption.main(PGPDecryptio
n.java:49)
… 5 more
it is possible to encrypt and decrypt file using private key?
my requirement is public key is share with publicly, they encrypt file using public key and i have private key only for decrypt that file and using same private key encrypt file again because i don’t have public key.
thanks
hi,
now i am facing new error
i have added US_export_policy.jar and local_policy.jar in jre and add bcpg and bcprov jar also added. then also i am facing below error
org.bouncycastle.openpgp.PGPException: Exception starting decryption
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at com.posidex.pgp.util.KeyBasedFileProcessorUtil.decryptFile(KeyBasedFileProcessorUtil.java:182)
at com.posidex.pgp.encrypt.PosidexPGPDecryption.main(PosidexPGPDecryption.java:49)
Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
… 5 more
org.bouncycastle.openpgp.PGPException: Exception starting decryption
java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at org.bouncycastle.openpgp.PGPPublicKeyEncryptedData.getDataStream(Unknown Source)
at com.posidex.pgp.util.KeyBasedFileProcessorUtil.decryptFile(KeyBasedFileProcessorUtil.java:182)
at com.posidex.pgp.encrypt.PosidexPGPDecryption.main(PosidexPGPDecryption.java:49)
Decrypted File created with name of E:/Encyption/final/out.txt
Please help me,
i am using GPG4Win for encrypt the file and then your code for decrypt file its give previous post error.
suppose i use your code for encrypt file and then use your decryption code its able to decrypt file and GPG4win also able to decrypt the file.
please help me i want to decrypt the file those encrypted by GPG4win
both using same algorithm or different. please give me some guide line.
Most likely the key is corrupt or not correct for the algorithm. I suggest you try encrypting and decrypting with the same key and see what happens
key don’t have any problem
actually code is able to encrypt/decrypt file. but suppose file is encrypted by pgp4win then its not decrypt by code.
my complete project download from below link
https://drive.google.com/file/d/0B5FTVD7kU2pxNDNnTnl0ckpSQ28/edit?usp=sharing