I have been able to run decryption and encryption locally using the bouncycastle jars. I have generated keys that I want to put the public key a client (Java and Android) and the private key in a web service. I have been able to encrypt and encoded a message and send the encrypted message to the webservice (on a hosted service by Lunarpages), but the webservice decryption fails with a FileNotFoundException on the line
BouncyCastleProvider bc = new BouncyCastleProvider();
or
Security.addProvider(new BouncyCastleProvider());
The bcprov-ext-jdk14-146.jar and the bcprov-jdk14-146.jar is included in the web-inf lib directory.
Is there something I can do programmatic to enable this or does Lunarpages have to do something?
I couldnt even get a stacktrace to print for me and so I thought I might attempt a different provider to see if I get a better response - the SunJCE.
access denied (java.security.SecurityPermission insertProvider.SunJCE)
java.security.AccessControlContext.checkPermission(AccessControlContext.java:269)
java.security.AccessController.checkPermission(AccessController.java:401)
java.lang.SecurityManager.checkPermission(SecurityManager.java:524)
java.lang.SecurityManager.checkSecurityAccess(SecurityManager.java:1673)
java.security.Security.check(Security.java:1307)
java.security.Security.insertProviderAt(Security.java:697)
java.security.Security.addProvider(Security.java:757)
net.wpstudios.tcws.pgp.RSAEncrypt.generateKeys(RSAEncrypt.java:81)
javax.servlet.http.HttpServlet.service(HttpServlet.java:165)
javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
com.caucho.server.http.FilterChainServlet.doFilter(FilterChainServlet.java:96)
com.caucho.server.http.Invocation.service(Invocation.java:315)
com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:135)
com.caucho.server.http.RunnerRequest.handleRequest(RunnerRequest.java:346)
com.caucho.server.http.RunnerRequest.handleConnection(RunnerRequest.java:274)
com.caucho.server.TcpConnection.run(TcpConnection.java:139)
java.lang.Thread.run(Thread.java:534)
Does the FileNotFound exception matter? Obviously the caucho server setup is using access restrictions on adding providers. Never mind that, if you want to develop some application level encryption/decryption you can simply use the bouncy castle crypto API directly. It's not as friendly as the JCE but it is useable enough. This might not work if you want to use a library that in its turn uses the JCA/JCE framework though.
Lunarpages is to change the permissions or add providers manually (using resin.conf, it seems), but it might be hard to change them just for you, unless you are the only one using the Java application server. It never hurts to ask I suppose.
Related
At the moment we have developed a system that can digitally sign documents using a java applet. However with the ban of applets under chrome we are looking for an alternative solution for digital signing.
At the moment the signing works the following way:
A HTTP GET is sent to a servlet to get the document that is going to
be signed;
The applet gets started, the digital signature driver gets extracted from the file system and the user enters the PIN;
The applet gets the certification chain, checks CRLs/OSCP and signs the document;
The applet sends a multipart post with the already signed file to a servlet in the system.
One alternative solution would be to import the certificate in the browser and use js to do the signing. But that won't be an user friendly solution.
Another solution could be to ask the user to download a run a program using JNLP that downloads and signs the document and automatically uploads it using HTTP multipart POST. The drawback of this approach would be it requires additional user interactions (the download action) and we lose browser http session, so we have to authenticate again.
Which is more viable? Can you think of alternative?
All post below suggests RSA based signing.
You may sign it in pure Javascript+ Web Crypto api.
Key points is extracting key with HTML5 <file> tag, use forge js library to deal with keys and hashes and canonize xml with deoxxa and use web crypto for sign/verify (in addition, forge also may sign/verify but web crypto is faster).
If you are signing xmls with exclusive canonicalization, use deoxxa (you should browserify it before using). If you sign xml and need to do inclusive canonicalization use my fork of deoxxa (hosted on own gitlab server). I was too lazy to rename exclusive to inclusive but my .js file performs inclusive, believe me) Example of usage forge+deoxxa+html5_p12_file_read in signJs, verifyJs files.
Also, forge supports signing binary files (CMS or in older naming style PKCS#7) but my JSP files doesn't have such example. About OCSP and chain test in JS - I opened the issue in forge, but it seems too difficult to handle CRL/OCSP and TSP protocols in JS, that's why you may sign in JS, but verify may be splitted - hash checking doing in JS(forge usage and additional code showed in my JSP) but smart checks like CRL, chain e.t.c do in your web service - you may extract X509Certificate and send it to your web service and use bouncycastle or any other cool library to do smart checks. X509Certificate is anyway public info, no problem in sending it to service, but digest checking requires files and you may not want to send files to service and thus use forge for checking digest which is showed in my verifyJS file.
My JS code is not refactored and even not in OOP and currently I'm not working on that project but on some stage I had fully working xml RSA siging with p12 keys in file system.
Latest JSP in my repo uses forge just for parsing p12 files and providing keys from them to Web Crypto API but my repo history also has pure Javascript sign/verify (if you don't like web crypto api). see history of the project branches.
I'm trying to write a program in Java that will digitally sign database entries prior to insertion. I would like for the program to be algorithm-independent - ideally, the user would specify the JCE provider and algorithm as arguments at runtime.
Is there a way to do this? I've been testing with the BouncyCastle provider, and the code runs fine when I dynamically register it:
Security.addProvider(new BouncyCastleProvider());
However, when I try to statically register the provider by adding the following lines to the end of my security/java.policy file, I get the error: java.security.NoSuchProviderException: no such provider: BC when I try to get an instance of a Security object using the provider.
security.provider.1=sun.security.provider.Sun
security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider
Specifically, I added those lines to /etc/java-7-openjdk/security/java.policy (which is linked to $JAVA_HOME/jre/lib/security/java.policy). This is on Ubuntu 12.04. I also tried just adding the BouncyCastleProvider as the first entry and got the same error.
Am I configuring the static registration wrong or is what I am attempting impossible?
I think you are adding the static registration into the wrong file.
Use security.policy instead of java.policy within the same folder.
See: https://www.bouncycastle.org/wiki/display/JA1/Provider+Installation
I have some code on Android that makes use of URL.openStream. For internal test purposes I need to be able to point it to a server that uses a private CA. We already have our CA bundles in PEM format (as we're also using libcurl from NDK), and would like to be able to just read the PEM files directly into whatever KeyStore (or similar) that URL.openStream uses.
So this question is a multi-part thing:
How do you get the key storage used by URL.openStream? Or should I just be using HttpClient directly?
How do you add a PEM certificate to said key storage? (even if using HttpClient)
Thanks.
I can't speak for Android specifically, but at least standard desktop Java has a default keystore that is used by all instances of the JVM, located at /lib/security/cacerts.
In many cases, this file should not be modified globally for all instances of the JVM, but on a case-by-case basis, as you already eluded to. To do this, you can't call .openStream directly. Instead, get a HttpsURLConnnection by calling URLConnection.openConnection() (and casting it do a HttpsURLConnection). Before performing any other operations on this connection, set a custom SSLSocketFactory by calling HttpsURLConnection.setSSLSocketFactory. From here, you'll need to work with a custom SSLContext and TrustManagers.
Some additional details around this are already answered at How can I use different certificates on specific connections?.
If you want to use HttpClient, additional references are available at http://hc.apache.org/httpclient-3.x/sslguide.html and How to handle invalid SSL certificates with Apache HttpClient?.
I'm running Apache Tomcat locally and have installed a self signed certificate using OpenSSL. I also have a servlet running.
What I want to do is the following:
The servlet takes in POST parameters and will echo back the parameters signed using the PrivateKey of the server. That is, treat the input parameter as an integer and raise it to the power of the private key.
The problem: Is it even possible to access the server's PrivateKey from the servlet? If deployed on some other hosting, it's probably not possible to access it directly. So is there any way that I can request that the server 'sign' some piece of data with its Private key?
Thanks in advance.
If I were writing a weberver I'd go to great lengths to prevent code from reading from the certificate store - I certainly wouldn't provide an API call for it!
Usually the cert is stored as a file on the webserver's filesystem (not always) but for a site with any serious security on it, this would be encrypted and require a passphrase to decrypt. Since you are using a self-signed certificate its probably not encrypted - just import the cert from the file into the keystore.
This depends on the way the container is configured. In the general case, the SSL configuration of the container will not be accessible by a servlet it contains. For example, in Apache Tomcat, that connector's SSL configuration can be completely independent of the settings accessible by a servlet. (In addition, SSL may be handled by APR or an Apache Httpd front-end, for example, which won't have much to do with the Java keystore configuration).
You would probably be able to gain access to the keystore if they are configured using the javax.net.ssl.* properties. However, that's not necessarily the way the SSLContext of the server connector is configured from. It's not generally a good idea to pass those parameters on the command line either in a production environment.
What you may be able to do is to load the keystore used by the container, from your servlet, but you'd have to know where it is, in advance. In addition, I would suppose that a hosting service would run Tomcat with a security manager turned on, which may prevent you from doing this.
Note that you could use your own keystore, shipped within your webapp (it can even be loaded from the classpath as a resource stream). Whether this keystore will contain the same private key as the one use by the server's SSL layer is up to the server's administrators (if they let you have it).
If you use a Java keystore you can access it from your servlet, as long as it knows the keystore location and password.
Servlet can access any data on your machine including keys. The only situation can be when Apache and Tomcat are running from different user names and keys are locked to be accessed only by Apache user name. You can do a trick in this case as su a process under Apache user name and read the file.
I have a process that runs on a UNIX (Solaris) server that runs nightly and needs to be able to send out encrypted emails.
I only need the "encryption" portion, NOT the digital signature / self-repudiation part of PKI.
I use MS Outlook in a corporate setting and I am assuming that when a user clicks "Publish to GAL..." under Tools -> Options -> Security, this will publish their PUBLIC KEY to the Global Address List (GAL).
So I am thinking that I need a way to connect to the Exchange Server that the GAL is on from my UNIX server.
Then I would need to retrieve the recepients PUBLIC KEY.
Then I could encrypt the email using the recepients PUBLIC KEY.
This would encrypt the email and only allow someone with the recepients PRIVATE KEY to read the email right?
Then I would send out the email.
But, what I am not sure about, is how to encrypt the email using only the recepients PUBLIC KEY (no KEYS on the UNIX side) in a way that MS Outlook will be able to read the email when the recepient receives it?
Would this work?
Anybody out there run into a similiar problem and come up with a solution?
Java code is preferred, but any langauge would do to start with.
Any additional details required in order to get a reasonable answer?
Thanks
You're logic is right.
Typical PKI encryption is:
cryptoAlgorithm(plaintext, public key) = ciphertext
cryptoAlgorithm(ciphertext, private key) = plaintext
For some algorithms, the cryptoAlgorithm is the same procedure, sending and receiving.
So... for each recipient you need their digital certificate, which will contain their public key.
GAL Certificate Storage
I would think it would be possible to configure the GAL to allow users to publish certificates. My general impression is that how the GAL is configured and used varies from company to company.
S/MIME & PGP
I agree with the post that S/MIME is what you want for Outlook.
Also note - if your users are using Outlook Web, rather than the Outlook client, they won't be able to receive encrypted emails. At least as of 2000, but I suspect 2003 as well. It's a huge usability problem and I've got no good workaround.
General Microsoftyness
Microsoft has their own special way of doing things (no kidding...). They are
no different in the world of PKI. User certificates must be clearly marked with an encryption capability. I know it must have the KeyUsage field KeyEncipherment. And there may be one other extension required by Microsoft. Having an incorrectly formatted user certificate could mean that the recipient will be unable to read the mail when it arrives, because Outlook won't agree on the fact that the mail was encrypted. Spare some serious integration testing time here and plan to hit lots of user groups on how to do this. Every time my team has had to integrate with a Microsoft product, there have been nasty surprises, particularly regarding how the certificate is configured.
Libraries & Tools
I second the recommendation for BouncyCastle - I haven't used it, but people I trust swear by it. I personally loved the Phaos toolkit when I had to write this stuff, but I'm out of date. I know it cost serious money, and may be too much bang for your buck.
OpenSSL is another fabulous tool, and useful for much more than SSL. It's great for generating test certificates, but I can't remember if it does S/MIME email encryption as well.
For most libraries, you should be able to take plaintext, and the certificate, and put both into a function that generates the S/MIME message. They may require the encryption algorithm as well.
In the general case : to send an encrypted message to someone, you only need their public key. You dont need to have a key yourself. The rule with asymetric crypto is whatever is encrypted with a public key can be decrypted with the corresponding private key, and whatever is encrypted with a private key can be decrypted with the corresponding public key.
You will need a key for your server only if you want to sign the message.
If you want to do the implementation in Java, I dont think that JavaMail supports encryption out of the box, but you can have a look at JavaMail-Crypto (havent used it myself). There is supposedly a JNI interface to GnuPG somewhere ... And you can always exec PGP or GnuPG from any language ...
I dont know about the support for PGP in Outlook, nor anything else about Outlook.
You have to send encrypted mail to Outlook in s/mime format. Outlook doesn't support PGP.
Start by trying to send a plaintext message from Java and see if you can get it into Outlook. Worry about the encryption later. Use the JavaMail library to create and send emails.
I don't know how to extract keys from the GAL. It is probably easiest to start off by exporting a key manually and see if you can work with it.
To create encrypted mails in s/mime format I recommend Bouncy Castle. Bouncy Castle is a crypto-provider that also has support for s/mime. (Look for the CMS/Smime package). There should be some examples in the downloaded sources. I've used it in the past to send emails to a wide array of email clients, including Outlook and it works pretty well. But brace yourself for the crypto stuff -- it can be a steep learning curve!
The caveat not noted previous is that the GAL isn't necessarily on the Exchange Server, and is more frequently found on the Domain server, when not run in a standalone mode. The certificate will be found in the LDAP attribute userCertificate or userSMIMECertificate.