Apache PDFBox - can't decrypt PDF - java

I have a problem with decrypting a PDF document with Apache PdfBox (v1.8.2) lib. Encryption works, but decryption with the same password throws an exception. (Java 1.6)
package com.test;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardDecryptionMaterial;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
public class PdfEncDecTest {
static String pdfPath = "G:\\files\\filed5b3.pdf";
public final static String PDF_OWNER_PASSWORD = "cd1j";
public final static String PDF_USER_PASSWORD = "";
public static void main(String[] args) throws Exception {
PDDocument document = PDDocument.load(pdfPath);
AccessPermission ap = new AccessPermission();
ap.setCanPrint(true);
ap.setCanExtractContent(false);
ap.setCanExtractForAccessibility(false);
StandardProtectionPolicy spp = new StandardProtectionPolicy(PDF_OWNER_PASSWORD, PDF_USER_PASSWORD, ap);
document.protect(spp);
document.save(pdfPath+".pdf");
document.close();
PDDocument doc = PDDocument.load(pdfPath+".pdf");
if(doc.isEncrypted()) {
StandardDecryptionMaterial sdm = new StandardDecryptionMaterial(PDF_OWNER_PASSWORD);
doc.openProtection(sdm); // org.apache.pdfbox.exceptions.CryptographyException: Error: The supplied password does not match either the owner or user password in the document.
doc.decrypt(PDF_OWNER_PASSWORD); // the same like above
}
doc.close();
}
}
I don't know what is wrong. With version 1.8.7 I get the same exception. I've posted the full code above.
Exception in thread "main" org.apache.pdfbox.exceptions.CryptographyException: Error: The supplied password does not match either the owner or user password in the document.
at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.prepareForDecryption(StandardSecurityHandler.java:265)
at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.decryptDocument(StandardSecurityHandler.java:156)
at org.apache.pdfbox.pdmodel.PDDocument.openProtection(PDDocument.java:1595)
at org.apache.pdfbox.pdmodel.PDDocument.decrypt(PDDocument.java:942)
at com.test.PdfEncDecTest.main(PdfEncDecTest.java:29)
I've put sample project to github: https://github.com/marioosh-net/pdfbox

You need the user password.
if (doc.isEncrypted())
{
StandardDecryptionMaterial sdm = new StandardDecryptionMaterial(PDF_USER_PASSWORD);
doc.openProtection(sdm);
// don't call decrypt() here
}
this works even if the user password is not null. The user password is for what the ordinary human thinks encryption is, the owner password is an encryption for the security rights.
edit: sorry, my answer is wrong, although it was helpful. You can open a PDF with the user password (you'll possibly get restricted rights) or with the owner password (you'll get full rights). What may have happened is that there is a bug with matching the owner password with 40bit keys (which is the
default). This bug is currently being investigated, see PDFBOX-2456 and search for "MD5".

I have tested your code and it work's fine for me.
i am using
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>1.8.7</version>
</dependency>

Related

Aspose License not working correctly for spring-boot application

I have a spring-boot application which has a public rest api endpoint. The api extracts text from a given pdf file. I am loading the Aspose license in a static initialising block and it loads correctly.
public class AsposeLicenseLoader {
private static Logger logger = LoggerFactory.getLogger(AsposeLicenseLoader.class);
private static boolean isLicenseLoaded;
public static void doLoad(AsposeConfig asposeConfig) {
String location = asposeConfig.license().location();
logger.debug("Loading Aspose license \"{}\"", location);
try (InputStream is = AsposeLicenseLoader.class.getClassLoader()
.getResourceAsStream(location)) {
com.aspose.pdf.License pdfLicense = new com.aspose.pdf.License();
pdfLicense.setLicense(is);
isLicenseLoaded = true;
logger.info("Aspose license loading completed");
} catch (Exception e) {
logger.error("Unable to load the Aspose license", e);
}
}
public static boolean isAsposeLicenseLoaded() {
return isLicenseLoaded;
}
When I try to extract text from pdf the output shows the license is not applied correctly with the following output.
Evaluation Only. Created with Aspose.Pdf. Copyright 2002-2017 Aspose Pty Ltd.
The the text extraction logic in my application below.
com.aspose.pdf.Document pdfDocument = new com.aspose.pdf.Document(filePath);
// Create TextAbsorber object to extract text
com.aspose.pdf.TextAbsorber textAbsorber = new com.aspose.pdf.TextAbsorber();
// Accept the absorber for all the pages
pdfDocument.getPages().accept(textAbsorber);
// Get the extracted text
extractedText = textAbsorber.getText();
However if I explicitly load the license just before the text is extracted then it applies the license correctly and extracts the full text from the file. As per the documentation of aspose I only need to load the license once and not for each incoming request. Does anyone know if I am missing anything here?
I have looked at the official aspose documentation and followed their instructions. Also looked at similar issues posted by other members.
https://forum.aspose.com/t/loading-aspose-license-in-aspose-java/62945/2

JDeveloper don't find SignerEPES having xades4j.jar

Im using #lgoncalves code to sign an XML with XADES4J EPES. But however jdeveloper don't find (SignerEPES) when I have the xades4j.jar on my classpath. I let you the image of my library and the code:
Project Library
private static void signBes(Document doc) throws XadesProfileResolutionException, XAdES4jException,
KeyStoreException {
//Document doc = getTestDocument();
Element elemToSign = doc.getDocumentElement();
SignaturePolicyInfoProvider policyInfoProvider = new SignaturePolicyInfoProvider()
{
#Override
public SignaturePolicyBase getSignaturePolicy()
{
return new SignaturePolicyIdentifierProperty(
new ObjectIdentifier("oid:/1.2.4.0.9.4.5", IdentifierType.OIDAsURI, "Policy description"),
new ByteArrayInputStream("Test policy input stream".getBytes()))
.withLocationUrl(""); //<- I really don't know what to put right here.
}
};
KeyingDataProvider kdp = new FileSystemKeyStoreKeyingDataProvider("pkcs12","C:/****/****.pfx",new FirstCertificateSelector(),new DirectPasswordProvider("****"),new DirectPasswordProvider("****"),true);
SignerEPES signer = (SignerEPES) new XadesEpesSigningProfile(kdp, policyInfoProvider).newSigner();
new Enveloped(signer).sign(elemToSign);
}
Link to the sample code on GitHub: https://github.com/luisgoncalves/xades4j/blob/master/src/test/java/xades4j/production/SignerEPESTest.java
EDIT:
I tried to force the import like (import xades4j.production.SignerEPES) but IDE says "Cannot be accessed from outside package" but really don't know what that means
SignerEPES is a package-private class, so application code won't be able to import it. The tests use it just to be sure that the proper type is being returned.
In your code you can just use XadesSigner as the type of your variable.

Why Java Azure Function App freezes when trying to access Azure datalake?

I am developing a Java Azure function that needs to download a file from Azure Datalake Gen2.
When the function tries to read the file, it freezes and no exception is thrown, and nothing is written to the console.
I am using the azure-storage-file-datalake SDK for Java dependency and this is my code:
import com.azure.storage.common.StorageSharedKeyCredential;
import com.azure.storage.file.datalake.DataLakeDirectoryClient;
import com.azure.storage.file.datalake.DataLakeFileClient;
import com.azure.storage.file.datalake.DataLakeFileSystemClient;
import com.azure.storage.file.datalake.DataLakeServiceClient;
import com.azure.storage.file.datalake.DataLakeServiceClientBuilder;
public DataLakeServiceClient GetDataLakeServiceClient(String accountName, String accountKey)
{
StorageSharedKeyCredential sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
DataLakeServiceClientBuilder builder = new DataLakeServiceClientBuilder();
builder.endpoint("https://" + accountName + ".dfs.core.windows.net");
builder.credential(sharedKeyCredential);
return builder.buildClient();
}
public void DownloadFile(DataLakeFileSystemClient fileSystemClient, String fileName) throws Exception{
DataLakeDirectoryClient directoryClient = fileSystemClient.getDirectoryClient("DIR");
DataLakeDirectoryClient subdirClient= directoryClient.getSubdirectoryClient("SUBDIR");
DataLakeFileClient fileClient = subdirClient.getFileClient(fileName);
File file = new File("downloadedFile.txt");
OutputStream targetStream = new FileOutputStream(file);
fileClient.read(targetStream);
targetStream.close();
}
#FunctionName("func")
public HttpResponseMessage run(
#HttpTrigger(name = "req", methods = {HttpMethod.GET}, authLevel = AuthorizationLevel.ANONYMOUS)
HttpRequestMessage<Optional<String>> request,
final ExecutionContext context
)
{
String fileName= request.getQueryParameters().get("file");
DataLakeServiceClient datalakeClient= GetDataLakeServiceClient("datalake", "<the shared key>");
DataLakeFileSystemClient datalakeFsClient= datalakeClient.getFileSystemClient("fs");
DownloadFile(datalakeFsClient, fileName);
}
The app freezes when it hits fileClient.read(targetStream);
I've tried with really small files, I've checked the credentials and the file paths, the access rights to datalake, I've switched to SAS token - the result is the same: no error at all, but the app freezes.
I am using these Maven dependencies:
<dependency>
<groupId>com.microsoft.azure.functions</groupId>
<artifactId>azure-functions-java-library</artifactId>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-file-datalake</artifactId>
<version>12.2.0</version>
</dependency>
so i was facing the same problem.Then i came across this.
https://github.com/Azure/azure-functions-java-library/issues/113
This worked for me on java 8,azure function v3.
Set FUNCTIONS_WORKER_JAVA_LOAD_APP_LIBS to True
in the function app Application settings.Then save and restart the function app.It will work.
Please check and do update if it worked for you as well.

How to test email verification flow with dynamic email generation and get email data in automation?

I am facing a problem with registration and login flow where it is required to generate an email and get token for verification. I need a service which allows user to generate n numbers of disposable emails with email data access that can self-destructs max 24 hours. Could anyone please share the service code to use in selenium java automation?
The QA teams leave such tasks for manual testing instead of writing automation tests for these scenarios. \
But, all communication from the email can be automated by the disposable email service. This article will describe how to use this service within the automation suite using Nightwatch.js (Node).
Registration and Login automation
You can use this code as well to automate such things:
2. Write down the logic of getEmail in common-function class and add dependencies in pom.xml file :
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
We will use Unirest for handling the Mail7 API code. it is a set of lightweight HTTP libraries available in multiple languages, built and maintained by Mashape, who also maintain the open-source API Gateway Kong.
Create a mail7.java file with below code
import org.apcahe.commons.lang3.RandomStringUtils;
public class mail7{
private static final String EMAIL-DOMAIN = ‘mail.io’;
private static final String EMAIL_APIKEY = ‘mail7_api_key’;
private static final String EMAIL_APISecret = ‘mail7_api_secret’;
private String emailid;
public usernameGenerator(){
String username = RandomStringUtils.randomAlphanumeric(8).toLowerCase();
System.out. println(“Random Username is ” + username);
return username;
}
public getInbox(String username){
HttpResponse <String> httpResponse = Unirest.get(“"https://api.mail7.io/inbox?apikey=" + EMAIL_APIKEY + "&apisecret=" + EMAIL_APISecret + "&to=" + username”)
.asString();
System.out.println( httpResponse.getHeaders().get("Content-Type"));
System.out.println(httpResponse.getBody());
return httpResponse.getBody();
}
3. Create a class file for Test Script of Register and Login event :
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class TestEmail throws IOException, UnirestException
{
public static void main(String[] args) {
//create a Selenium WebDriver instance
System.setProperty("webdriver.gecko.driver","dir_path\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
//launch the Firefox browser and navigate to the website
driver.get(“YOUR_TEST_URL");
//puts an implicit wait for 10 seconds before throwing exceptions
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//locate the email field
WebElement email = driver.findElement(By.xpath("//input[#type='email']"));
// create a random email address
String username = usernameGenerator();
String emailID = username.concat(“#”+EMAIL_DOMIAN);
//set the field's value
email.sendKeys(emailID);
//locate the password field
WebElement password = driver.findElement(By.xpath("//input[#type='password']"));
//set the password's value
password.sendKeys("password");
//locate and click the submit button
driver.findElement(By.xpath("//input[#type='submit']")).click();
//check if the mail has been received or not
String response = getInbo(username );
if(response.isEmpty()) {
System.out.println("Test not passed");
}else {
System.out.println("Test passed");
}
//close the Firefox browser.
driver.close();
}
}
}
}

how to authorize an user using jGit

I'm creating an application in Java and using jGit. As part of this I need to authenticate an user. I want to output if the user is existing or not. Currently I get an exception as user is not authorized. Below is my code.
import java.io.File;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
public class AuthenticateanUser {
public static void main(String[] args) throws Exception {
final String REMOTE_URL = "https://myRepo.git";
// prepare a new folder for the cloned repository
File localPath = File.createTempFile("TestGitRepository", "");
localPath.delete();
// then clone
try (Git result = Git.cloneRepository().setURI(REMOTE_URL)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider("myId", "myPwd"))
.setDirectory(localPath).call()) {
System.out.println("Having repository: " + result.status());
}
}
}
when I run my above code, If I give correct credentials, I get the output as
Having repository:XXXXX
if I give wrong credentials I get error as
Exception in thread "main" org.eclipse.jgit.api.errors.TransportException: https://myRepo.git: not authorized
Instead of this I want to print, Invalid credentials.
please let me know where am I going wrong and how can I fix this.
Thanks
You go:
try (Git result = Git.cloneRepository().setURI(REMOTE_URL) {
...
} catch (TransportException te) {
System.out.println("Invalid credentials");
}
for example.
You should not tell the user if the account exists or not. As in: if you tell that an attacker, he can conclude that he already got a valid username.

Categories

Resources