I've got a java applet that loads some pre-installed native code extensions to display custom content in the browser. Some of this content may include native code to be loaded by the JVM. Obviously, this is a security concern. I'd like to enforce that all content comes only from authorized servers.
The path I've been following to accomplish this is to create a keystore that contains just one SSL certificate. I set the keystore location and password and turned on debug output.
System.setProperty("javax.net.ssl.keyStore", "C:\\keys\\keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
Syste开发者_JAVA百科m.setProperty("javax.net.debug", "ssl");
I was under the impression that this would mean that the JVM would have access to only the one keystore file and consequently the one key inside it. In fact, the SSL debug info lists something like 75 CA keys in addition to the one key I added. Clearly, this isn't going to keep anyone from sending us untrusted code.
Is there a way to tell the SSL system to only use a single certificate? Should I be using a completely different approach?
Update: Changing the cacerts file isn't really an option here. The JVM should continue to function normally for other applications using it. Is there a way, at runtime, to elect not to load that file? I'm looking at the TrustManager and KeyManager classes but I don't really understand how to use them.
You need to set the javax.net.ssl.trustStore
system property to point to a keystore with your one certificate in it. The keystore is for your authentication credentials, not your peer's.
The very question is wrong here. A certificate is only a proof of identity. You don't authorize certificates, you authorize identities. What if the same client comes up with a new certificate?
The correct answer is to install a HandshakeCompletedListener
that checks the peer identity. The truststore is only there for authentication, i.e. is that person who they said they were. What you are doing is authorization, which is a different thing completely. You shouldn't use the truststore (or any PKI mechanism) for authorization.
You also have the global keystore installed with the JRE, which is where all the CA's are stored. Try to rename it and see what happens.
You still "see" the CA certificates of the system-wide JRE cacerts
file located in java.home/jre/lib/security
, which is normal.
Now, quoting the keytool documentation about this file:
IMPORTANT: Verify Your cacerts File
Since you trust the CAs in thecacerts
file as entities for signing and issuing certificates to other entities, you must manage thecacerts
file carefully. Thecacerts
file should contain only certificates of the CAs you trust. It is your responsibility to verify the trusted root CA certificates bundled in thecacerts
file and make your own trust decisions. To remove an untrusted CA certificate from thecacerts
file, use the delete option of thekeytool
command. You can find thecacerts
file in the JRE installation directory. Contact your system administrator if you do not have permission to edit this file.
In your case, it might be easier to entirely replace the cacerts
with your own key store instead of removing all 75 entries if this is really what you want. If not, then you should use a different approach indeed (why don't you just restrict or hard code the list of authorized servers?).
精彩评论