Java Digital signature (signature generation, verifying signature with certificate)

Source: Internet
Author: User
Tags base64 hash md5 md5 hash rfc

Partial signature Principle Http://blog.csdn.net/lijiecong/archive/2010/12/24/6096289.aspx (reprint preface: On the net to look for a good article, a piece of I looked for a few days of all things are summed up in, Thank you very much. Author: Li Suko It is the process of finding data, the main unresolved problem is how to obtain the KeyStore file in the Privatekey, the JSDK 1.4 API documents can be known, but incredibly from top to bottom to see 2 times, did not find this method: Load ( )  .......)

A certificate (certificate, also known as Public-key certificate) is a digital voucher that can be used as a trust-relational intermediary with a signature algorithm that digitally signs something, such as a public key. The certificate issuing authority informs the certificate consumer or entity of its public key (Public-key) and some other ancillary information by issuing a certificate. Certificates are widely used in E-commerce security transactions, and certification authorities are also known as CAS (certificate authority).

Apply Certificate



The role of certificates in public key cryptography is to ensure that public key is published in some trusted organizations, and it has important applications in protocol SSL and electronic Transaction protocol set. Figure 1 shows one of the simplest certificate application methods:

Figure 1 Certificate Application method

The



Certificate is applied by:  

(1) A to send its own public key to the CA (certificate authority);  

(2) CA generates A's certificate with its own private key and A's public key , the certificate includes a digital signature for the CA. The Signature object includes the content that needs to be described in the certificate, such as A's public key, timestamp, serial number, and so on, in order to simplify here it may be assumed that there are only three items in the certificate: A's public key pka, timestamp TIME1, serial number IDA. The simple certificate voucher that the CA sends to a can be expressed as: certa=eca[time1,ida,pka]; 

(3) B also sends its own public key PKB to ca; 

(4) b The certificate issued by the CA certb; 

(5) A tells B certificate certa; 

(6) B tells a certificate CERTB. &NBSP

A and B each obtain each other's certificates, using the public key obtained from the CA (in the CA's self-signed book) to verify that each other's certificates are valid and, if valid, to each other's public key. Using the other's public key, you can encrypt the data, or you can use it to authenticate the other person's digital signature. &NBSP

This article, for convenience of illustration, does not use a certificate obtained from a CA, but rather that each party to the communication produces its own visa, meaning that A and B of Figure 1 do not pass through the CA, but only if A and B have each other's certificate. The content and meaning of the  

Certificate are shown in table 1 (for example, in the General X. 509 certificate format). Table 1 certificate content and meaning

Certificate content Significance
Version Tell me which version of the X.509 certificate is currently v1, V2, v3
Serial number Set the serial number of the certificate by the certificate distribution authority
Signature algorithm Identifier What signature algorithm is used for the certificate
Issuer Name The name of the certificate publisher, which is the name of the organization to which this certificate is signed
Validity Period Certificate Valid time range
Subject Name The name of the public key owner or entity that is signed by the certificate issuing authority, using the X.500 protocol, the logo on the Internet is unique. For example: Cn=java,ou=infosec,o=infosec LAB,C=CN represents a subject name.



The various protocols related to the detailed definition of the certificate and its application are not described in detail here, please see documents such as RFC2450, RFC2510, RFC2511, RFC2527, RFC2528, RFC2559, RFC2560, RFC2585, RFC2587, etc. generated from the visa book



A person or organization can request a certificate from a trusted certificate distributor, for example, to obtain a personal certificate from http://ca.pku.edu.cn. Here you can use the J2SDK security tool Keytool hand-generated visa books, the so-called "Subject name" and "Issuer name" certificate in the certificate.

The following produces a self-visa book. After installing J2SDK (here is j2sdk1.4), there is a keytool executable program in the bin directory of the J2SDK installation directory. The following steps are used to produce the Keytool from the visa book:

The first step, using the-genkey command option, is to generate a public-private key pair. In the console interface input: Keytool-genkey-alias testkeypair-keyalg rsa-keysize 1024-sigalg md5withrsa. The-alias here represents the use of this pair of private keys to generate a new KeyStore entry alias (KeyStore is used to store the management key pair and the certificate chain, the default location is in the user's home directory, Hidden files in the name of. KeyStore, of course, you can also specify a path to store the. keystore file;-keyalg is the algorithm used to generate the public key pair, here is the length of the rsa;-keysize definition key;-sigalg is the signature algorithm, Select Md5withrsa, which is signed with RSA, and then use the MD5 hash algorithm summary. Next, the system prompts for some input:

Enter KeyStore password:  abc123
What is your first and last name.
  [Unknown]:
What is your organizational unit name, Li?
  [Unknown]:  Infoseclab
What is your organization's name.
  [Unknown]:  Infoseclab Group
What is the name of your city or region.
  [Unknown]:  Beijing
What is the name of your state or province.
  [Unknown]:  Beijing
What is the two-letter country code for this unit
  [Unknown]:  CN
Cn=li, Ou=infoseclab, O=infoseclab Group, l=beijing, st= Beijing, is C=CN right?
[No]:  y
enter <testkeypair> 's master password (if same as KeyStore password, press ENTER):


The second step, produced from the Visa book, enter the following command:

Keytool-selfcert-alias testkeypair-dname "Cn=li, Ou=infoseclab, O=infoseclab 
Group, l=beijing, ST=Beijing, C=CN" c2/> Enter KeyStore password:  abc123


The third step, export from the visa book, the certificate produced by the above two steps, has been stored in the "Testkeypair" as the alias of the KeyStore entrance, if you use its files, you must export the certificate. Input:

Keytool-export-rfc-alias testkeypair-file mycert.crt  
input keystore Password:  abc123 The
authentication saved in the file <mycert.crt >


In this way, you get a self-signed certificate mycert.crt. Note that the option RFC prints the certificate as a RFC1421-defined, BASE64, final encoded format.

Read Certificate



Java provides rich api,j2sdk1.4 Jsse for secure applications (JAVATM secure Socket Extension) Includes javax.security.certificate packages, and provides an action method for the certificate. And the read operation of the certificate, only with Java.security.cert. Certificatefactory and Java.security.cert.X509Certificate will be all right. The following is part of the code that reads the contents of the certificate:

Import javax.swing.*;
Import java.awt.*;
Import java.awt.event.*;
Import javax.swing.table.*;
Import Java.security.cert.CertificateFactory;
Import Java.security.cert.X509Certificate;
Import java.io.*; 
 public class Caread extends JPanel {private String ca_name;
 Private String ca_itemdata[][] = new STRING[9][2];
 Private string[] ColumnNames = {"certificate field token", "content"};
  Public Caread (String certname) {ca_name=certname;
  /* Three panel to display certificate content */JTabbedPane TabbedPane = new JTabbedPane ();
  JPanel panelnormal = new JPanel ();   
  Tabbedpane.addtab ("General Information", Panelnormal);
  JPanel panelall=new JPanel ();
  Panelall.setlayout (New BorderLayout ());
  Tabbedpane.addtab ("All Information", panelall);
  JPanel panelbase64=new JPanel ();
  Panelbase64.setlayout (New BorderLayout ());
  Tabbedpane.addtab ("Base64 encoded Information", PANELBASE64);
  /* Read the certificate general Information * * Read_normal (Panelnormal);
  /* Read the certificate file string representation content */Read_bin (Panelall);
  * * Read evidence of the original BASE64 encoded form of the certificate document * * * READ_RAW (PANELBASE64);
  Tabbedpane.setselectedindex (0); SetLayout (nEW GridLayout (1, 1));
 Add (TabbedPane); /* Below is the definition of read_normal (), Read_bin (), Read_raw () and main () omitted here ... *


The read function that defines the certificate information is as follows:

private int read_normal (JPanel panel) {String Field;
  try{certificatefactory certificate_factory=certificatefactory.getinstance ("X.509");
  FileInputStream file_inputstream=new FileInputStream (ca_name);
  X509Certificate x509certificate= (X509Certificate) certificate_factory.generatecertificate (File_inputstream);
  Field=x509certificate.gettype ();
  ca_itemdata[0][0]= "type";
  Ca_itemdata[0][1]=field;
  Field=integer.tostring (X509certificate.getversion ());
  ca_itemdata[1][0]= "Version";	
  Ca_itemdata[1][1]=field;
  Field=x509certificate.getsubjectdn (). GetName ();
  ca_itemdata[2][0]= "title";
  Ca_itemdata[2][1]=field; /* The following is similar to omit Field=x509certificate.getnotbefore (). toString (); Get start valid date field=x509certificate. Getnotafter (). ToString (); Get the cut-off date field=x509certificate.getserialnumber (). ToString (16); Get Serial number field= X509certificate.getissuerdn (). GetName (); Get Publisher name Field=x509certificate.getsigalgname (); Get Signature Algorithm field= X509certificate.getpublickey (). Getalgorithm (); Get public key algorithm * * file_inputstream.clOSE ();
  Final JTable table = new JTable (Ca_itemdata, columnnames);
  TableColumn Tc=null;
  TC = Table.getcolumnmodel (). GetColumn (1); 
  Tc.setpreferredwidth (600);
 Panel.add (table);
  }catch (Exception Exception) {exception.printstacktrace ();
 return-1;
return 0; }


If you read the certificate as a string, add the following read_bin this function. where certificatefactory.generatecertificate () This function can extract readable information from the Certificate standard encoding (RFC1421 definition). The Read_bin function code is as follows:

 private int read_bin (JPanel panel) {try{FileInputStream file_inputstream=new Fileinputstrea
  M (ca_name);
  DataInputStream data_inputstream=new DataInputStream (File_inputstream);
  Certificatefactory certificatefactory=certificatefactory.getinstance ("X.509");
  Byte[] Bytes=new byte[data_inputstream.available ()];
  data_inputstream.readfully (bytes);
  Bytearrayinputstream bais=new bytearrayinputstream (bytes);
  JEditorPane Cert_editorpane;
  Cert_editorpane=new JEditorPane (); while (Bais.available () >0) {X509Certificate cert= (x509certificate) certificatefactory.generatecertificate (Bais)
  ;
 Cert_editorpane.settext (Cert_editorpane.gettext () +cert.tostring ());
 } cert_editorpane.disable ();
 JScrollPane edit_scroll=new JScrollPane (Cert_editorpane);
 Panel.add (Edit_scroll);
 File_inputstream.close ();
 Data_inputstream.close ();
  }catch (Exception Exception) {exception.printstacktrace ();
 return-1;	
return 0; }


If you want to get the information encoded by the original certificate, you can use the following code:

private int Read_raw (JPanel panel) {
 try{		
  jeditorpane cert_editorpane=new jeditorpane ();
  String Certtext=null;
  File Inputfile = new file (ca_name);
  FileReader in = new FileReader (inputfile);
  Char[] Buf=new char[2000];
  int Len=in.read (buf,0,2000);
  for (int i=1;i<len;i++) 
  {   
   certtext=certtext+buf[i];
  }
  In.close ();
  Cert_editorpane.settext (certtext);
  Cert_editorpane.disable ();
  JScrollPane edit_scroll=new JScrollPane (cert_editorpane);
  Panel.add (Edit_scroll);
 } catch (Exception Exception) {
  exception.printstacktrace ();
  return-1;
 }
 return 0;	
}


Finally, use this applet to look at the certificate mycert.crt content just generated, write the file name in main ():

public static void Main (string[] args) {
 JFrame frame = new JFrame ("Certificate Reader");
 Frame.addwindowlistener (New Windowadapter () {public
  void windowclosing (WindowEvent e) {system.exit (0);}
 });
 Frame.getcontentpane (). Add (New Caread ("Mycert.crt"), borderlayout.center);
 Frame.setsize (M, 425);
 Frame.setvisible (true);


The contents of the certificate mycert.crt shown in Figure 2, all the information and the Base64 display, are not listed here.

Figure 2 The contents of the certificate Mycert.crt show that some of the contents of the certificate have now been read, so how to use the certificate. We can assume that A and B share a top-secret file F,b trust and have a certificate, which means B has the public key of a. Then A and B-known encryption algorithm (symmetric key algorithm, such as DES algorithm) first encrypt the file F, then the encrypted F for signature and hash summary (such as MD5 algorithm, the purpose is to ensure the integrity of the file), and then send F to B. b After receiving the file, first verify the signature with the public key in A's certificate, and then decrypt it with the cryptographic algorithm by the common knowledge, then you can get the original file. The digital signature used here guarantees that B gets the file, which is a, and a cannot deny that it does not own the file F, because only a has a private key that allows a's public key to authenticate its signature, and the DES algorithm is used to encrypt the file to make it confidential.

Using the DES algorithm encryption decryption function is similar, here does not have the encryption algorithm to do further discussion, detailed see J2SDK JSE part content, the encryption signature, the decryption authentication file structure See Figure 3. Figure 3 Encryption signature, decryption verification file structure diagram

The Deskeydata in the cryptographic function holds the DES encryption key and, if you want to specify it in the program, you can set it to:

Static byte[] Deskeydata = {(byte) 0x01, (Byte) 0x02, (Byte) 0x03, (byte) 0x04, 
(Byte) 0x05, (Byte) 0x06, (Byte) 0x07, (byt e) 0x08};


The cryptographic function is written as:

public static void Crypt (byte[] ciphertext,string outfilename) {		
 try{deskeyspec
  deskeyspec = new Deskeyspec ( Deskeydata);
  Secretkeyfactory keyfactory = secretkeyfactory.getinstance ("DES");
  Secretkey Secretkey = Keyfactory.generatesecret (deskeyspec);
  Cipher cdes = cipher.getinstance ("DES");
  Cdes.init (Cipher.encrypt_mode, secretkey);
  byte[] ct = cdes.dofinal (ciphertext);
  try{
   fileoutputstream out=new fileoutputstream (outfilename);
   Out.write (CT);
   Out.close ();
  } catch (IOException e) {
   e.printstacktrace ();
  }
 } catch (Exception e) {
  e.printstacktrace ();
 }
}


Where the CT is the encrypted content, Outfilename save the file name of the encrypted file. Replacing Cdes.init (Cipher.encrypt_mode, Secretkey) with Cdes.init (Cipher.decrypt_mode, Secretkey) is the decryption file.

File encryption will be signed to the file, to ensure that a sent to B file can not be forged. The following is a function that is signed with the private key stored in the. KeyStore, and the digest algorithm used by the signature is MD5. Where Sigtext is the input array of the signed content, Outfilename is the name of the output file after the signature is saved, Keypassword is the password used to read the KeyStore. Keystorepath is the path to the. keystore file, and the function code is as follows:

public static void Sig (Byte[] Sigtext, String outfilename,string 
keypassword,string keystorepath) {
 char[] Kpass;
 int i;
 try{
  KeyStore ks = keystore.getinstance ("JKS");
  FileInputStream Ksfis = new FileInputStream (keystorepath); 
  Bufferedinputstream Ksbufin = new Bufferedinputstream (Ksfis);  
  Kpass=new char[keypassword.length ()];
  For (I=0;i<keypassword.length (); i++)
   Kpass[i]=keypassword.charat (i);
  Ks.load (Ksbufin, kpass);
  Privatekey Priv = (privatekey) ks.getkey (keystorealias,kpass);
  Signature rsa=signature.getinstance ("Md5withrsa");  
  Rsa.initsign (PRIV);
  Rsa.update (sigtext);
  Byte[] Sig=rsa.sign ();
  System.out.println ("Sig are Done");
  try{
   fileoutputstream out=new fileoutputstream (outfilename);
   Out.write (SIG);
   Out.close ();
  } catch (IOException e) {
   e.printstacktrace ();
  }    
 } catch (Exception e) {
  e.printstacktrace ();
 }
}


The verification signature needs to hold the signature file and the signed file as well as the certificate, in which, UpdateData holds the content of the signed file, sigedtext the contents of the signature, CertName is the certificate name. Verify the signature code as follows:

public static void Verisig (byte[] updatedata, byte[] sigedtext) {
    try{  
        certificatefactory 
Certificatefactory=certificatefactory.getinstance ("X.509");
		FileInputStream fin=new FileInputStream (certname);
		X509Certificate 
certificate= (x509certificate) certificatefactory.generatecertificate (Fin);
	    PublicKey pub = Certificate.getpublickey ();
	    Signature rsa=signature.getinstance ("Md5withrsa");
        Rsa.initverify (pub);
        Rsa.update (updatedata);
        Boolean verifies=rsa.verify (Sigedtext);
        SYSTEM.OUT.PRINTLN ("verified" +verifies);
        if (verifies) {
               System.out.println ("Verify is done!");
          } else{
               System.out.println ("Verify is not successful");
        }	    
	  catch (Exception e) {    
            e.printstacktrace ();	           	
	 }
}


You can use Keytool to generate two self-signed certificates, or to apply for two certificates to a CA. Using Java to write encryption and validation programs, the example above is a very simple certificate application, and the actual protocol is much more complex to use for certificates, such as SSL.

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.