I'm implementing a mutual authentication with a web server in Java on Windows.
I have a certificate on a SmartCard which is supposed to be used to authenticate me (or other user).
So far I've figured out that I can access the certificates using Windows-MY key store.
I do it like that:
KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.init(null, null);
This works. I can see all certificates inside keystoreSpi (in debugger). One of them is the one which I need to use - I confirmed that.
The problem is as follows:
KeyStore api allows me to get a certificate only by using it's alias. e.g. keyStore.getCertificate("alias") or keystore.getCertificateChain("alias")
I noticed that there are multiple different certificates with the same alias in this keystore. I cannot change the aliases. I just physicaly got the smartcard with given certificates.
When I call one of the mentioned methods, keystore returns just the first certificate in the list with given alias. (generally, in the implementation there is a map where aliases are it's keys, so all duplicated aliases are ignored).
Unfortunately first certificate's purpose is "email encryption", etc. The second certificate's purpose is "SmartCard Logon" and this one I need to use. I confirmed that by going into debugger and manually hacking the list of certificates.
The question is: how do I get a proper certificate using the API (eg. the second one) when there are duplicated aliases?
If this can be done by external libraries, I can opt for that.
More details which may be useful:
I use KeyStore, then create KeyStoreManager.
I initialize SSLContext with given keyStoreManager sslContext.init(keyManagerFactory.getKeyManagers(), ...)
I create HttpsUrlConnection with given ssl context, which is my objective.
This has been fixed a while ago. Just update to a recent JRE. For more information see here: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6483657
Related
I have a keystore that I used to generate some .csr files, sent these off and got back .p7b files. However I managed to lose my keystore password, I saw there is a brute force java program to work it out however I know my password is 15 characters long and this would take a very long time. I also tried creating a new keystore from the old one, like some people had suggested but it still requires me to enter the password and fails without it.
Am I likely to run into problems if I just create a new keystore and import the certificates into that one or do I have to request new certificates?
Am I likely to run into problems if I just create a new keystore and import the certificates into that one
You will run into the problem that you can't do it. You've lost access to the private key.
or do I have to request new certificates?
You have to create a new keystore, keypair, CSR, get it signed, import it, ...
Actually it's a bit more complicated. In spite of its name, a Java 'keystore' can actually contain any combination of:
PrivateKeyEntry -- contains privatekey and matching certificate or chain, used to prove your own identity, particularly for an SSL/TLS server
TrustedCertEntry -- contains cert, usually root CA cert, used to verify other parties, including SSL/TLS client(s) verifying server(s)
(only in some formats, not common JKS) SecretKeyEntry -- not relevant here
See the javadoc for java.security.KeyStore. In fact the 'truststore' of CA certs used by SSL/TLS (including HTTPS) clients in Java to verify servers is normally a keystore file, by default JRE/lib/security/cacerts which is supplied as part of the JRE (for Oracle-formerly-Sun packages) or linked from it (for OpenJDK, at least in systems I've used).
Thus if you tell keytool to import your own certificate(s) to a new keystore file, it will do so -- but as trusted cert entry(ies) that can identify someone else, not as a privatekey entry that can identify you. The only indication is a subtle one: keytool will say Certificate was added (which means a trustedcert) NOT Certificate reply was installed (which means a matching privatekey).
If you then use this cert-only-not-privatekey keystore for an SSL/TLS server, it will not give any immediate or obvious error; normally it will instead reject all connection attempts as 'no cipher suites in common'. (If both endpoints have configured to allow 'anonymous' ciphersuites the connection will/may succeed with an anonymous suite, but this gives no security against now-common active attacks and therefore is not usually done.)
But this doesn't change the result: without the passphrase and thus access to the old privatekey, you're wedged and must start over. Note that if you used a paid CA many (IME most) of them allow 'rekeying' a cert for the same domainname(s) free or at a substantial discount.
A keystore (no matter if it's used for "keystores" or "truststores") is initialized after creation using the load() method. One version expects an InputStream corresponding to the keystore file, and the password to decrypt the file. Providing the password to the method programmatically seems strange to me.
For example, a server uses a keystore to store its private keys and the associated certificates. The information present in the keystore is sensible so it is protected by a password. What are the problems of passing the password to the load() method programmatically? What is the best practice?
The other example, but for now concerning truststores. The client has a truststore where it stores the certificates of trusted CAs. As I understand it, the truststore doesn't contain the certificate of the server but only the certificates of the CAs that allow verifying the server's certificate. One truststore example I see is the one present with the JRE (in the security folder - cacerts). By looking at the configuration, I can see it is protected by the default password changeit. I understand that a truststore is implemented using a keystore, so it has (or maybe it's optional?) to be encrypted using a password. But, since truststores generally store public information (trusted CA's certificates) in the file, why changing the password is recommended?
Thanks
Providing the password to the method programmatically seems strange to
me.
I'm not sure why this would be strange. The application will need to be able to get hold of the content of the keystore at one point or another. The password will need to be passed to it, somehow. Passing it to the load() method doesn't make less sense than other solutions (avoid hard-coding, of course). Alternatively, you can use the method that uses a callback instead. If you don't think that's suitable, you can use a PKCS#11 provider and a hardware token (although you'll still need to enter the password/PIN somewhere) or use something like the Apple KeychainStore (where the password isn't used, but the OS keychain service takes care of that).
Regarding the truststore, there are in fact two passwords in use. They can be different, when using the JKS format. One protects the keystore itself, and one protects access to the private entries (getKey). In this case, the keystore password is used to prevent unauthorised parties from altering the truststore (and adding their own CA or server certificates).
I read this article on how to use keytool to generate CSRs for your organization. It was simple and easy, but left me with a few questions that I couldn't find clear, descriptive answers to:
What is Java's concept of a CSR alias and why would you want to use one? Where is this alias field stored and what other tools/APIs have access to it?
What is the difference between a key and a keystore?
What is Java's concept of a CSR alias and why would you want to use one? Where is this alias field stored and what other tools/APIs have access to it?
First of all, java uses keystores to keep keys (and certificates) inside. Single keystore can hold many certificates, so you need a way to differentiate them. That's what aliases are for. Having a keystore, an alias (and a password if needed) you can get the certificate from the keystore using Java Crypto API (specifically classes like Keystore). Here, you have a an example of how the Crypto API can be used to load a key from keystore
What is the difference between a key and a keystore?
The keystore is a container. The keys are kept inside keystores.
A keystore is a file format used to hold certificates and private keys, and alias is used to identify each entry in the keystore.
Hi I'm a bit lost and hope you'll get me out of here. I'll try to be as clear as possible since I don't really understand/know how I should use certificates.
I've got an application that is supposed to communicate with another one using webservices and SSL. We both asked our main "Certificate Authority" to get certificates.
They sent us 4 files and a password for the .P12 file:
.csr, .cer, .key, .P12
Here is what I did :
* Configure JBoss to use SSL on 8443 and used the P12 file as the keystore
To test this I did a small Java class that call a webservices on this server, using :
props.setProperty("javax.net.ssl.trustStore", "/.../.../certif.p12");
props.setProperty("javax.net.ssl.trustStorePassword", "XXXXXXXXX");
props.setProperty("javax.net.ssl.trustStoreType", "PKCS12");
The connection works, but I think I'm missing something as I did not use the other files.
If I send my .P12 file and the password to the application that is supposed to call my Webservices will it be ok/enough ?
Edit :
I forgot to mention that I should call a Webservice on the other application too, so it should be the other way around, do I only need a .P12 and pass ?
I've read a lot of thing about public key, private key, keytool but it's a bit messy in my head right now.
Thanks for any information !
They sent us 4 files and a password for the .P12 file: .csr, .cer,
.key, .P12
Ideally, you should have generated the private key (in .key) and CSR (in .csr) yourself and the CA should have come back with the certificate (typically in .cer) based on the CSR, which you would have assembled together to build your PKCS#12 file (.p12).
At this stage, you can discard the CSR. The PKCS#12 file should now contain the private key, its associated certificate and possibly the certificate chain attached. You could extract the .key and .cer files from that .p12 file later again. I guess you were given all these files because of the way they have been generated (using intermediate files), or for convenience, not to have to convert them yourself.
The Java terminology isn't ideal, but keystore and truststore are two entities of type keystore, but with a different purpose. The difference between the KeyManager and TrustManager (and thus between javax.net.ssl.keyStore and javax.net.ssl.trustStore) is as follows (quoted from the JSSE ref guide):
TrustManager: Determines whether the remote authentication credentials (and thus the connection) should be trusted.
KeyManager: Determines which authentication credentials to send to the remote host.
The javax.net.ssl.trustStore* properties are one way of configuring the TrustManager. The javax.net.ssl.keyStore* properties are one way of configuring the KeyManager.
Typically, there is no need for private key material in a trust store (unless you also use the same as a keystore). It's often better to use a separate truststore, which you'd be able to copy freely across machine, without worrying about leaking private key material.
What would make sense would be to build a new keystore (JKS) that you would use as a truststore, using the CA certificates (not sure if you've been provided with them).
You're not doing mutual authentication by setting the truststore only (there are no default values for the keystore, so they need to specify these parameters explicitly). If you want to use your client-certificate to connect to a remote party, you need to set it in the keystore (for example, using the javax.net.ssl.keyStore* properties in the same way you've done it for the trust store).
You could point both the keystore and truststore to the same .p12 file. The side effect is that other connections made by your service to other places (e.g https://www.google.com) would not be trusted, since it wouldn't contain the CA for those. That's why it might be better to create a separate "truststore keystore" (JKS might be easier) for the CA certificates. You could make a copy of the default cacerts (in the JRE directory), import your CA's certificate into it and use that.
I've got an application that is supposed to communicate with another
one using webservices and SSL.
Ok, stop here. Communicate how? I mean is it only server authentication i.e. your client application will authenticate the web service or mutual authentication and the web service will also request your applications certificate?
This is important as the files you present by the names seem to suggest the latter i.e. that mutual authentication is expected while your code you show is only setting SSL library for server authentication.
Since you are not providing context here I would say that:
.key has your private key
.p12 has your private key along with your signed certificate or perhaps the CA's root certificate (?)
cer could have your signed certificate or perhaps the root's CA
signing certificate that is considered as trusted in the domain and
has probably also signed the web service you want to communicate with
certificate (well that is a possibility/guess here since you don't
say much)
csr is your certificate signing request
I did a small Java class that call a webservices on this server, using
What you do in the code is setting the p12 as the truststore.
If you say this works then there is no mutual authentication only server side authentication and you are authenticating the web service using whatever is in the p12.
In this case the rest are not needed for communication.It is for you to keep especially the key file since this could be your private key and if you lose/someone steals this then your private certificate is useless/compromised.
I am not sure what your requirements on security are here, but it seems to me that you should probably look into it more.
Even for this question I just tried to do an educated guess based on the file names.....
I hope this puts you in some track to read.
Can we load multiple Certificates & Keys in a Key Store?
Is it always required to load only Pairs (i.e. Certificates & Keys together)?
If a Key Store has multiple Certificates and Keys, which one will get selected when Java SSL tries to establish connection as a Server?
Although this depends on the KeyStore type, generally, you can store multiple private keys and certificates in a single store.
Which key and certificate combination is used for a Java-based server will depend on how the application was implemented. A number of applications let you select a given certificate using the alias name. The key and certificate getters in KeyStore take an alias parameter to make this choice. Usually, when this is not specified in the configuration, the application or framework will use the first suitable one it finds based on the KeyStore.aliases() enumeration.
Tomcat, for example, uses the keyAlias attribute in its Connector configuration:
keyAlias: The alias used to for the server
certificate in the keystore. If not
specified the first key read in the
keystore will be used.
Regarding key pairs, some KeyStores (again, depending on the type) can be used to store SecretKeys (e.g. DES), that is shared keys, as well as public-private key pairs.
You can have a keystore with as many certificates and keys as you like.
If there are multiple certificates in a keystore a client uses as its truststore, all certificates are being looked at until one is found that fits. You can look at the preinstalled certificates, they are in /lib/security/cacerts. It's just a big collection of root CAs' certificates.
Regarding the keys I don't know. I'd reckon the client uses a key that is signed by the same CA as the certificate that is provided by the server and if there are multiple, the first is used. But I can't say that for sure.