Showing posts with label Security. Show all posts
Showing posts with label Security. Show all posts

Tuesday, August 14, 2012

Input not an X.509 certificate

When I imported a certificate in my keystore, I got the error “Input not an X.509 certificate”

The keytool is very strict about format. If you have anything in your certificate before —–BEGIN CERTIFICATE—– or anyting after —–END CERTIFICATE—–

After I remove that the text before “—–BEGIN CERTIFICATE—– ”, I can import the certificate.

Monday, August 8, 2011

Debugging SSL

 java  -Djavax.net.debug=all  \
-Djavax.net.ssl.trustStore=trustStore
SSLSocketClientWithClientAuth bongos 2001 /index.html


For detail see http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/ReadDebug.html

CA and its certificate

A certificate is insecure until it is signed, as only a signed certificate cannot be modified. You can sign a certificate using itself, it is called a self signed certificate. All root CA certificates are self signed.

exempted from http://tldp.org/HOWTO/SSL-Certificates-HOWTO/x64.html

HTTPS encryption and handshaking

About the detail steps of HTTPS encryption and handshaking, here is it

http://support.microsoft.com/kb/257591

here is diagram.

ssl_hello

Here is a concentrated diagram about handshaking.

handshak

Here is a rough conclusion:

In handshaking

The client get the certificate from the server. If it is a trusted one, use the public key from the certificate to encrypt a key (pre-master, a random generated by the browser) and send it to the server

The server uses its private key to decrypt the message and get the client key (pre-master)

Both server and client compute a symmetric key from the pre-master. (pre-master secret –> master secret –> session key)

Then the session is established.

In the session both server and client use the created symmetric key for both encryption and decryption.

So, the business data transferred in the HTTPS session is using symmetric encryption. The certificate and its asymmetric encryption is only used in handshaking to guarantee that only the server and the client browser has the symmetric key.

Friday, August 5, 2011

-Djavax.net.ssl.keyStore or -Djavax.net.ssl.trustStore

They are two arguments of JVM. What is the diference?
-Djavax.net.ssl.trustStore is to declare the keystore file which trusts the certificate of the remote site. It guarantee that the remote server is the server it claims to be.
-Djavax.net.ssl.keyStore is to provide the private key to encrypt the data which is sent to server. It guarantee that the client is the client it claims to be.
A keystore file can save both private key or trusted certificate (public key).
private key –> encryption
public key –> decryption
If JVM see the argument -Djavax.net.ssl.keyStore, JVM only cares the private keys saved in that keystore file.
If -Djavax.net.ssl.trustStore, JVM only cares the certificates saved in the keystore file.
If you are creating a java client to connect a HTTPS server, you should use -Djavax.net.ssl.trustStore.
If dual authentication is required, you need use both.



The command line argument for trust keystore password is -Djavax.net.ssl.trustStorePassword
For example
java -Djavax.net.ssl.trustStore=truststore -Djavax.net.ssl.trustStorePassword=123456 MyApp
-Djavax.net.ssl.trustStorePassword is the password argument for -Djavax.net.ssl.keyStore

Certificate signed by VeriSign is not trusted in java

My current project need create a https connection in java code. The code worked fine in the past 5 years. But recently the certificate expired. After we got the new certificate (signed by veriSign) and installed it on the target server, the https connection still cannot be established.

Hmm… before, I thought all certificate signed by VeriSign is trusted automatically.

After look into the certificate, it was issued by “CN=VeriSign Class 3 Public Primary Certification Authority - G3”.

That is a new CA root. VeriSign has a lot of CA root. This one is published much later than the JDK and it is not a trusted CA in cacert of JDK.

We download the root certificate for “CN=VeriSign Class 3 Public Primary Certification Authority - G3” and import it in cacert, then it works.

 

Some resource from internet

http://www.tbs-certificats.com/FAQ/en/565.html

http://www.verisign.com/support/roots.html

Wednesday, July 13, 2011

java download remote certificate

In one of my project, I need a certificate from the server which provides web service over https. The server can only be visited from a unix box which cannot run firefox, IE…

The java code below can download the certificate. Note, the certificate must be signed by a trusted certification provider, like versign. Otherwise, like self signed certificate, it won’t allow you establish the connection.

URL url = new URL("https://www1.royalbank.com/");
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("Altaproxy.tmi.telus.com", 8080));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.connect();
Certificate certs[] = con.getServerCertificates();
for (Certificate cert : certs) {
System.out.println(cert.toString());
}
Method getEncoded() of Certificate returns byte[] which allows you save it in a file.

Reference


a blog from internet


java.security.cert.Certificate api


Using proxy in http connection

Thursday, September 30, 2010

HTTPS Certificate and HTTPS URL integrity check

The HTTPS specification mandates that HTTPS clients must be capable of verifying the identity of the server.

The basic idea of the URL integrity check is that the server certificate’s identity must match the server host name. This integrity check has an important impact on how you generate X.509 certificates for HTTPS: the certificate identity (usually the certificate subject DN’s common name) must match the host name on which the HTTPS server is deployed.

For example, if a server supports secure TLS connections at the following URL:

https://www.progress.com/secure


The corresponding server certificate would have the following subject DN:

C=IE,ST=Co. Dublin,L=Dublin,O=Progress,
OU=System,CN=www.progress.com


Using the subject DN’s Common Name for the certificate identity has the disadvantage that only one host name can be specified at a time. If you deploy a certificate on a multi-homed host, however, you might find it is practical to allow the certificate to be used with any of the multi-homed host names. In this case, it is necessary to define a certificate with multiple, alternative identities, and this is only possible using the subjectAltName certificate extension.



For example, if you have a multi-homed host that supports connections to either of the following host names:

www.progress.com
fusesource.com


Then you can define a subjectAltName that explicitly lists both of these DNS host names. If you generate your certificates using the openssl utility, edit the relevant line of your openssl.cnf configuration file to specify the value of the subjectAltName extension, as follows:

subjectAltName=DNS:www.progress.com,DNS:fusesource.com


Here is the original article



If the URL integrity check failed, in java code, you probably will get the exception below

java.io.IOException: HTTPS hostname wrong:  should be <THE_HOST_USING_HTTPS_CERTIFICATE>;
at sun.net.www.protocol.https.HttpsClient.b(DashoA12275)
at sun.net.www.protocol.https.HttpsClient.afterConnect(DashoA12275)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(DashoA12275)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:569)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(DashoA12275)
at TestSSL.doC8Authentication(TestSSL.java:75)
at TestSSL.main(TestSSL.java:24)


If you cannot change the certificate and have to use it for testing purpose, here is one alternative way to avoid integrity check

HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
con.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});


See reference





An alternative way

static {
//for localhost testing only
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
new javax.net.ssl.HostnameVerifier(){

public boolean verify(String hostname,
javax.net.ssl.SSLSession sslSession) {
if (hostname.equals("localhost")) {
return true;
}
return false;
//if you don't care host name, return true
}
});
}





Or you can create a certificate which CN is "localhost". (Let's say the testing server name is localhost.)


localhostKeystore

Sunday, December 7, 2008

Public Key encryption in Java

http://www.developer.com/java/ent/article.php/3447491
http://www.junkheap.net/content/public_key_encryption_java

Tuesday, August 26, 2008

Keeping key pair and certificates in Java

In order to use PKI, typically you should have a private key for yourself (see the diagram below), a certificate for yourself so that you can send to others, a certificate for each person that you need to send something confidential to (e.g., Paul and Mary) and the public keys of the CA's that you trust. For the public key of the CA, you don't directly store its public key. Instead, you store its certificate which contains its public key. But who issued that certificate to it? It was issued by itself (signed by its own private key)

Such a table is called a “keystore” in Java (see the diagram below). A keystore is stored in a file. In addition, each entry in the table has a name called the "alias" of the entry. This way you can, e.g., tell the software to sign a particular message using the private key in the “john” entry (yourself), or encrypt the message using the public key in “paul” entry. Without the alias you will have to use the DN to refer to an entry.


Generating a key pair
In order to generate a key pair, you can use the keytool program in JDK. For example, if your JDK is in c:\Program Files\Java\jdk, then you can find keytool.exe in the bin sub-folder (i.e., c:\Program Files\Java\jdk\bin). For convenience, let's add c:\Program Files\Java\jdk\bin to the PATH. Next, create a folder "c:\keys" to hold the keys and change into there. Now, generate a key pair:
c:\keys>keytool -genkey -alias c1 -keystore client.ks
-keyalg RSA -sigalg SHA1withRSA





To verify that the entry has been added, you can list the entries:
c:\keys>keytool -list -keystore client.ks



You can see that both the "Owner" and the "Issuer" are set to the DN of c1. It shows that it is indeed a self-signed certificate. Having a self-signed certificate is not useful. You need to ask a CA to sign it. To do that, generate a certificate request first.
c:\keys>keytool -certreq -alias c1 -keystore client.ks -file c1.csr
It will generate a cerificate request for the entry named "c1" and put the certificate request into the file "c1.csr". Run it:


Now it has put the certificate request into c:\keys\c1.csr. You need to send to a CA. In real life, you should send it to VeriSign or some well known CA to get a certificate (of course a payment is required). Here you'll setup your own CA.

Setting up a CA
Go to http://www.openssl.org/related/binaries.html to download the Windows version of OpenSSL. Suppose the file is Win32OpenSSL-v0.9.8a.exe. Login as the Administrator and run it. Follow the instruction to complete the installation. Suppose that it has been installed into c:\OpenSSL. To make it easier to run, add c:\OpenSSL\bin to the PATH.
Next, create a folder say c:\CA to contain the files of the CA. Then create a private key for the CA itself.
openssl req -new -keyout cakey.pem -out careq.pem




Next, generate a self-signed certificate for it
c:\CA>openssl x509 -signkey cakey.pem -req -days 3650 -in careq.pem
-out cacert.pem -extfile c:\OpenSSL\bin\openssl.cnf -extensions v3_ca

openssl.cnf may not exist, so you can run the command like this
c:\CA>openssl x509 -signkey cakey.pem -req -days 3650 -in careq.pem
-out cacert.pem
Run it and enter "ca-pass" as the password for the CA key.


Now you're about to use this CA to sign the certificate request from John (john.csr). However, before that, you need to note that when a CA issues a new certificate, it will put a unique serial number into that certificate. So you need to tell OpenSSL what is the next serial number to use. To do that: To sign c1's certificate request: Store the string "02" into a file serial.txt.
echo 02 > serial.txt
Note that the "0" is necessary. Using "2" will NOT work because OpenSSL expects a hexadecimal number that contains an even number of digits.

To sign c1's certificate request:
c:\CA>openssl x509 -CA cacert.pem -CAkey cakey.pem
-CAserial serial.txt -req -in c:\keys\c1.csr -out c:\keys\c1.cer -days 1095



Run it and enter "ca-pass" as the password for the CA key:


Importing the certificate into the keystore
Now you have got the certificate in c1.cer, you can import it into the keystore. However, before doing that, you must first import the certificate of the CA itself into your keystore as a trusted CA certficate, otherwise it will refuse to import John's certificate. To do that:
c:\keys>keytool -import -alias testCA -file c:\CA\cacert.pem -keystore client.ks



Run it:

Note that it asked you to trust this certificate or not. This is a very important decision. If you trust this certificate as a CA certificate, you will trust all certificates issued by it.

Next, add John's certificate to the keystore to replace his self-signed certificate. This is also done using the -import option.
c:\keys>keytool -import -alias c1 -file c1.cer -keystore client.ks



Run it


To verify, you can list the entries in the keystore:
C:\keys>keytool -list -v -keystore client.ks
Your keystore contains 2 entries. One is trustedCertEntry which is the CA just generated and imported. The other one is c1's certificate. The picture below is the second Entry.


The first certificate is c1's certificate. From the "Issuer" field you can see it is
issued by the test CA, so the next certificate is that of the test CA.
A certificate chain is also called "certificate path". If the certificate of your test CA was issued by yet another CA, then the certificate path would contain the certificate of that other CA as the last certificate.

-- excerpted from Developing Web Services with Apache Axis2
By Kent Ka Iok Tong


If you need trust your self-signed certificate on another machine, you need
  • export the certificate
  • copy the certificate to the other machine
  • import the certificate there

To export the certificate, here is the sample command
keytool -export -alias tomcat -keystore .keystore -rfc -file ep.cer -storepass password


To import the certificate,
keytool -import -alias tomcat -file ep.cer -keystore cacerts -storepass changeit


If you did anything wrong, you can delete it from the keystore
keytool -delete -alias tomcat -keystore cacerts -storepass changeit

Encryption and Decryption

Private key and public key
When you encrypt some text using a key, and you use the same key to decrypt it. This is called "symmetric encryption". If you need to send something private to 100 individuals, then you'll need to negotiate with each such individual to agree on a key (so 100 keys in total). This is troublesome.

To solve the problem, an individual may use something called a "private key" and a "public key". First, he uses some software to generate a pair of keys: One is the private key and the other is the public key. There is an interesting relationship between these two keys: If you use the private key to encrypt something, then it can only be decrypted using the public key (using the private key won't work). The reverse is also true: If you use the public key to encrypt something, then it can only be decrypted using the private key.

Now, suppose that you'd like to send something confidential to an individual Paul (see the diagram below), you can use his public key to encrypt it. Even though other people know his public key, they can't decrypt it (as it is encrypted using the public key, only the private key can decrypt it). Only Paul knows the private key and so only he can decrypt it. This kind of encryption is called "asymmetric encryption".

Digital signature
Suppose that the message you send to Paul is not confidential. However, Paul really needs to be sure that it is really from you. How to do that? You need to prove to Paul that the creator of the message knows your private key. If he does, then he must be you (remember, nobody else is supposed to know your private key). To prove that, you can use your private key to encrypt the message, then send it to Paul. Paul can try to decrypt it using your public key. If it works, then the creator of the message must know your private key and must be you.

However, this is not a good solution, because if the message is long, the encrypted message may double in size and the encryption takes a lot of time. To solve this problem, you can feed the message to a "one way hash function" (see the diagram below). No matter how long the input is, the output from the one way hash function is always the same small size (e.g., 128 bits). In addition, if two input messages are different (maybe just a single bit is different), then the output will be completely different. Therefore, the output message can be considered a small-sized snapshot of the input message. It is therefore called the "message digest" of the original message.

Another feature of the one way hash function is that it is very fast to calculate the digest of a given message, but it is extremely difficult to calculate a message given a digest. Otherwise people would find different messages for a given digest and it is no longer a good snapshot for the message.

Now, to prove to Paul that you know your private key, you can use your private key to encrypt the message digest (because the digest is small, the result is also small and the encryption process will be fast), then send both the message and the message digest to Paul. He can try to decrypt the digest using your public key. Then he can calculate the digest from the message and compare the two. If the two match, then the person producing the encrypted digest must be you.

The encrypted digest is called the "Digital Signature". The whole process of calculating the digest and then encrypting it is called "signing the message".

Signing and encrypting
What if you'd like to sign the message, while keeping the message available to Paul only? Just sign it as usual (see the diagram below) and then encrypt the message and the digest using Paul's public key. When Paul receives it, he uses his private key to decrypt it and then go on to verify the signature as usual.

Certificate and CA
This seems to work very well. However, when you need to say send a confidential message to Paul, you'll need his public key. But how can you find out his public key? You can call him on the phone to ask him. But how can you be sure that the person on the phone is really Paul? If he is a hacker, he will tell you his public key. When you send the message to Paul using the hacker's public key, the hacker will be able to decrypt it using his private key.

If you need to communicate with many different individuals, this will get even more troublesome. To solve the problem, Paul may go to a government authority, show his ID card and etc and tell the authority his public key. Then the authority will generate an electronic message (like an email) stating Paul's public key. Finally, it signs that message using its own private key.

Such a signed message is called a "certificate". That authority is called a "certificate authority (CA)".

Then Paul can put his certificate on his personal web site, email it to you directly or put it onto some 3rd party public web site. From where you get the certificate is unimportant. What is important is that if you can verify the signature of that CA and you trust what the CA says, then you can trust that public key in the certificate. In order to verify the signature, you will need the public key of that CA. What?! You're back to the origin of the problem. However, you only need to find out a single public key for a single entity (the CA), not a public key for everyone you need to communicate with. How to obtain that public key? Usually it is already configured in your browser or you can download it from a trusted web site, newspaper or other sources that you trust.

It means that in order to use asymmetric encryption and digital signature, people need private keys, public keys, a CA and certificates. All these elements combined together is called a "public key infrastructure (PKI)" because it provides a platform for us to use public keys.

Distinguished name
In a real certificate, usually the country, city and the company of that individual are also included like:


Performance issue with asymmetric encryption
Suppose that you'd like to send an encrypted message to Paul. You can use Paul's public key to do that. However, in practice few people would do it this way, because asymmetric encryption is very slow. In contrast, symmetric encryption is a lot faster. To solve this problem, you can generate a random symmetric key, use it to encrypt the message, then use Paul's public key to encrypt that symmetric key and send it to Paul along with the encrypted message. Paul can use his private key to get back the symmetric key and then use it to decrypt the message:


-- excerpted from Developing Web Services with Apache Axis2
By Kent Ka Iok Tong