Unable to create password protected existing PDF file - java

I am trying to make password protected PDF file which is already created in my directory .
Below is my sample code:
try {
PdfReader pdfReader = new PdfReader("D:/test/SI1491232250299.pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream("D:/test/SI1491232250299.pdf"));
pdfStamper.setEncryption("abc".getBytes(), "abc".getBytes(), PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
pdfStamper.close();
} catch (Exception e) {
e.printStackTrace();
}
After execution got java.io.EOFException exception

Related

FileoutputStream FileNotFoundException

I'm using java SE eclipse.
As I know, When there are no file named by parameter FileOutputStream constructor create new file named by parameter. However, with proceeding I see that FileOutputStream make exception FileNotFoundException. I really don't know Why this exception needed. Anything wrong with my knowledge?
My code is following(make WorkBook and write into file. In this code, although there are no file "data.xlsx", FileOutpuStream make file "data.xlsx".
public ExcelData() {
try {
fileIn = new FileInputStream("data.xlsx");
try {
wb = WorkbookFactory.create(fileIn);
sheet1 = wb.getSheet(Constant.SHEET1_NAME);
sheet2 = wb.getSheet(Constant.SHEET2_NAME);
} catch (EncryptedDocumentException | InvalidFormatException | IOException e) {
e.printStackTrace();
} // if there is file, copy data into workbook
} catch (FileNotFoundException e1) {
initWb();
try {
fileOut = new FileOutputStream("data.xlsx");
wb.write(fileOut);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} // if there is not file, create init workbook
} // ExcelData()
If anything weird, please let me know, thank you
It will throw a FileNotFoundException if the file doesn't exist and cannot be created (doc), but it will create it if it can. To be sure you probably should first test that the file exists before you create the FileOutputStream (and create with createNewFile() if it doesn't)
File yourFile = new File("score.txt");
yourFile.createNewFile();
FileOutputStream oFile = new FileOutputStream(yourFile, false);
Answer from here: Java FileOutputStream Create File if not exists
There is another case, where new FileOutputStream("...") throws a FileNotFoundException, i.e. on Windows, when the file is existing, but file attribute hidden is set.
Here, there is no way out, but resetting the hidden attribute before opening the file stream, like
Files.setAttribute(yourFile.toPath(), "dos:hidden", false);

How to check if xlsx file is password protected or not using apache poi

How to check if xlsx file is password protected or not. we can check for xls file as follows
FileInputStream fin = new FileInputStream(new File("C:/Book1.xls"));
POIFSFileSystem poifs = new POIFSFileSystem(fin);
EncryptionInfo info = new EncryptionInfo(poifs);
Decryptor d = Decryptor.getInstance(info);
try {
if (!d.verifyPassword(Decryptor.DEFAULT_PASSWORD)) {
throw new RuntimeException("Unable to process: document is encrypted");
}
InputStream dataStream = d.getDataStream(poifs);
HSSFWorkbook wb = new HSSFWorkbook(dataStream);
// parse dataStream
} catch (GeneralSecurityException ex) {
throw new RuntimeException("Unable to process encrypted document", ex);
}
But the above code works for only xls not for xlsx.
First,
public boolean isEncrypted(String path) {
try {
try {
new POIFSFileSystem(new FileInputStream(path));
} catch (IOException ex) {
}
System.out.println("protected");
return true;
} catch (OfficeXmlFileException e) {
System.out.println("not protected");
return false;
}
}
then,
if (isEncrypted(sourcepath)) {
org.apache.poi.hssf.record.crypto.Biff8EncryptionKey.setCurrentUserPassword("1234");
POIFSFileSystem filesystem = new POIFSFileSystem(new FileInputStream(inpFn));
EncryptionInfo info = new EncryptionInfo(filesystem);
Decryptor d = Decryptor.getInstance(info);
if (!d.verifyPassword("1234")) {
System.out.println("Not good");
} else {
System.out.println("Good!");
}
in = d.getDataStream(filesystem);
} else {
in = new FileInputStream(inpFn);
}
try {
XSSFWorkbook wbIn = new XSSFWorkbook(in);
.
.
.
If you don't know what you have, but you know the password, then you should use WorkbookFactory.create and pass the password to it, eg
Workbook wb = WorkbookFactory.create(new File("protected.xls"),
"NiceSecurePassword");
WorkbookFactory will identify the type, then call the appropriate decryption and workbook loading for you. If the file isn't protected, the password will be ignored
.
If you know for sure that the file is .xlsx based, but aren't sure if it is protected or not, then you can do something like:
Workbook wb = null;
try {
wb = new XSSFWorkbook(new File("test.xlsx"));
} catch (EncryptedDocumentException e) {
// Password protected, try to decrypt and load
}
If you give the XSSFWorkbook a password protected .xlsx file, it'll throw a EncryptedDocumentException which you can catch and then try decrypting, based on the code you've already got
Try using
XSSFWorkbook wb = new XSSFWorkbook(dataStream);
From Apache POI: "HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format. XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format." http://poi.apache.org/spreadsheet/ You're using the HSSF (which will work for xls) on a XLSX file.

Give password protection to existing pdf file

Am trying to give password to an existing pdf file. It is working for a jasper report which is saved with .jrxml or .jasper but how to give it for pdf file.
Sample code:
public static void main(String[] args) {
String USER="Sai123";
String OWNER="Sairam";
try {
InputStream input=new FileInputStream(new File("D:\\Project1\\EmailSendExample\\WebContent\\PDFiles\\AnnexI.pdf"));
OutputStream file = new FileOutputStream(new File("D:\\Test.pdf"));
/*PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\Test.pdf"));
stamper.setEncryption(PdfWriter.ALLOW_PRINTING, OWNER,USER, PdfWriter.ENCRYPTION_AES_128 | PdfWriter.DO_NOT_ENCRYPT_METADATA);
stamper.close();
reader.close();*/
JRPdfExporter exporter = new JRPdfExporter();
//exporter.setParameter(JRExporterParameter.INPUT_FILE, new File("D:\\Project1\\EmailSendExample\\WebContent\\PDFiles\\AnnexI.pdf"));
exporter.setParameter(JRExporterParameter.OUTPUT_FILE,new File("D:\\Test.pdf"));
exporter.setParameter(JRPdfExporterParameter.OWNER_PASSWORD, "Sai123");
exporter.setParameter(JRPdfExporterParameter.USER_PASSWORD, "Sairam");
exporter.setParameter(JRPdfExporterParameter.IS_ENCRYPTED, Boolean.TRUE);
exporter.exportReport();
System.out.println("Report Generation Complete");
file.close();
} catch (Exception e) {
e.printStackTrace();
}
it is throwing error like
net.sf.jasperreports.engine.JRException: No input source supplied to the exporter.
at net.sf.jasperreports.engine.JRAbstractExporter.setInput(JRAbstractExporter.java:922)
at net.sf.jasperreports.engine.export.JRPdfExporter.exportReport(JRPdfExporter.java:296)
at pdfpassword.main(pdfpassword.java:45)
Thanks in advance for your valuable suggestions.
According to me,we cannot provide pdf file as input to JRexporter. so in order to make existing pdf password protected use the code below.It works for me.
code:
private static String USER_PASSWORD = "password";
private static String OWNER_PASSWORD = "naveen";
public static void main(String[] args) throws IOException {
try
{
PdfReader pdfReader = new PdfReader("/home/base/Desktop/newtask/ext.pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader,new FileOutputStream("/home/base/Desktop/newtask/ext1.pdf"));
pdfStamper.setEncryption(USER_PASSWORD.getBytes(),OWNER_PASSWORD.getBytes(), PdfWriter.ALLOW_PRINTING,PdfWriter.ENCRYPTION_AES_128);
pdfStamper.close();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (com.itextpdf.text.DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I see this line commented -
//exporter.setParameter(JRExporterParameter.INPUT_FILE, new File("D:\\Project1\\EmailSendExample\\WebContent\\PDFiles\\AnnexI.pdf"));
And exception talks about input -
net.sf.jasperreports.engine.JRException: No input source supplied to the exporter.

How to check if a PDF is Password Protected or not

I am trying to use iText's PdfReader to check if a given PDF file is password protected or not, but am getting this exception:
Exception in thread "Main Thread" java.lang.NoClassDefFoundError:org/bouncycastle/asn1/ASN1OctetString
But when testing the same code against a non-password protected file it runs fine. Here is the complete code:
try {
PdfReader pdf = new PdfReader("C:\\abc.pdf");
} catch (IOException e) {
e.printStackTrace();
}
In the old version of PDFBox
try
{
InputStream fis = new ByteArrayInputStream(pdfBytes);
PDDocument doc = PDDocument.load(fis);
if(doc.isEncrypted())
{
//Then the pdf file is encrypeted.
}
}
In the newer version of PDFBox (e.g. 2.0.4)
InputStream fis = new ByteArrayInputStream(pdfBytes);
boolean encrypted = false;
try {
PDDocument doc = PDDocument.load(fis);
if(doc.isEncrypted())
encrypted=true;
doc.close();
}
catch(InvalidPasswordException e) {
encrypted = true;
}
return encrypted;
Use Apache PDFBox - Java PDF Library from here:Sample Code:
try
{
document = PDDocument.load( "C:\\abc.pdf");
if(document.isEncrypted())
{
//Then the pdf file is encrypeted.
}
}
The way I do it is by attempting to read the PDF file using PdfReader without passing a password of course. If the file is password protected, a BadPasswordException will be thrown. This is using the iText library.
Here's a solution that doesn't require 3rd party libraries, using the PdfRenderer API.
fun checkIfPdfIsPasswordProtected(uri: Uri, contentResolver: ContentResolver): Boolean {
val parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")
?: return false
return try {
PdfRenderer(parcelFileDescriptor)
false
} catch (securityException: SecurityException) {
true
}
}
Reference: https://developer.android.com/reference/android/graphics/pdf/PdfRenderer
try {
PdfReader pdfReader = new PdfReader(String.valueOf(file));
pdfReader.isEncrypted();
} catch (IOException e) {
e.printStackTrace();
}
Using iText PDF library you can check. If it went to an exception handle it(ask for password)
Try this code:
boolean isProtected = true;
PDDocument pdfDocument = null;
try
{
pdfDocument = PDDocument.load(new File("your file path"));
isProtected = false;
}
catch(Exception e){
LOG.error("Error while loading file : ",e);
}
Syste.out.println(isProtected);
If your document is password protected then it can not load document and throw IOException.
Verified above code using pdfbox-2.0.4.jar
public boolean checkPdfEncrypted(InputStream fis) throws IOException {
boolean encrypted = false;
try {
PDDocument doc = PDDocument.load(fis);
if (doc.isEncrypted())
encrypted = true;
doc.close();
} catch (
IOException e) {
encrypted = true;
}
return encrypted;
}
Note: There is one corner case in iText some file are encrypted protected but open without a password, to read those files and add water mark like this
PdfReader reader = new PdfReader(src);
reader.setUnethicalReading(true);
I didn't want to use any third party library, so i used this -
try {
new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
} catch (Exception e) {
e.printStackTrace();
// file is password protected
}
If the file was password protected, i didn't use it.

Create a Word file using POI

My requirement is that I should read a template file and change some values in its content and write it back to another file. Most importantly it should have the same styles as that of the template.
The problem I face is that I am able to read and write, but its very difficult to transfer the styles as well. Especially I am tired trying to apply the paragraph styles to the document. Pls help me..... this is my code
public static void main(String[] args) {
try {
HWPFDocument templateFile = new HWPFDocument(new FileInputStream("D:\\POI\\testPOIin.doc"));
HWPFDocument blankFile = new HWPFDocument(new FileInputStream("D:\\POI\\blank.doc"));
ParagraphProperties pp = templateFile.getRange().getParagraph(4).cloneProperties();
blankFile.getRange().insertAfter(pp, 0);
OutputStream out = new FileOutputStream("D:\\POI\\testPOIout.doc");
blankFile.write(out);
} catch (FileNotFoundException fnfe) {
// TODO: Add catch code
fnfe.printStackTrace();
} catch (Exception ioe) {
// TODO: Add catch code
ioe.printStackTrace();
}
}
}
Pls let me know that I am doing wrong.....
I also had similar task and after investigation i created solution, but it works only for docx files:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream(new File("transformed.docx"));
XWPFDocument doc = new XWPFDocument(new FileInputStream(new File("original.docx")));
for(XWPFParagraph p:doc.getParagraphs()){
for(XWPFRun r:p.getRuns()){
for(CTText ct:r.getCTR().getTList()){
String str = ct.getStringValue();
if(str.contains("NAME")){
str = str.replace("NAME", "Java Dev");
ct.setStringValue(str);
}
}
}
}
doc.write(fos);
}
it operates on low level elements so it saves styles and other props. Hope it will help somebody.

Categories