I developed a PDF Encoder which normaly removes the password and enable editing and this stuff.
But now there is a file which is protected by a certificate and it's forbidden to change anything but the type is no security.
I tryed this code:
PDDocument doc = PDDocument.load(input);
AccessPermission perms = new AccessPermission();
perms.setCanAssembleDocument(true);
perms.setCanExtractContent(true);
perms.setCanModify(true);
perms.setCanModifyAnnotations(true);
perms.setCanExtractForAccessibility(true);
perms.setCanFillInForm(true);
perms.setCanPrint(true);
perms.setCanPrintDegraded(true);
perms.setCanExtractForAccessibility(true);
StandardProtectionPolicy policy = new StandardProtectionPolicy("secret", "", perms);
doc.protect(policy);
doc.setAllSecurityToBeRemoved(true);
doc.save(output);
But it's only working on password protected files.
Anyone knows the mistake / soultion?
My guess is the file is encrypted using certificates and not using standard password method. In this situation unless you have the corresponding certificate for decryption there is nothing you can do.
Related
I would like to get the email address and expire date to a S/MIME certificate based on it's public key. Is this aproach even possible? Or am I totally wrong? Can I decrypt the public key to get these kind of data via java?
I searched in google, read the wiki pages and read about an oracle s/mime project. But it doesn't seam like its possible. Are those data only availabe in the csr??
Thanks in advance
I'm amazed this isn't a dupe, but I couldn't find a good one.
Although Bouncy is fine and has many features if you want to use it, core Java can handle X.509 certificates since forever. For a cert in a file (or anything that can be accessed as a Stream) in either PEM or DER format (although the javadoc isn't clear on that) all you need is CertificateFactory:
CertificateFactory fact = CertificateFactory.getInstance("X.509");
// from a real file
InputStream is = new FileInputStream ("filename");
Certificate cert = fact.generateCertificate(is);
is.close(); // or use try-resources to do automatically
// from an alternate/custom filesystem, such as a ZIP
Path p = Paths.get("somespecification"); // or any other creation of a Path
InputStream is = Files.newInputStream(p); // add open options if needed
// same as before
// from the classpath (usually a JAR)
InputStream is = ClassLoader /*or any Class<?> object*/ .getResourceAsStream("name");
// same as before
// from a byte[] in memory
InputStream is = new ByteArrayInputStream (bytearray);
// same as before, except don't really need to close
// you get the idea
Although JCA APIs like this one are defined to allow a lot of extension, reading an X.509 cert will actually give you not just Certificate but subclass X509Certificate from which .getNotAfter() gives the expiration date-time directly. The email address if present (which isn't required by X.509 certs in general, but should always be the case in a cert used for S/MIME) will usually be an attribute in the subject name, which actually has internal structure that Java doesn't let you get at directly so you need to:
String x500name = ((X509Certificate)cert).getSubjectX500Principal()) .toString();
// simple case: no multivalue RDN, no reserved chars ,+="<>\;# or extra spaces
for( String attr : x500name.split(", ") )
if( attr.startsWith("EMAILADDRESS=") )
... use attr.substring(13) ...
// other cases require slightly more complicated parsing
Note there is no encryption at all in X.509, and thus no actual decryption, although many people use 'decrypt' to describe anything unfamiliar not an actual cipher.
File file = new File(fileName);
FileReader fileReader = new FileReader(file);
PEMParser pemParser = new PEMParser(fileReader);
X509CertificateHolder caCertificate = (X509CertificateHolder) pemParser.readObject();
I have two secured pdf files. One has a password and the other one is secured but without password. I am using PDF Box.
How can I identify which file has password and which one is secured but without password?
PDF's have two type of encryption -
Owner password - Password set by PDF owner / creator to restrict its usage (e.g. edit, print, copy etc)
User password - Password set to open / view the PDF
PDF can have only owner password or both; but not only user password. In either case the PDF is termed to be encrypted and there is no direct API to distinguish between two kind of encryption.
In case of PDFBox you can use below code snippet to determine if it is encrypted or not; and distinguish whether it has only owner password or both.
PDDocument pdfDoc = PDDocument.load(new File("path/to/pdf"));
boolean hasOwnerPwd = false;
boolean hasUserPwd = false;
if(pdfDoc.isEncrypted()){
hasOwnerPwd = true;
try{
StandardDecryptionMaterial sdm = new StandardDecryptionMaterial(null);
pdfDoc.openProtection(sdm);
hasUserPwd = true;
} catch(Exception e){
// handle exception
}
}
See PDFBox API docs here and here.
EDIT Thanks to Tilman to point out latest code and alternate way to determine / distinguish between two encryption. Updated the code snippet and post accordingly.
Is it possible to set owner password as some value and user password as null or empty while using set encryption method of PdfWriter class?
I tried using code something like this
String OWNER = "test";
PdfWriter.setEncryption(null,OWNER.getBytes(),
PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
I am able to open PDF generated with this code without entering any password.
BUT when I try to open it for editing with Adobe Acrobat, it opens the document in view mode and throws an error "This is secured document. Editing is not permitted."
Screenshot of error: http://dropbox.com/s/1ef551o1z0n9ug1/editerror.jpg
Any idea why this must be occurring? Am I doing something wrong?
On an additional note,
I have generated this new document with
PdfWriter.setEncryption("test1".getBytes(),"test".getBytes(),
PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
Link: http://dropbox.com/s/8jeia7ezervrz18/Test_Success.pdf
I am able to view it after entering password as "test1" and able to edit it with password "test". I am not sure what exactly is going wrong when I pass USER as null in earlier case.
I am using following set of jars in my project
itext-2.1.7.jar
bcmail-jdk14.jar
bcprov-jdk14.jar
private static String user = "";
private static String admin = "ADMIN";
writer.setEncryption(admin.getBytes(), user.getBytes(),
PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
By using the above approach you can set admin password. There might be some problem in your classpath setting. Use Mavel on Gardle for dependencies
How to display details of the subject in a certificate (DER format ie .cer file) in java ? eg: email, country, Name or seperate OIDs etc.
Reading a certificate could be done from the above code. Will work in Android as well. Thank you GreyBeardedGeek. But to more elaborate on it (As curious requested), if you display the subject details by using methods getSubjectDN() or cert.getSubjectX500Principal().getname() it will display the whole details. Some may be encoded. I believe it ASN1.(not sure). What I need is to extract only the information I need. For an example please refer the output of the code for a sample certificate I had created. using method - cert.getSubjectX500Principal().getname() Subject Name 2.5.4.5=#130d4e2d61626c652f49542f303130,2.5.4.72=#1308456e67696e656572,2.5.4.41=#13104e7577616e20446520416c6d65696461,1.2.840.113549.1.9.1=#16106e7577616e406e2d61626c652e62697a,OU=Information Technology,O=N-able Pvt Ltd\ ,ST=Western,C=LK
2.5.4.5 is an OID (Object Identifier) which is encoded.
Using method - getSubjectDN()
OID.2.5.4.5=N-able/IT/010, OID.2.5.4.72=Engineer, OID.2.5.4.41=Nuwan De Almeida, OID.1.2.840.113549.1.9.1=#16106E7577616E406E2D61626C652E62697A, OU=Information Technology, O="N-able Pvt Ltd ", ST=Western, C=LK
Here also some information is encoded eg: email address.
So coming back to my question , how can we extract information(not encoded) separately based on the OID. Further if you install the certificate in windows OS you could view the subject information correctly.What I need is a code to get the OID value information passing the OID in java, to extract subject details separately.
Thank you again in advance.
Look into the Bouncy Castle ASN.1 parsing libraries and especially X500Name. It can parse a distinguished name (DN) into its parts (CN, O, etc.).
http://www.bouncycastle.org/docs/docs1.5on/index.html
The following code (no error handling included) will produce an instance of X509Certificate from the .cer file. You can then use that object's methods to inspect the properties of the certificate. The code is generic java, but should work in Android.
X509Certificate cert = null;
FileInputStream fis = null;
ByteArrayInputStream bais = null;
String source = "certificate.cer";
String certType = "X.509"
fis = new FileInputStream(source);
byte[] value = new byte[fis.available()];
fis.read(value);
bais = new ByteArrayInputStream(value);
java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance(certType);
cert = (X509Certificate)cf.generateCertificate(bais);
I need upload a image into Google doc with google format in order to retrieving it back and saving the storage uasage as well. Below it my code sample, it was work fine but broken recently, What I got just a empty document. Could anyone help me?
DocsService client = new DocsService("testappv1");
client.setUserCredentials(username, password);
client.setProtocolVersion(DocsService.Versions.V2);
File file = new File("C:/test.jpg");
DocumentEntry newDocument = new DocumentEntry();
newDocument.setTitle(new PlainTextConstruct("test"));
String mimeType = DocumentListEntry.MediaType.fromFileName(file.getName()).getMimeType();
newDocument.setMediaSource(new MediaFileSource(file, mimeType));
newDocument = client.insert(destFolderUrl, newDocument);
Please have a look at this answer. Also, remove this line from your code:
client.setProtocolVersion(DocsService.Versions.V2);
You should use the default version (3.0) whenever possible.