Establish one-way Https verification for Tomcat, and implement secure communication with mainstream browsers and Android/iOS clients.

Source: Internet
Author: User

Establish one-way Https verification for Tomcat, and implement secure communication with mainstream browsers and Android/iOS clients.

As we all know, iOS9 has begun to force the use of Https to replace the original Http request in terms of networking. Although Http and Https have their own advantages, in general, it is now in this secure information age, developers can no longer leave Https.

There are a lot of Https tutorials on the Internet, but they are scattered. The specific deployment of Web browsers and mobile terminals is not very clear. If they are used in projects, you still need to make some effort, I directly came to a project-level Demo.


Before getting started, I would like to summarize the meanings of several common suffix formats to be processed by the keytool certificate tool:

Jsk/keystoreIndicates a keystore, which can contain multiple key entries (certificates), and key entries (certificates) can also be divided into private and trusted keys, private information generally includes private key, public key, and key entry information. Trusted information generally includes public key and key entry information (Public Key Certificate ). A password is required to open the keystore, and a password is required to open each private key entry (however, it is generally recommended that you set the password to open the private key entry the same as the password to open the keystore, the Demo below is the same.) I have packaged the android apk signature and I can see this.

Csr/certreq, Certificate request file, you submit this to CA, CA will give you a certificate (Public Key Certificate) containing the public key and key entry information in cer format to you.

CerThe public key file used to store a key entry (certificate). After you submit the csr to the CA, the CA will issue it to you. You can also issue the csr through a self-Signed CA, if you already have a key entry (certificate) in the keystore, you can also export the certificate (Public Key Certificate) of its public key and key entry content from a key entry (certificate) in jsk/keystore ).

To sum up, the simplest understanding is that the keystore is equivalent to the SQL database, and various key entries (certificates) are equivalent to the SQL database table, a SQL database table actually has a parent-child (foreign key) Relationship with other tables. This relationship is called the key chain of the key entry (certificate. To make the description easier,The term "keystore" is called "certificate store" and "key entry".DescriptionThe certificate is called certificate, and the certificate of the content of the public key and key entry in cer format is called Public Key Certificate.


Next, we will demonstrate the Demo:

1. Generate the server certificate library and Certificate :(Generate server certificate library and CertificateThere are multiple methods. We recommend that you use a third-party CA to generate a certificate that is more secure and secure (especially for web clients, you can start the "Green address bar/security lock address bar to display the unit name EV international certification mark", etc ))

1-1-1. method 1. Use keytool to generate a self-Signed CA certificate and a self-Signed server certificate (the CA generated below is self-signed, of course, the server generated below is also self-signed, and these certificates will never contain green bars in browsers ):

1. Generate a self-Signed CA: keytool-genkey-v-Alias ca-Keyalg RSA-keystoreD: \ ca_cert_lib.jks-Validity 3650
2. Generate the server certificate: keytool-genkey-v-Alias server-Keyalg RSA-keystoreD: \ server_cert_lib.jks-Validity 365

Note that the certificate name is ca defined as a self-Signed CA certificate,The Certificate Name is server.Certificate storePath:D: \ ca_cert_lib.jksAndD: \ server_cert_lib.jks
ScoreSelf-Signed CA certificateAndServerServer certificate, because under normal circumstances ourServerThe server certificate must be applied to a third-party CA. The third-party CA will use its root certificate to generate a public key for you.Certificate(This process is called a signature from a third-party CA). Here, we need to self-export and display the self-Signed CA to sign the server certificate.

1-1-2. Use a self-Signed CA to sign the CA signature for the server (the server itself is also self-signed. The following is equivalent to replacing the self-Signed server with the CA signature, you may ask who the CA signature is, And the CA can also be someone else's. For example, if wotong is willing to sign your CA, then the CA issuer is wotong, my Demo here does not have an authority to sign it, so my CA is self-signed. This CA is actually a ROOT certificate, but it will not be trusted by any client (such: browser, etc.), that is, using all server certificates issued by the CA will never show green bars in any browser ):

Before signing the certificate to the server, check the current certificate database. They are all signed by themselves:
Keytool-list-v-keystore D: \ ca_cert_lib.jks
Keytool-list-v-keystore D: \ server_cert_lib.jks

Now, use a self-Signed CA to sign the server (if you want wotong CA to sign the server, you can hand over the following csr to wotong ):
1. Generate the server certificate request file: keytool-certreq-Alias server-KeystoreD: \ server_cert_lib.jks>D: \ server. csr(On linux: keytool-certreq-alias server-keystore <path>/server_cert_lib.jks | tee <path>/server. csr)
2. Use a self-Signed CA to sign the server certificate request file and issue the serverServer. cerPublic Key Certificate: keytool-gencert-Alias ca-KeystoreD: \ ca_cert_lib.jks-InfileD: \ server. csr-OutfileD: \ server. cer
3. Generate the self-Signed CA Public Key File: keytool-export-Alias ca-KeystoreD: \ ca_cert_lib.jks-Rfc-fileD: \ ca. cer

You can view the following ca. cer and server. the specific content of the cer Public Key Certificate (pay attention to ca. cer is a self-Signed CA Public Key File, its issuer is itself, and server. cer is the public key file of the server, and its issuer is a self-Signed CA. The two are essentially different. We can see the difference after installing and replying below ), however, they are all base64-encoded strings:
Keytool-printcert-rfc-fileD: \ ca. cer
Keytool-printcert-rfc-fileD: \ server. cer

Install certificate reply (reply to this translation may not be very good, it means: Install the cer Public Key Certificate issued by the CA to the server certificate library, the premise is that the CA's cer Public Key Certificate must also be installed first ):
1. First install the CA Public Key Certificate (this step can not be less, otherwise the following certificate reply is not installed): keytool-importcert-Alias ca-Keystore D: \ server_cert_lib.jks-fileD: \ ca. cer
2. Install the Public Key Certificate of the server (install the certificate reply (signed by CA): keytool-importcert-Alias server-Keystore D: \ server_cert_lib.jks-fileD: \ server. cer

Check the server certificate: keytool-list-v-keystore.D: \ server_cert_lib.jks-alias server

At this time, it is found that the server certificate has changed a lot. First, the certificate has become longer and changed to 2. The server certificate is attached with the information of the self ca root cert of the previous certificate, second, the server publisher is changed to self ca root cert, which means that the SELF-Signed CA is successfully used to sign the server.


1-2-1. The certificate is generated by an authoritative CA (a third-party SSL Certificate Authority). For example, if a free/charged server-side keystore and certificate are generated through wotong, the certificate generated by the CA is more secure, the most intuitive result is that the client uses a Web browser to access the Https website with a green logo (of course, the more gorgeous the display, the more money the authoritative CA has to pay), such as github :, the following example shows how to apply for a free dv ssl Certificate by using vo.

1-2-1. log on to waotong and apply for a free dv ssl certificate.

1-2-2. You need to bind a domain name before applying.

1-2-3. After the application is completed, you need to verify the domain name. You can do it yourself.

1-2-4. The self-Signed CA has mentioned how to generate the csr file. Here, the process of submitting the csr application file is omitted. The following example shows how to generate a public key certificate online, that is, the certificate library of the server is also generated and the Public Key Certificate is imported into the certificate library, the password entered here is actually the password of both the server certificate library and the server certificate (the certificate generated in this way is called 1, and this 1 corresponds to the server certificate imported by the self-Signed CA above ).

After entering the password to generate the certificate, you can download the certificate library and certificate issued by wotong CA to your server, and then deploy it to the corresponding server program. In this case, deploy it to tomcat, to maintain uniformity and intuition, the certificate database name issued by wotong CA is used here. change the name of jks to server_cert_lib.jks.


Generally, the generated Certificate Name (alias) is: 1, which corresponds to the server certificate in the Self-Signed CA mode.

Therefore, after you get the certificate issued by wotong, you can continue to issue it to others. These certificates are trustworthy, because the root certificate above wotong must be trustworthy, otherwise wotong itself cannot be trusted.


2. Through the above steps, you have obtained the certificate library server_cert_lib.jks containing the certificate issued by the CA. Next, configure the server program tomcat certificate library (which can be understood as installing the server keystore on the server)

2-1. installation directory on tomcat/Conf/server. xmlConfigure and enable ctor with the following port 8443 in

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="D:\\server_cert_lib.jks" keystorePass="s123456"


3. Next,You have to operate the client (the client here includes a variety of types: 1 is the mainstream browser, 2 is the Android, 3 is the iOS)

3-1. First, export the server-side Public Key Certificate server. cer in cer format from the server certificate library server_cert_lib.jks in jks format.

keytool -keystore D:\server_cert_lib.jks -export -alias server -file D:\server.cer

3-2. the cer server-side Public Key Certificate is imported to the client-side trust certificate library (this implementation cannot be imported using keytool, but must be implemented based on specific client platforms. This step can be understoodTo the clientInstallServer-side Public Key Certificate)

3-2-1. Web browser implementation: Use a browser to install the server-side server. cer Public Key Certificate

3-2-1-1. in IE browser, double-click server. cer, and then store all the certificates in the following storage, and select a trusted root certificate authority.

3-2-1-2. Firefox cannot directly send the server from the self-Signed CA. the cer Public Key Certificate is imported to the certificate authority, because Firefox will check your server Public Key Certificate server. the highest level issuer of cer is not an authoritative organization (an authoritative third-party CA). If not, it will not pass. For example, if you choose Firefox> advanced> certificate> View certificate> server/Certificate Authority: import server. cer, the system will prompt that the data cannot be imported, so the solution is not to import the server. server, but add an external column address in the server tab. cer, You can import it directly.


3-2-2. Android client implementation

3-2-2-1. Set the server-side Public Key Certificate to server. put cer in the android assert directory, and then use HttpsUtil. getSslSocketFactory initialization (for details about the methods of this tool class, refer to the Demo code below)

Private void initHttpsEngine (boolean isSelfCa) {try {// initialize the server-side Public Key Certificate and obtain SSLSocketFactory sslSocketFactory = HttpsUtil. getSslSocketFactory (new InputStream [] {getAssets (). open ("server. cer ")}); OkHttpClient. builder builder = new OkHttpClient. builder (); if (isSelfCa) {/*** note; if your server. if the cer is issued by a self-Signed CA, you must set the following customVerifier to solve the following exception: * Skip Hostname www. verification on CA, if your server. the cer is issued by a third-party SSL authority. You do not need to set this customVerifier ** ssl. SSLPeerUnverifiedException: Hostname www. not verified: * certificate: sha1/en1_jhnxjvudko/rJqPmJ9XaIMs = * DN: CN = Andy Wu (www., OU = Andy5 Server, O = www., L = Beijing, ST = Guangdong, C = CN * subjectAltNames: [] */HostnameVerifier customVerifier = new HostnameVerifier () {@ Override public boolean verify (String hostname, SSLSession session) {// specify SERVER_URL. You can use if (SERVER_URL.equalsIgnoreCase (hostname) {return true;} else {// use the default OkHostnameVerifier to verify return OkHostnameVerifier. INSTANCE. verify (hostname, session) ;}}; mOkHttpClient = builder. sslSocketFactory (sslSocketFactory ). connectTimeout (30, TimeUnit. SECONDS ). hostnameVerifier (customVerifier ). build ();} else {mOkHttpClient = builder. sslSocketFactory (sslSocketFactory ). connectTimeout (30, TimeUnit. SECONDS ). build () ;}} catch (IOException e) {e. printStackTrace ();}}

3-2-2-2. You can initiate an Https request to the server anywhere. If it is a server certificate issued by a self-Signed CA, domain name verification needs to be ignored for normal communication (depending on the Demo Code), which is obviously not safe.

Public void testHttps (View v) {if (mOkHttpClient = null) {Toast. makeText (getApplicationContext (), "initialize the client keystore and the server public key first! ", Toast. LENGTH_SHORT ). show (); return;} mTvResult. setText ("getting data from" + HTTPS_SERVER_URL + .... "); mWvResult. loadData ("", "text/html", "UTF-8"); Request request = new Request. builder (). url (HTTPS_SERVER_URL ). build (); Call call = mOkHttpClient. newCall (request); call. enqueue (new Callback () {@ Override public void onFailure (Call call, final IOException e) {e. printStackTrace (); runOnUiThread (new Runn Able () {@ Override public void run () {mTvResult. setText ("retrieving data from" + HTTPS_SERVER_URL + "failed! \ N "+ e) ;}}) ;}@ Override public void onResponse (Call call, Response response) throws IOException {final String html = response. body (). string (); runOnUiThread (new Runnable () {@ Override public void run () {mTvResult. setText ("getting data from" + HTTPS_SERVER_URL + "is successful! "); MWvResult. loadData (html," text/html "," UTF-8 ");}});}});}

3-2-2-3. The successful request interface is AS follows: software environment: MIUI 6 (Android 4.4.2) + AS 1.5.1


3-2-3. iOS client implementation

3-2-3-1. Set the server-side Public Key Certificate to server. put cer in the root directory, and then use HttpsUtil. configSecurityPolicy configures AFNetworking Security Options (for details about the methods of this tool class, refer to the Demo code below)

-(IBAction) testHttps :( UIButton *) sender {AFHTTPSessionManager * manager = [AFHTTPSessionManager manager]; NSArray * serverCersNames = [[NSArray alloc] initWithObjects: @ "server. cer ", nil]; [HttpsUtil configSecurityPolicy: manager. securityPolicy serverCers: serverCersNames]; manager. requestSerializer. timeoutInterval = 30366f; manager. responseSerializer = [AFHTTPResponseSerializer serializer]; [_ tvResult SetText: [NSString stringWithFormat: @ "retrieving data from % .... ", HTTPS_SERVER_URL]; [_ wvResult loadHTMLString: @" "baseURL: nil]; [manager GET: HTTPS_SERVER_URL parameters: nil progress: ^ (NSProgress * _ Nonnull downloadProgress) {//} success: ^ (NSURLSessionDataTask * _ Nonnull task, id _ Nullable responseObject) {NSString * result = [[NSString alloc] initWithData: responseObject encoding: callback]; NSLog (@ "Succeeded in obtaining data \ n % @", result); [_ tvResult setText: [NSString stringWithFormat: @ "succeeded in obtaining data from %! ", HTTPS_SERVER_URL]; [_ wvResult loadHTMLString: result baseURL: nil];} failure: ^ (NSURLSessionDataTask * _ Nullable task, NSError * _ Nonnull error) {NSLog (@ "failed to get data \ n % @", error); [_ tvResult setText: [NSString stringWithFormat: @ "failed to get data from %! \ N % @ ", HTTPS_SERVER_URL, error] ;}];}

3-2-3-2. The successful request interface is as follows: software environment: iOS 9.2.1 + Xcode 7.2.1



4. Now, the client (web browser, Android, and iOS) can initiate Https requests to the server. For details, see the Demo (for compatibility demonstration of Self-Signed CA, the Demo uses a self-Signed server certificate ).


5. Additional instructions:

1. All the www. the domain name "" can be changed to an IP address, which can be tested successfully. Of course, nat123 is used for ing during the test to bring the domain name closer to the real environment.








Https two-way authentication will be released later


Original essay, reprinted to indicate the source.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.