Self-Signed X.509 digital certificate generation and Verification

Source: Internet
Author: User
Tags dname
Self-Signed X.509 digital certificate generation and Verification

 

Self-Signed X.509 digital certificate generation and Verification

 

Digital Certificates are used to mark the identity of network users. In Web applications, digital certificates are widely used, such as secure email, secure website access, Secure Electronic Transaction Processing, and secure electronic transactions.

The format of digital certificates generally adopts the X.509 international standard. At present, the digital certificate certification center mainly issues Security Email certificates, personal and enterprise ID certificates, server certificates, and code signature certificates.

 

Digital certificates are issued by the Certificate Authority. Generally, the Certificate Authority must register and authenticate the Certificate Authority. In enterprise applications, enterprises are often used to issue digital certificates as the issuing authority (without prior authentication). The scope of use of certificates is also within the enterprise, such a certificate is called "Self-signed.

 

The digital certificate uses a public key and password system. Each user has a private key (Private Key) that is only owned by himself, which is used for decryption and signature. At the same time, the digital certificate has a Public Key (Public Key) it can also be made public for encryption and signature verification.

 

The following describes the generation and verification methods of self-signed certificates commonly used in projects. For simplicity, we assume that all website users use the same digital certificate clientca.

 

I. Server Side

 

Log on to the remote server, generate a certificate on the server, and download the certificate. Jdk1.5 and above should be installed on the server, because we need to use the built-in JDK keytool, which is located in the bin directory of the JDK installation directory.

1. Generate the key database and root certificate

If the certificate is used for 1st times, it is likely that no key database is available on the server. You can use the following command to create a key database (keystore ).

Keytool-genkey-dname "cn = issuer name, ou = issuer's department, O = issuer's company, L = Kunming, St = Yunnan, C = China "-alias ipccca-keyalg RSA-keysize 1024-keystore ipccca-keypass root certificate password-storepass library Password

 

After the script is run, the private key database file ipccca is generated in the current user's home directory (for example, C:/Documents and Settings/Administrator directory. Note: You need to set two passwords, one is the root certificate password keypass, and the other is the Database Password storepass. If you are not sure about the difference between the two, it is best to set them to the same.

 

2. Generate a self-signed certificate

Run the following command to generate a self-signed certificate:

Keytool-genkey-dname "cn = issuer name, ou = issuer's department, O = issuer's company, L = Kunming, St = Yunnan, C = China "-alias clientca-keyalg RSA-keysize 1024-keystore ipccca-keypass 123456-storepass Database Password-validity 1

This certificate is a self-signed certificate, and its alias is clientca, which is stored in the previously generated keystore file (ipccca. This requires the Database Password (storepass) to access the database, which must be the same as that in step 1. Kepass is the public key of the Certificate. You must provide this key when verifying the certificate.

To facilitate testing, we set the certificate validity period to one day. In this way, you must download the certificate again every day.

3. view the keystore

You can use the following command to view the two generated keys:

Keytool-list-keystore ipccca-storepass Database Password

The two keys are listed as follows:

Your keystore contains 2 Inputs

 

Clientca, 2011-3-30, keyentry,

Authentication fingerprint (MD5): 10: B8: 51: 54: 7b: 1c: 60: 7c: 89: E7: B6: 8e: 71: E5: E1: E7

Ipccca, 2011-3-30, keyentry,

Authentication fingerprint (MD5): C3: E3: 7d: 7c: 9B: AA: 05: 84: 92: AF: 93: 18: 42: D2: 1c: 07

 

4. Download the certificate

We can place a servlet on the server to provide download of the Self-signed certificate:

Private Static final long serialversionuid = 1l;

// Validity period days

Private Static final int max_days = 1;

// Keystore Password

Private Static final char [] Password = "b7-@ 95598". tochararray ();

// Keystore file path

Private Static final string keystorefilename = "C: // Documents and Settings // administrator // ipccca ";

// Certificate file name

Private Static final string certfilename = "client. Cer ";

// Certificate alias

Private Static final string alias = "clientca ";

Private keystore;

Private string sigalgrithm;

// Read the keystore

Private keystore loadkeystore (string keystorepath ){

Keystore Ks = NULL;

Try {

Fileinputstream fin = new fileinputstream (keystorepath );

Ks = keystore. getinstance ("jks ");

KS. Load (FIN, password );

Fin. Close ();

Return KS;

} Catch (exception e ){

System. Out. println (E. getmessage ());

}

Return KS;

}

 

// Obtain certinfo

Private x509certinfo getcertinfo (certificate C, string alias ){

X509certinfo certinfo = NULL;

Try {

// Extract certificate information from the certificate to be issued

Byte [] encod2 = C. getencoded (); // obtain the certificate content (encoded bytes)

X509certimpl cimp2 = new x509certimpl (encod2); // create an x509certimpl Image

Sigalgrithm = cimp2.getsigalgname ();

// Obtain the x509certinfo object

Certinfo = (x509certinfo) cimp2.get (x509certimpl. Name

+ "." + X509certimpl. info );

 

} Catch (exception e ){

System. Out. println (E. getmessage ());

}

Return certinfo;

}

 

// Modify the validity period

Private void updatevalidity (x509certinfo Cinfo, int days ){

// Obtain the current time

Date d1 = new date ();

// The validity period is extended by N days after the current date

Date D2 = new date (d1.gettime () + days * 24*60*60 * 1000l );

// Create a validity period object

Certificatevalidity CV = new certificatevalidity (D1, D2 );

Try {

Cinfo. Set (x509certinfo. validity, CV); // set the validity period

} Catch (exception e ){

E. printstacktrace ();

}

}

 

// Store the certificate

Private void savecert (keystore KS, char [] storepass, string alias,

Privatekey pkey, char [] keypass, x509certinfo Cinfo, string algrithm ){

Try {

X509certimpl Cert = new x509certimpl (Cinfo); // create a certificate

CERT. Sign (pkey, algrithm); // sign it with the CA private key

// Obtain the certificate chain of the corresponding entry of the alias

Certificate [] Chain = new certificate [] {Cert };

// Add entries to the keystore. If an existing alias is used, the existing entries are overwritten.

KS. setkeyentry (alias, pkey, keypass, chain );

// Store the keystore to a file

Fileoutputstream fout = new fileoutputstream (keystorefilename );

Keystore. Store (fout, password );

Fout. Close ();

} Catch (exception e ){

E. printstacktrace ();

}

}

// Export the certificate

Private void exportcert (keystore KS, string alias, httpservletresponse response ){

Try {

Certificate Cert = keystore. getcertificate (alias );

// Obtain the certificate content (in the encoded format)

Byte [] Buf = cert. getencoded ();

// Write the Certificate file

Response. setcontenttype ("application/X-download ");

Response. addheader ("content-disposition", "attachment; filename ="

+ Certfilename );

Outputstream out = response. getoutputstream ();

Out. Write (BUF );

Out. Close ();

} Catch (exception e ){

E. printstacktrace ();

}

}

/**

* @ See httpservlet # httpservlet ()

*/

Public getnewcert (){

Super ();

// Todo auto-generated constructor stub

}

 

/**

* @ See httpservlet # doget (httpservletrequest request, httpservletresponse response)

*/

Protected void doget (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {

Try {

Keystore = loadkeystore (keystorefilename); // read the keystore

 

Certificate c = keystore. getcertificate (alias); // read the certificate

X509certinfo Cinfo = getcertinfo (C, alias); // obtain the certinfo Certificate

Updatevalidity (Cinfo, max_days); // modify the certificate validity period

 

// Read the private key of the CA from the keystore

Privatekey pkey = (privatekey) keystore. getkey (alias, "123456"

. Tochararray ());

 

// Store the keystore to the keystore File

Savecert (keystore, password, alias, pkey, "123456". tochararray (), Cinfo, sigalgrithm );

Exportcert (keystore, alias, response );

} Catch (exception e ){

E. printstacktrace ();

}

}

 

/**

* @ See httpservlet # dopost (httpservletrequest request, httpservletresponse response)

*/

Protected void dopost (httpservletrequest request, httpservletresponse response) throws servletexception, ioexception {

Doget (request, response );

}

 

}

The role of this servlet is:

When you request this Serlvet, extract the clientca certificate from the keystore and change the certificate validity period to the next day.

That is to say, when the user client requests the servlet, a new certificate can be obtained. The validity period of this certificate has been extended for one day.

The purpose is to check the certificate downloaded by the user after each login. If the certificate has expired, request this servlet to obtain a valid new certificate.

 

Ii. Client

The client may be any device, including PCs and mobile terminals. Assume that the client is a mobile terminal based on android1.6 or above, the following is the certificate verification class mycertificate of the Java client:

Public class mycertificate {

Private Static string tag = "mycertificate ";

Public static certificate readcert (File file ){

Certificate c = NULL;

Try {

Certificatefactory cf = certificatefactory. getinstance ("X.509 ");

Fileinputstream in1 = new fileinputstream (File );

C = Cf. generatecertificate (in1 );

In1.close ();

} Catch (exception e ){

Log. E (TAG, E. tostring ());

}

Return C;

}

// Verify the certificate validity

Public static Boolean verifycert (certificate c ){

Publickey pBK = C. getpublickey ();

Try {

C. Verify (pbk );

Return true;

} Catch (exception e ){

Log. E (TAG, "certificate is invalid ");

}

Return false;

}

// Verify the certificate validity period

Public static int verifycertvalidity (date, certificate c ){

Int I = 0;

X509certificate t = (x509certificate) C;

Try {// valid

T. checkvalidity (date );

} Catch (certificateexpiredexception e) {// expiration

Log. E (TAG, "certificate expired ");

I =-1;

} Catch (certificatenotyetvalidexception e) {// not activated

Log. E (TAG, "certificate too early ");

I =-2;

}

Return I;

}

Public static Boolean verify (context CTX ){

Activity Act = (activity) CTX;

Boolean B = false;

// Check whether the certificate file exists

File file = new file (environment. getexternalstoragedirectory () + act. getstring (R. String. cert_dir) + act. getstring (R. String. cert_file ));

If (! File. exists ()){

Act. showdialog (1 );

} Else {

Date d = new date (); // obtain the current time

Certificate c = mycertificate. readcert (File); // read the Certificate file

// Verify the certificate validity

If (! Mycertificate. verifycert (c )){

Act. showdialog (0); // invalid certificate

} Else {

// Verify the certificate validity period

Int I = mycertificate. verifycertvalidity (D, C );

Switch (I ){

Case 0: // valid

B = true;

Break;

Case-1: // expired

Act. showdialog (2 );

Break;

Case-2: // not effective

Act. showdialog (3 );

Break;

}

}

}

Return B;

}

}

You can use it in related activities as follows:

Private void login (string ACC, string pass ){

String url = This. getstring (R. String. port_login_url );

Url = string. Format (URL, ACC, pass );

// Log. I (TAG, URL );

Mainloginhandler handler = new mainloginhandler ();

Modules = saxhelper. getmodules (URL, Handler );

// Log. I (TAG, systems. tostring ());

Log. I ("modules:", "" + modules );

If (modules! = NULL ){

String status = (string) modules. Get ("loginstatus ");

If ("true". Equals (Status )){//Logon successful

If (! Verifycert ()){

Return;

}

Bundle bundle = new bundle ();

Bundle. putserializable ("data ",

(Serializable) modules. Get ("modules "));

Gotoactivity (main. Class, bundle );

} Else {

Toast. maketext (getbasecontext (), "the user name or password is incorrect! ",

Toast. length_short). Show ();

}

}

}

Private Boolean verifycert (){

Return mycertificate. Verify (this );

}

// Create activity hosting dialog box

Protected dialog oncreatedialog (int id ){

Log. E ("::::", "showdialog! ");

String MSG = "";

Switch (ID ){

Case 1:

MSG = "the certificate has not been downloaded! Click "yes" to download the certificate. ";

Break;

Case 2:

MSG = "certificate expired! Click "yes" to download the certificate again. ";

Break;

Case 3:

MSG = "the certificate has not taken effect! Please log on again after the certificate takes effect. ";

// For an invalid certificate, you do not need to download it again.

Return new alertdialog. Builder (this)

. Setmessage (MSG)

. Setnegativebutton ("yes ",

New dialoginterface. onclicklistener (){

Public void onclick (dialoginterface dialog,

Int which ){

Dialog. Dismiss (); // removedialog (0); remove dialog box

}

}). Create ();

Case 4:

Return new alertdialog. Builder (this)

. Setmessage ("location source not set! Are you sure you want to set the location source? ")

. Setpositivebutton ("yes ",

New dialoginterface. onclicklistener (){

Public void onclick (dialoginterface dialog,

Int which ){

// Go to the GPS settings page

Intent intent = new intent (

Settings. action_security_settings );

Startactivityforresult (intent, 0 );

}

})

. Setnegativebutton ("no ",

New dialoginterface. onclicklistener (){

Public void onclick (dialoginterface dialog,

Int which ){

Dialog. Dismiss (); // removedialog (0); remove dialog box

}

}). Create ();

Default:

MSG = "invalid certificate! Click "yes" to download the certificate again. ";

}

Return new alertdialog. Builder (this). setmessage (MSG)

. Setpositivebutton ("yes", new dialoginterface. onclicklistener (){

Public void onclick (dialoginterface dialog, int which ){

// Start to download the certificate

Downloadcert ();

}

})

. Setnegativebutton ("no", new dialoginterface. onclicklistener (){

Public void onclick (dialoginterface dialog, int which ){

Dialog. Dismiss (); // removedialog (0); remove dialog box

}

}). Create ();

}

The code in the bold red part calls mycertificate. Verify (). The oncreatedialog method returns the certificate verification result in the dialog box.

Http://www.cnblogs.com/encounter/archive/2011/05/13/2188492.html

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: info-contact@alibabacloud.com 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.