keytool Java and TLS/SSL - java

I have a socket client and server socket. The server has a keystore with a key in it.
keytool -genkey -alias mystuff -keyalg RSA -keystore keystore.jks -keysize 2048
This page says that it generates a key pair when the above command is run. https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html
When I run this command:
keytool -list -v -keystore keystore.jks
I can see:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: mystuff
Creation date: 25-Jun-2015
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Richard, OU=OSS, O=OSS, L=Yat, ST=Hamp, C=GB
Issuer: CN=Richard, OU=OSS, O=OSS, L=Yat, ST=Hamp, C=GB
Serial number: 48ee5103
Valid from: Thu Jun 25 17:09:18 BST 2015 until: Sun Jun 19 17:09:18 BST 2016
Certificate fingerprints:
MD5: 60:63:F2:41:A3:AB:DB:E0:63:F9:B0:E4:C8:2C:90:D4
SHA1: 52:8A:F7:76:82:B7:E9:BE:D3:4E:4A:3C:DD:CF:8A:58:A6:9F:70:DE
SHA256: 3C:80:C1:0E:E7:30:DD:69:9F:97:A9:02:F9:4E:6E:57:84:82:C5:22:0E:7F:7A:EE:C1:D2:7A:8A:45:A3:86:79
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 42 4F 07 15 3A 9A 8C 59 6A 65 EB B6 62 FD 77 C5 BO..:..Yje..b.w.
0010: AC E3 B2 4F ...O
]
]
What I am seeing there is the certificate but what does the entrytype: PrivateKeyEntry mean ?
So ... when I load the Java Server:
java -Djavax.net.ssl.keyStore=keystore.jks -Djavax.net.ssl.keyStorePassword=somepassword EchoServer
I can point it to the keystore so it can be used in setting up the SSLServerSocket.
Now on the client side does the client just need the exported crt from that key store using this command ?
keytool -export -alias mystuff -file mystuff.crt -keystore keystore.jks
Or is something else required to enable secure SSL between the Java Sockets.
Additional Information
Standard Java Notes
Running server and client using SSL
http://stilius.net/java/java_ssl.php
First copy certificate file that you created before into working directory and run server with these parameters (notice that you have to change keyStore name and/or trustStrorePassword if you specified different options creating certificate:
java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 EchoServer
And now again copy certificate file that you created before into working directory and run client with these parameters (notice that you have to change keyStore name and/or trustStrorePassword if you specified different options creating certificate:
java -Djavax.net.ssl.trustStore=mySrvKeystore -Djavax.net.ssl.trustStorePassword=123456 EchoClient
If you want SSL debug information just add these parameters when running server and/or client:
-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl
javax.net.ssl.keyStore- Location of the Java keystore file containing an application process's own certificate and private key. On Windows, the specified pathname must use forward slashes, /, in place of backslashes.
javax.net.ssl.keyStorePassword - Password to access the private key from the keystore file specified by javax.net.ssl.keyStore. This password is used twice: To unlock the keystore file (store password), and To decrypt the private key stored in the keystore (key password).
javax.net.ssl.trustStore - Location of the Java keystore file containing the collection of CA certificates trusted by this application process (trust store). On Windows, the specified pathname must use forward slashes, /, in place of backslashes, .
If a trust store location is not specified using this property, the SunJSSE implementation searches for and uses a keystore file in the following locations (in order):
$JAVA_HOME/lib/security/jssecacerts
$JAVA_HOME/lib/security/cacerts
javax.net.ssl.trustStorePassword - Password to unlock the keystore file (store password) specified by javax.net.ssl.trustStore.
javax.net.ssl.trustStoreType - (Optional) For Java keystore file format, this property has the value jks (or JKS). You do not normally specify this property, because its default value is already jks.
javax.net.debug - To switch on logging for the SSL/TLS layer, set this property to ssl.
Richard

Related

can't get go daddy ssl certificate to work with spring boot

I have a certificate with a generated a CSR within go daddy.
I tried generating my own CSR to get a certificate for my domain.
I have followed their tutorial to generate a store with the CSR:
keytool -genkey -alias codesigncert -keypass -keyalg RSA -keysize 2048 -dname "CN=displayname,O=companyname,C=US,ST=state,L=city" -keystore codesignstore -storepass
But the godaddy rejected the generated CSR, so I used the one they generate.
After that I used this command from a tutorial at thomasvitale.com.:
keytool -import -alias <my alias> -file <downloadedcertificate file>.crt -keystore keystore.p12 -storepass password
The generated .p12 keystore wouldn't boot because spring said:
DerInputStream.getLength(): lengthTag=109, too big.
Reading a LOT on that I have found out it was the way the keystore was generated and the version of something. Because of that I had to generate another keystore.
To generate the current problematic keystore I tried following medium.com instructions:
Used this to generate the keystore:
keytool -genkey -alias <alias> -keyalg RSA -keystore <keystore.jks> -keysize 2048
Used this to generate a CSR:
keytool -certreq -alias <alias> -keystore <keystore.jks> -file <domain>.csr
Sent the CSR to generate the ssl certificates, downloading them using the tomcat option. Then imported the certificates:
intermediate certificate: keytool -import -trustcacerts -alias <alias> -file gd_bundle-g2-g1.crt -keystore <keystore.jks>
root certificate: keytool -import -trustcacerts -alias <alias> -file e2e56xxxxf40c7.crt -keystore <keystore.jks>
Then I created the pcks keystore this way:
keytool -importkeystore -srckeystore <keystore.jks> -destkeystore <keystore.p12> -srcstoretype JKS -deststoretype PKCS12 -deststorepass <password> -srcalias <src alias> -destalias <dest alias>
After that, my spring boot config to install the certificate is:
After comments on this question I changed to use the JKS and removed ciphers.
server:
port: 8443
ssl:
enabled: true
key-store-type: JKS
key-store: classpath:asgard_keystore.jks
key-store-password: generated
key-alias: asgard
After installing all those to the p12, the server started okay, but any requests to the server would yield: err_ssl_version_or_cipher_mismatch or SSL_ERROR_NO_CYPHER_OVERLAP
Capturing that in wireshark just said Alert 21 using TLS 1.2 Handshake Failure (40).
I'm using undertow as a server. I don't remember if I used the domain in the name and last name field of the CSR.
Decoding my CSR using digicert tool I got:
Common name
<my domain>
Organization
<my org>
Organizational unit
<my city>
City/locality
<my city>
State/province
<my estate>
Country
<my country>
Signature algorithm
SHA256
Key algorithm
RSA
Key size
2048
Seems I'm doing everything exactly like every single tutorial, and every time something fails :(
As per the comment on the question, the keytool -list calls:
keytool -list for the .jks:
Keystore type: jks
Keystore provider: SUN
Your keystore contains 3 entries
Alias name: asgard
Creation date: Dec 7, 2018
Entry type: trustedCertEntry
Owner: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US
Issuer: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US
Serial number: 7
Valid from: Tue May 03 07:00:00 UTC 2011 until: Sat May 03 07:00:00 UTC 2031
Certificate fingerprints:
MD5: 96<removed>:40
SHA1: 2<removed>B8
SHA256: 97:3A<removed>E9:76:FF:6A:62:0B:67:12:E3:38:32:04:1A:A6
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
< not relevant >
]
*******************************************
*******************************************
Alias name: intermediate
Creation date: Dec 14, 2018
Entry type: trustedCertEntry
Owner: CN=<removed>, OU=Domain Control Validated
Issuer: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US
Serial number: 5c<removed>
Valid from: Fri Dec 07 20:25:19 UTC 2018 until: Mon Dec 07 18:10:35 UTC 2020
Certificate fingerprints:
MD5: 31<removed>74:77
SHA1: 8D:<removed>:C0:F5:AE:0B
SHA256: 77:14:9<removed>8B:1D:67:46:1A:67:A2:72:2F:2F:9E:F2:16
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
< not relevant >
]
*******************************************
*******************************************
Alias name: server
Creation date: Dec 7, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=<removed>, OU=São Paulo, O=Ideas Farm, L=São Paulo, ST=SP, C=BR
Issuer: CN=a<removed>, OU=São Paulo, O=Ideas Farm, L=São Paulo, ST=SP, C=BR
< not relevant >
]
]
*******************************************
*******************************************
full report: pastebin report
I have removed parts of the response that I find not relevant. I found it weird that the pkcs (.p12) file reported as being a jks type.
Also, the files that I received form the certificate authority are:
5<removedhex>6b1b.crt
gd_bundle-g2-g1.crt
gdig2.crt.pem
The gd_bundle contains 3 certificates -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- three times. The other two are just one.
You have told java to use the certificate with an alias of asgard. I can see in your .p12 dump that "asgard" is actually a CA. Look at the owner:
Alias name: asgard
Creation date: Dec 14, 2018
Entry type: trustedCertEntry
Owner: CN=Go Daddy Secure Certificate Authority - G2, OU=http://certs.godaddy.com/repository/, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US
Issuer: CN=Go Daddy Root Certificate Authority - G2, O="GoDaddy.com, Inc.", L=Scottsdale, ST=Arizona, C=US
I'm guessing that you actually want to tell spring to load your .jks file and specify an alias of codesigncert.
Also, delete your ciphers and enabled-protocols properties unless you have a good reason to override what spring sets up as defaults. Spring keep their defaults up to date with the latest security bulletins.
Finally, change your keystore password because the whole internet now knows what it is :)
I have solved the problem.
After fiddling A LOT with each certificate, I have found out that GoDaddy issues the certificate response and 2 equal intermediate certificates. Both come in the download package and there is no root certificate in there.
What happened is that I had a self signed dummy key, as stated in the comments and I didn't knew that I had to import the server certificate (the certificate response) with the same alias as my private key. I was importing with another alias thinking it was something else. My private key would remain self signed and not validated.
The errors I was getting about ciphers were because I was telling spring to use a certificate that was not a private key. Those don't support decoding the handshake.
Another problem that I faced is that godaddy doesn't provide the root certificate in the bundle you download. I was trying to add two intermediates, while the root was avaliable at a repository they had. After downloading and importing the correct root certificate, then I was able to import the private key validation certificate to the same alias as my dummy key.
So the solutin was simply to start with the JKS keystore used to create the CSR (one that contains only the private key I generated). Then add to it the root and intermediate certificates, and finally add the server cert (the one with the hex name), with the same alias as the private key.

How correct certificate is getting picked up in JKS in ssl handshake

Lets say I have a JAVA client app and it tries to connect to a server (example.com) over https. Client app has a trust store JKS , which has the server's certificate and some other certificates as well. In the hand shake process when server sends it certificate to this client app, how correct certificate will be picked up from the trust store jks. i.e based on what parameters java matches the certificate sent by the server with the certificates stored in JKS.
Matching is done by the certificate's Subject.
E.g. if you browse https://www.google.com/ and look at their certificate, it shows a certificate chain with:
Subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
Issued by: /C=US/O=Google Inc/CN=Google Internet Authority G2
Issued by: /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
Issues by: /C=US/O=Equifax/OU=Equifax Secure Certificate Authority
* Actually obtained using openssl s_client -connect www.google.com:443 -showcerts
The certificate will be trusted if any of these are in your truststore.
You can scan the truststore like this (assuming you have grep):
keytool -list -keystore /path/to/cacerts -storepass changeit -v | grep "CN=GeoTrust Global CA" -B 4 -A 8
To get this kind of output:
Alias name: geotrustglobalca
Creation date: Jul 18, 2003
Entry type: trustedCertEntry
Owner: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Issuer: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Serial number: 23456
Valid from: Tue May 21 00:00:00 EDT 2002 until: Sat May 21 00:00:00 EDT 2022
Certificate fingerprints:
MD5: F7:75:AB:29:FB:51:4E:B7:77:5E:FF:05:3C:99:8E:F5
SHA1: DE:28:F4:A4:FF:E5:B9:2F:A3:C5:03:D1:A3:49:A7:F9:96:2A:82:12
SHA256: FF:85:6A:2D:25:1D:CD:88:D3:66:56:F4:50:12:67:98:CF:AB:AA:DE:40:79:9C:72:2D:E4:D2:B5:DB:36:A7:3A
Signature algorithm name: SHA1withRSA
Version: 3

Invalid certification path - tomcat, SSL, Jasig

I try to login into cas-management-app using cas-server-webapp and I have problems with certification path.
I generated keystore file:
"$JAVA_HOME/bin/keytool.exe" -genkey -alias tomcat -keyalg RSA
Enter keystore password: pass
Re-enter new password: pass
What is your first and last name?
[Unknown]: localhost
What is the name of your organizational unit?
[Unknown]: localhost
What is the name of your organization?
[Unknown]: localhost
What is the name of your City or Locality?
[Unknown]: Crc
What is the name of your State or Province?
[Unknown]: Lesser
What is the two-letter country code for this unit?
[Unknown]: PL
Is CN=localhost, OU=localhost, O=localhost, L=Crc, ST=Lesser, C=PL correct?
[no]: yes
Enter key password for <tomcat>
(RETURN if same as keystore password): pass
Re-enter new password: pass
I changed Tomcat configuration:
server.xml
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="C:/Users/Mateusz/.keystore" keystorePass="pass"
clientAuth="false" sslProtocol="TLS"/>
Value of keystoreFile is valid path.
In next step I exported (using browser) certificate to localhost.crt and added it to cacerts:
"$JAVA_HOME/bin/keytool.exe" -import -alias incommon -file <localhost.crt location> -keystore cacerts -storepass changeit
When I list cacerts everything is OK:
$ "$JAVA_HOME/bin/keytool.exe" -v -list -keystore cacerts -storepass changeit
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: incommon
Creation date: 2015-11-02
Entry type: trustedCertEntry
Owner: CN=localhost, OU=localhost, O=localhost, L=Crc, ST=Lesser, C=PL
Issuer: CN=localhost, OU=localhost, O=localhost, L=Crc, ST=Lesser, C=PL
Serial number: 32432ba5
Valid from: Mon Nov 02 19:19:02 CET 2015 until: Sun Jan 31 19:19:02 CET 2016
Certificate fingerprints:
MD5: 9F:A6:4A:B0:F3:26:89:60:73:5C:CA:36:59:0A:32:F9
SHA1: 62:12:60:61:A9:3D:83:E8:1B:C5:3A:85:27:9A:7F:A7:D3:54:7D:D1
SHA256: F1:43:EE:6E:F7:D4:C6:DF:20:16:71:C1:0D:F5:88:5F:85:21:BE:E6:3C:E5:C1:8D:28:6A:51:BB:38:E7:A2:94
Signature algorithm name: SHA256withRSA
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: B0 94 2A 98 B8 A4 21 71 EB 34 46 D4 16 67 24 E8 ..*...!q.4F..g$.
0010: 67 61 C4 D6 ga..
]
]
When I run Tomcat server, open https://localhost:8443/cas-management I can see login form. After writing user login and password I see message:
The CAS management webapp is unavailable.
There was an error trying to complete your request. Please notify your support desk or try again.
Log files give me information
SEVERE: Servlet.service() for servlet [default] in context with path [/cas-management] threw exception
java.lang.RuntimeException: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I tried to install certs using InstallCert class but nothing changed. I also tried setup path to trust store (jssecacerts) using truststoreFile and truststorePass in Tomcat configuration.
I have no idea what next I can do to successfully configure SSL on my Tomcat server.

how to know the domain used in keystore/truststore?

I have self signed certificates for my https protocol based web application.but I want to know the domain mentioned in the keystore/truststore.
can any one help me to know it?
List certificates in keystore using following command:
keytool -list -v -keystore yourkeystorefile -storepass keystorepassword
Find your certificate and check the common name (CN) value in "Owner" tag. This is the domain name the certificate is created for.
Alternative domain names you may use are listed in optional SubjectAlternativeName section.
Before adding new certificates in keystore or truststore its good to see, count and verify already installed certificates. run following keytool command to get a list of certififcates from keystore:
javin#localhost:C/Program Files/Java/jdk1.6.0_26/jre/lib/security keytool -list -keystore cacerts
Enter keystore password: changeit
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 76 entries
digicertassuredidrootca, 07/01/2008, trustedCertEntry,
Certificate fingerprint (MD5): 87:CE:0B:7B:2A:0E:49:00:E1:58:71:9B:37:A8:93:72
trustcenterclass2caii, 07/01/2008, trustedCertEntry,
Certificate fingerprint (MD5): CE:78:33:5C:59:78:01:6E:18:EA:B9:36:A0:B9:2E:23
You see currently keystore "cacerts" holds 76 certificates.
Read more: http://javarevisited.blogspot.com/2012/03/add-list-certficates-java-keystore.html#ixzz39n3jfusy

How to sign java applet with .pfx file?

I was trying to sign a jar applet archive with our company .pfx certificate using this guide
(and few others from the internet):
http://www.globalsign.com/support/ordering-guides/SignJavaCodeAppletsPFX.pdf
Everything seems to be fine, but when I try t run apple through the browser I see that
'Publisher' is UNKNOWN (untrusted). And when I go to details I'm able to see proper company
name and certificate vendor (GlobalSign). Why it's not properly displayed as known/trusted?
The one thing which looks suspicious to me is output of command
jarsigner -verify -verbose -certs Applet.jar:
(...)
sm 1936 Wed Apr 13 03:00:50 CEST 2011 org/my/Applet.class
X.509, CN=CompanyName, O=CompanyName, L=Tilst, ST=ProperState, C=DK
[certificate is valid from 18.02.10 14:58 to 18.02.13 14:58]
s = signature was verified
m = entry is listed in manifest
k = at least one certificate was found in keystore
i = at least one certificate was found in identity scope
So looks like 'k = at least one certificate was found in keystore' is missing
(should be smk and it is sm). Is it signed only partially? Or what?
Is it possible that .pfx file given to me by GlobalSign is somehow wrong
on not enough to sign applets? For normal executables it was working just fine...
Any ideas? ;)
EDIT
#Jcs
Looks like you are totally right. I checked my PFX file with keytool and I get:
Your keystore contains 1 entry
Alias name: company_alias
Creation date: Apr 13, 2011
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
So looks like chain is not complete.
I'm not sure if it matters, but there are also few extensions like for example:
#1: ObjectId: (some_numbers_here) Criticality=true
KeyUsage [
DigitalSignature
]
#2: ObjectId: (some_numbers_here) Criticality=false
AuthorityInfoAccess [
[
accessMethod: (some_numbers_here)
accessLocation: URIName: http://secure.globalsign.net/cacert/ObjectSign.crt]
]
(...)
Question is: is my PFX file totally wrong, or somehow I need to add globalsign root to it?
According to your post, it seems that there is only one certificate in the signature certificate chain. I verified an applet I signed (this applet works correctly in a browser)
(...)
sm 2419 Thu Mar 31 15:49:14 CEST 2011 org/xml/sax/helpers/XMLReaderFactory.class
X.509, CN=Company Name, O=Company Name, L=Paris, ST=Ile de France, C=FR
[certificate is valid from 8/4/10 2:00 AM to 8/4/12 1:59 AM]
X.509, CN=Thawte Code Signing CA - G2, O="Thawte, Inc.", C=US
[certificate is valid from 2/8/10 1:00 AM to 2/8/20 12:59 AM]
[KeyUsage extension does not support code signing]
(...)
We can see that there is 2 certificates in the chain since my signing certificate has been issued by the Thawte Code Signing CA.
In your case if there is only one certificate in the jarsigner output it may indicates that the intermediate CA is missing and I hardly doubt that GlobalSign is directly issuing certificates from the root CA (which is in the java trust store). Therefore when the applet is loaded and the signatures are verified the JVM is not able to rebuild a certificate chain between the signing certificate and the GlobalSign root CA, explaining the current behaviour.
Maybe the PKF file does not contains that intermediate CA. With OpenSSL you can check how many certificates are present:
[jcs#home:~/]$ openssl pkcs12 -in myfile.pfx
or with keytool
[jcs#home:~/]$ keytool -list -v -storetype pkcs12 -keystore myfile.pfx
Enter keystore password:
Keystore type: PKCS12
Keystore provider: SunJSSE
Your keystore contains 1 entry
Alias name: 2
Creation date: Aug 4, 2010
Entry type: PrivateKeyEntry
Certificate chain length: 2 <-- the chain length is here.
Certificate[1]:
(...)
Thanks a lot for all, especially Jcs :)
I finally discovered that .pfx file was just imported improperly.
I asked my boss to import it for me from scratch with all possible paths/chains/certificates included and now it works :)
So if anyone will have similar problem my advice is to try to get/import certificate again
- it's rather problem with certificate itself than with signing method.

Categories