Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session

Use Encryption Service with a reader-extended PDF

Avatar

Level 2
Hi,



I success to use Reader Extension Service to extend my PDF form.

However, I want to crypt this extended PDF with the Encryption Service (within LiveCycle ES). The problem is when I try to do this, there is an error which is : "it doesn't crypt a signed PDF".

But my PDF is not signed, only extended.



I don't understand the problem.

What the steps to crypt an extended PDF?



Thanks for any help



Best regards
14 Replies

Avatar

Level 4
I think you need to apply the encryption before you run the file through Reader Extensions, then pass the authentication information to the Reader Extensions API. I've done this recently on 7.2, but I imagine the principal remains the same for ES.



And when you encrypt the file, don't forget that if the permissions you set when you apply the security are more restrictive than the Reader Extensions permissions, the features won't be available (e.g. if no commenting is allowed at document security level, setting commenting in Reader Extensions will not have any effect).

Avatar

Level 2
Hi,



I try to apply the encrypton before run the file through Reader Extension but my problem is Reader Extension said the pdf is crypted so it doesn't work on this.

So I agree to pass the authentification information but how?



Could you explain more precisely the steps please?

I crypt my file with Encryption Service with password to open the file.

But how pass this password to Reader Extension Service?



For the question of permissions, when I apply Encryption I don't specify permission. The only option I specify is : passSpec.setEncryptOption(PasswordEncryptionOption.ALL);

However with Reader Extension my permission are :

useRight.setEnabledComments(true);

useRight.setEnabledFormFillIn(true);

useRight.setEnabledFormDataImportExport(true);



These permission can give problem?



Thanks for your help

Avatar

Level 4
>>passSpec.setEncryptOption(PasswordEncryptionOption.ALL);



This just means that everything (document and attachments will be encrypted), the permissions are something slightly different. The different permission types are set with the PasswordEncryptionPermission enumeration, and if they are too restrictive they can block Reader Extensions from working... e.g. without PasswordEncryptionPermission.PASSWORD_EDIT_ADD, enabling commenting, form filling or digital signing will have no effect.



I think I was a bit misleading when I said you pass the authentication to Reader Extensions, it seems you actually have to use the EncryptionServiceClient to temporarily unlock the Document object prior to sending it to Reader Extensions.



Check out the EncryptionServiceClient.unlockPDFUsingPassword method.



This is new to ES, as on my code I simply called the openPDFWithPassword when I made the Document object instead.

Avatar

Level 2
Hi,



Thanks for your help but I have two problems with your explanation. (sorry but I am new in Adobe LiveCycle)



1/ I don't understand how specify the passwordEncryptionPermission when I crypt a PDF?



2/ Moreover when I try to use the method unLock, I don't see the difference. If I pass this document (normally unlocked) at ReaderExtension I have the same problem "the pdf is crypted". And if I write on fileSystem the document after the method unLock, the PDF (result) always asks a password.



I am a quite lost :(



If you could explain further it would be nice.



Best regards.

Avatar

Level 4
I've just thrown together a quick example by adapting one of the other sdk samples. This will take a pdf file, encrypt it, and reader extend it. The input file needs to have no encryption on to begin with.<br /><br />The instructions for compiling and running the samples can be found in the sdkHelp.zip of the LiveCycle ES SDK Help.<br /><br />http://www.adobe.com/support/documentation/en/livecycle/<br /><br />Here goes:<br /><pre><br />/*<br /><br />ADOBE SYSTEMS INCORPORATED<br /><br />Copyright 2007 Adobe Systems Incorporated<br /><br />All Rights Reserved<br /><br /> <br /><br />NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the <br /><br />terms of the Adobe license agreement accompanying it. If you have received this file from a <br /><br />source other than Adobe, then your use, modification, or distribution of it requires the prior <br /><br />written permission of Adobe.<br /><br />*/<br /><br />package com.test;<br /><br />import com.adobe.idp.Document;<br /><br />import com.adobe.idp.dsc.clientsdk.ServiceClientFactory;<br /><br />import com.adobe.idp.dsc.clientsdk.ServiceClientFactoryProperties;<br /><br />import com.adobe.livecycle.encryption.client.EncryptionServiceClient;<br /><br />import com.adobe.livecycle.encryption.client.PasswordEncryptionOption;<br /><br />import com.adobe.livecycle.encryption.client.PasswordEncryptionOptionSpec;<br /><br />import com.adobe.livecycle.encryption.client.PasswordEncryptionPermission;<br /><br />import com.adobe.livecycle.readerextensions.client.ReaderExtensionsOptionSpec;<br /><br />import com.adobe.livecycle.readerextensions.client.ReaderExtensionsServiceClient;<br /><br />import com.adobe.livecycle.readerextensions.client.UsageRights;<br /><br />import java.io.File;<br /><br />import java.util.List;<br /><br />import java.util.Properties;<br /><br />import java.util.Vector;<br /><br />public class EncryptAndExtend <br /><br />{<br /><br /> private static String _pdf_file_name = null;<br /><br /> <br /><br /> private static String _user_name = null;<br /><br /> private static String _password = null;<br /><br /> private static String _server_url = null;<br /><br /> private static String _server_type = null;<br /><br /> private static String _connection_type = null;<br /><br /> <br /><br /> private static Properties _scf_props = null;<br /><br /> private static EncryptionServiceClient _enc_client = null;<br /><br /> private static ReaderExtensionsServiceClient _lcre_client = null;<br /><br /> private static ServiceClientFactory _scf_factory = null;<br /><br /> <br /><br /> private static void encryptAndExtendSample()<br /><br /> {<br /><br /> final String OUT_FILE_NAME = "enc_ex_sample.pdf";<br /><br /> <br /><br /> File in_pdf_file = new File(_pdf_file_name); <br /><br /> <br /><br /> String path_name = in_pdf_file.getParent(); <br /><br /> String out_file_name = new File(path_name, OUT_FILE_NAME).getAbsolutePath();<br /><br /> Document in_doc = new Document(new File(_pdf_file_name), false);<br /><br /> <br /><br /> // set up the encryption opens, passwords, etc.<br /><br /> PasswordEncryptionOptionSpec doc_spec = new PasswordEncryptionOptionSpec();<br /><br /> doc_spec.setDocumentOpenPassword("open");<br /><br /> doc_spec.setPermissionPassword("master");<br /><br /> doc_spec.setEncryptOption(PasswordEncryptionOption.ALL);<br /><br /> List<PasswordEncryptionPermission> perms = new Vector<PasswordEncryptionPermission>();<br /><br /> perms.add(PasswordEncryptionPermission.PASSWORD_EDIT_ADD);<br /><br /> doc_spec.setPermissionsRequested(perms);<br /><br /> Document enc_doc = null;<br /><br /> try {<br /><br /> //encrypt the document using the spec<br /><br /> enc_doc = _enc_client.encryptPDFUsingPassword(in_doc, doc_spec);<br /><br /> <br /><br /> //set up the reader extensions options<br /><br /> ReaderExtensionsOptionSpec opts = new ReaderExtensionsOptionSpec();<br /><br /> UsageRights rights = new UsageRights();<br /><br /> rights.setEnabledComments(true);<br /><br /> opts.setUsageRights(rights);<br /><br /> <br /><br /> //since we haven't save the file to disk since encrypting it, we<br /><br /> //don't need to call unlock prior to applying usage rights<br /><br /> Document lcre_output = _lcre_client.applyUsageRights(enc_doc, <removed>, <removed>, opts);<br /><br /> <br /><br /> //write the output, done.<br /><br /> lcre_output.copyToFile(new File(out_file_name));<br /><br /> } catch (Exception e) {<br /><br /> e.printStackTrace();<br /><br /> System.exit(0);<br /><br /> }<br /><br /> }<br /><br /> <br /><br /> private static void initializeClientConnections()<br /><br /> {<br /><br /> _scf_factory = ServiceClientFactory.createInstance(_scf_props);<br /><br /> _enc_client = new EncryptionServiceClient(_scf_factory);<br /><br /> _lcre_client = new ReaderExtensionsServiceClient(_scf_factory);<br /><br /> }<br /><br /> <br /><br /> private static void initializeConnectionParameters(String[] args) throws IllegalArgumentException <br /><br /> {<br /><br /> _server_url = args[0];<br /><br /> _user_name = args[1];<br /><br /> _password = args[2];<br /><br /> _server_type = args[3];<br /><br /> _pdf_file_name = args[4];<br /><br /> _connection_type = args.length <= 5 ? "SOAP" : args[5]; <br /><br /> <br /><br /> if( !_connection_type.equalsIgnoreCase("SOAP") && <br /><br /> !_connection_type.equalsIgnoreCase("EJB") )<br /><br /> {<br /><br /> throw new IllegalArgumentException("The 'connection type' parameter may only be 'SOAP' or 'EJB'");<br /><br /> }<br /><br /> }<br /><br /> <br /><br /> private static void initializeSCFProperties()<br /><br /> {<br /><br /> _scf_props = new Properties();<br /><br /> <br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_CREDENTIAL_USERNAME, _user_name );<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_CREDENTIAL_PASSWORD, _password );<br /><br /> <br /><br /> if(_connection_type.equalsIgnoreCase("SOAP"))<br /><br /> {<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_SERVER_TYPE, _server_type );<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_DEFAULT_SOAP_ENDPOINT, _server_url );<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_TRANSPORT_PROTOCOL, "SOAP" );<br /><br /> }<br /><br /> else if(_connection_type.equalsIgnoreCase("EJB"))<br /><br /> {<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_SERVER_TYPE, _server_type );<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_DEFAULT_EJB_ENDPOINT, _server_url );<br /><br /> _scf_props.setProperty( ServiceClientFactoryProperties.DSC_TRANSPORT_PROTOCOL, "EJB" );<br /><br /> <br /><br /> // NOTE: these environment parameters should be specified at the command line with -D for JBoss EJB <br /><br /> // Different environment parameters may be necessary for other app servers.<br /><br /> //<br /><br /> _scf_props.setProperty( "java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );<br /><br /> _scf_props.setProperty( "java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );<br /><br /> }<br /><br /> }<br /><br /> <br /><br /> private static void printUsage()<br /><br /> {<br /><br /> System.out.println( "EncryptAndExtend usage:");<br /><br /> System.out.println( "EncryptAndExtend <server url> <user name> <password> <server type> <absolute PDF file name> [connection type]");<br /><br /> System.out.println( " where 'server type' is the type of server (e.g. JBoss), and 'connection type' optionally specifies SOAP or EJB. SOAP is the default");<br /><br /> }<br /><br /> <br /><br /> /**<br /><br /> * @param args<br /><br /> * Expects six arguments in the args array: <br /><br /> * URL, username, password, server type, file path (PDF), and policy name<br /><br /> */<br /><br /> public static void main(String[] args) <br /><br /> {<br /><br /> try<br /><br /> { <br /><br /> // Initialize the connection parameters from our arguments<br /><br /> if(args.length < 5 || args.length > 6)<br /><br /> {<br /><br /> printUsage();<br /><br /> <br /><br /> return;<br /><br /> } <br /><br /> initializeConnectionParameters(args);<br /><br /> initializeSCFProperties();<br /><br /> initializeClientConnections();<br /><br /> encryptAndExtendSample(); <br /><br /> }<br /><br /> catch(IllegalArgumentException e)<br /><br /> {<br /><br /> System.out.println("One or more parameters to the sample was incorrect:");<br /><br /> System.out.println(e.getMessage());<br /><br /> <br /><br /> printUsage();<br /><br /> } <br /><br /> }<br /><br />}<br /></pre>

Avatar

Level 2
Hi,<br /><br />I follow your example but it doesn't work. I have the same error : "ALC-RES-001-022: The input PDF document is encrypted and needs to be unlocked for this operation".<br />Moreover I have some differences. For example I don't work with Document object but with BLOB object. Indeed the method use BLOB object and no Document.<br />For information I call service with webservice on LiveCycle ES.<br /><br />I past my code, if you could analyse to tell me if there are some problems because I don't see the problem, I follow the same step that you.<br /><br />package formol.webservice.client;<br />import java.io.File;<br />import java.io.FileInputStream;<br />import java.io.FileOutputStream;<br />import java.io.OutputStream;<br />import java.util.List;<br />import java.util.Vector;<br />import com.adobe.idp.services.BLOB;<br />import com.adobe.idp.services.EncryptionService;<br />import com.adobe.idp.services.EncryptionServiceService;<br />import com.adobe.idp.services.EncryptionServiceServiceLocator;<br />import com.adobe.idp.services.PasswordEncryptionCompatability;<br />import com.adobe.idp.services.PasswordEncryptionOption;<br />import com.adobe.idp.services.PasswordEncryptionOptionSpec;<br />import com.adobe.idp.services.PasswordEncryptionPermission;<br />import com.adobe.idp.services.ReaderExtensionsOptionSpec;<br />import com.adobe.idp.services.ReaderExtensionsService;<br />import com.adobe.idp.services.ReaderExtensionsServiceService;<br />import com.adobe.idp.services.ReaderExtensionsServiceServiceLocator;<br />import com.adobe.idp.services.UsageRights;<br /><br />public class CryptAndExtend {<br /><br /> <br />public static void main(String[] args) {<br /> try{<br /> //Create an EncryptionServiceService client object<br /> EncryptionServiceService encryptionClient = new EncryptionServiceServiceLocator(); <br /> EncryptionService encryptClient = encryptionClient.getEncryptionService();<br /> ((javax.xml.rpc.Stub)encryptClient)._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "administrator");<br /> ((javax.xml.rpc.Stub)encryptClient)._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "password");<br /><br /> //Create a BLOB object to store the PDF document <br /> BLOB inDoc = new BLOB(); <br /> FileInputStream myForm = new FileInputStream("C:\\tmp\\test.pdf"); <br /> int bufSize = myForm.available(); <br /> //Populate the byte array with the contents of the FileStream object<br /> byte[]myBytes= new byte[bufSize]; <br /> myForm.read(myBytes); <br /> //Populate the BLOB object<br /> inDoc.setBinaryData(myBytes); <br /><br /> //Create a PasswordEncryptionOptionSpec <br /> //object that stores encryption run-time values<br /> PasswordEncryptionOptionSpec passSpec = new PasswordEncryptionOptionSpec();<br /> //Specify the password values<br /> passSpec.setDocumentOpenPassword("test");<br /> passSpec.setPermissionPassword("PermissionPassword");<br /> //Specify the PDF document resource to encrypt<br /> passSpec.setEncryptOption(PasswordEncryptionOption.ALL);<br /> //specify the permissions<br /> List<PasswordEncryptionPermission> perms = new Vector<PasswordEncryptionPermission>(); <br /> perms.add(PasswordEncryptionPermission.PASSWORD_EDIT_ADD); <br /> passSpec.setPermissionsRequested(perms.toArray()); <br /> <br />// Encrypt the PDF document with a password<br /> BLOB outDoc = encryptClient.encryptPDFUsingPassword(inDoc, passSpec); <br /><br /> ReaderExtensionsServiceService readerClient = new ReaderExtensionsServiceServiceLocator(); <br /> ReaderExtensionsService readerService = readerClient.getReaderExtensionsService(); <br /> ((javax.xml.rpc.Stub)readerService)._setProperty(javax.xml.rpc.Stub.USERNAME_PROPERTY, "administrator");<br /> ((javax.xml.rpc.Stub)readerService)._setProperty(javax.xml.rpc.Stub.PASSWORD_PROPERTY, "password");<br /><br /> //Create a UsageRight object and specify usage rights<br /> UsageRights useRight = new UsageRights(); <br /> useRight.setEnabledComments(true);<br /> //Create a ReaderExtensionsOptions object<br /> ReaderExtensionsOptionSpec reOptions = new ReaderExtensionsOptionSpec(); <br /> reOptions.setUsageRights(useRight);<br /><br /> //Apply usage rights to a PDF document <br /> BLOB outDoc2 = readerService.applyUsageRights(<br /> outDoc,<br /> "id",<br /> "pwd",<br /> reOptions);<br /> <br />// Populate a byte array with a BLOB data<br /> byte[] outByteArray=outDoc2.getBinaryData(); <br /><br /> if(outByteArray!=null){<br /> //Create a new file (result) <br /> OutputStream os = new FileOutputStream(new File("C:\\tmp\\test2.pdf"));<br /> os.write(outByteArray);<br /> os.close();<br /> }else<br /> System.out.println("ne reçoit rien!!!");<br /> }<br /> catch (Exception e)<br /> {<br /> e.printStackTrace();<br /> }<br /> }<br /><br />}

Avatar

Level 4
Ah yes, I've just reproduced that problem by changing the invocation method from EJB to SOAP on the arguments I pass into the EncryptAndExtend example I posted:



ALC-RES-001-022: The input PDF document is encrypted and needs to be unlocked for this operation.



So it seems that when using SOAP, that the lock status of a Document may be lost between calls to different Livecycle services.



Perhaps someone who has some experience with the web service method of invocation will be able to come forwards and shed some light on to possible causes, as I have only so far used EJB invocation with ES.



p.s. Incidentally, glancing at the SDK docs it appears that the BLOB object may only be necessary if you are using .NET, as the Java API seems to be able to quite happily box and unbox the objects being passed through SOAP to standard Document objects without any difficulty.

Avatar

Level 2
Thank you very much to take time to help me, testing my example.



So I agree to say it seems that is a problem with SOAP but I don't understand why :(



Waiting to see if someone have a great idea to solve my problem :)



Once again thank you for your time, and if you have an other idea, I take it :)



ps: I think that BLOB object is used when you use webService and no only with .Net Because in my code all my method have BLOB object as parameter and no Document as you can see on the documentation of Adobe's API. So I can't use Document Object to verify if the problem is related to BLOB object.

Avatar

Level 4
It's probably not relevant, but I believe you are using a different set of classes to the usage examples I have found in the SDK. Adobe have provided Client objects which can do alot of the heavy lifting when consuming Livecycle services. For example, in the example I posted I used:



com.adobe.livecycle.encryption.client.EncryptionServiceClient;



com.adobe.livecycle.readerextensions.client.ReaderExtensionsServiceClient;



And these client classes do work for connecting via SOAP in exactly the same way as EJB does (aside from the apparent bug you have discovered), so you can have basically the same code and use either invocation method by simply changing variables. Worth considering in the long run, as you probably save yourself quite a few headaches. You just need to remember to import the relevant jars into your app from:



C:\Adobe\LiveCycle8\LiveCycle_ES_SDK\client-libs\common

Avatar

Level 2
Hi,<br /><br />in fact I use set of classes which is generated when I create the webservice client with wsdl address.<br />I'm explaining, I use Eclipse with plugin for the webservice. I create a new project, then a new webservice client giving wsdl address. At the end I have a package com.adobe.idp.services which contains generated classes. I call these classes when I want use, for example, ReaderExtension. In this example the method applyUsageRights take a BLOB object as parameter and no a Document object like your example.<br />I have to use these classes since I call by webservice. So I can't use the same classes that you.<br />I think when you use webservice the method take BLOB object and when you use EJB call the method take Document object, but I am not sure.<br /><br />However, I try your example. I paste your code in a new project. But it doesn't work. When I launch it with as arguments : localhost administrator password JBoss test.pdf soap<br />I have an error message :<br />ALC-DSC-000-000: com.adobe.idp.dsc.net.DSCMalformedURLException: Internal error.<br /> at com.adobe.idp.dsc.provider.impl.soap.axis.sdk.SoapAxisDispatcher.createAxisCall(SoapAxisDispatcher.java:83)<br /> at com.adobe.idp.dsc.provider.impl.soap.axis.sdk.SoapAxisDispatcher.doSend(SoapAxisDispatcher.java:119)<br /> at com.adobe.idp.dsc.provider.impl.base.AbstractMessageDispatcher.send(AbstractMessageDispatcher.java:57)<br /> at com.adobe.idp.dsc.clientsdk.ServiceClient.invoke(ServiceClient.java:208)<br /> at com.adobe.livecycle.encryption.client.EncryptionServiceClient.encryptPDFUsingPassword(EncryptionServiceClient.java:71)<br /> at com.test.EncryptAndExtend.encryptAndExtendSample(EncryptAndExtend.java:79)<br /> at com.test.EncryptAndExtend.main(EncryptAndExtend.java:285)<br />Caused by: java.net.MalformedURLException: no protocol: localhost/soap/sdk<br /> at java.net.URL.<init>(URL.java:567)<br /> at java.net.URL.<init>(URL.java:464)<br /> at java.net.URL.<init>(URL.java:413)<br /> at org.apache.axis.client.Call.<init>(Call.java:345)<br /> at com.adobe.idp.dsc.provider.impl.soap.axis.sdk.SoapAxisDispatcher.createAxisCall(SoapAxisDispatcher.java:81)<br /> ... 6 more<br /><br />So for the moment I try to continue with your example.<br /><br />Best regards

Avatar

Level 4
Your first argument needs to be http://localhost:8080, as in addition to the hostname, the protocol (http) and port (8080 by default) are needed when you are connecting via SOAP over http.



Give that a try, let me know how you get on.

Avatar

Level 2
Hi,



I change my first parameter in http://localhost:8080

Now the program run but at the end I have the same message with my program which is :

ALC-RES-001-022: The input PDF document is encrypted and needs to be unlocked for this operation.



It is with your code :( I just change the name of the files (input, output) and the parameters of the method ApplyUsageRights (the two string)

Avatar

Level 4
Yes, I get the same error when using the code I posted in SOAP mode, see message (#7 of 12). It does work when I run the code in EJB mode though, I'd suggest trying that if you can.



For EJB mode the arguments would be:



localhost administrator password JBoss test.pdf ejb



It may be worth raising the issue with Adobe support if you have a support agreement, it's possible there is a config option or workaround to get the SOAP mode working.

Avatar

Level 2
OK !!! I understand :)



In fact for the moment I have not yet Adobe support. I work on project which is at the step study. We wait licenses to really run the project in development and production.

However I still ask this problem to a contact at Adobe but I don't have news since one week :(

I'm still waiting!!!



Else I want to thank you very much. It's very nice to take time to help me!!!