??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品国产欧美,91精品在线影院,99re66热这里只有精品3直播http://www.aygfsteel.com/Archangelsy/category/20557.htmlLSYzh-cnWed, 12 Sep 2007 05:10:36 GMTWed, 12 Sep 2007 05:10:36 GMT60如何用Javad使用证书http://www.aygfsteel.com/Archangelsy/articles/142911.htmlarchangelarchangelWed, 05 Sep 2007 07:18:00 GMThttp://www.aygfsteel.com/Archangelsy/articles/142911.htmlhttp://www.aygfsteel.com/Archangelsy/comments/142911.htmlhttp://www.aygfsteel.com/Archangelsy/articles/142911.html#Feedback0http://www.aygfsteel.com/Archangelsy/comments/commentRss/142911.htmlhttp://www.aygfsteel.com/Archangelsy/services/trackbacks/142911.html
证书(CertificateQ也Upublic-key certificate)是用某种{֐法Ҏ(gu)些内?比如公钥)q行数字{֐后得到的、可以用来当成信dpM介的数字凭证。证书发行机构通过发行证书告知证书使用者或实体其公?public-key)以及其它一些辅助信息。证书在?sh)子商务安全交易中有着q泛的应用,证书发行机构也称CA(Certificate Authority)?

应用证书


证书在公钥加密应用中的作用是保证公钥在某些可信的机构发布Q其在协议SSL、电(sh)子交易协议SET{方面有重要的应用。图1昄了一个最单的证书应用Ҏ(gu)Q?



? 证书应用Ҏ(gu)


证书的应用步骤是Q?

Q?Q?A把自q公钥PKA送到CA(Certificate Authority)Q?

Q?Q?CA用自qU钥和A的公钥生成A的证书,证书内包括CA的数字签名。签名对象包括需要在证书中说明的内容Q比如A的公钥、时间戳、序列号{,Z化这里不妨假设证书中只有三项内容QA的公钥PKA、时间戳TIME1、序列号IDA。那么CA发送给A的简单证书凭证可表达为:CertA=Eca[TIME1,IDA,PKA]Q?

Q?Q?B同样把自q公钥PKB送到CAQ?

Q?Q?B得到CA发布的证书CertB;

Q?Q?A告知B证书CertAQ?

Q?Q?B告知A证书CertB?

A、B各自得到Ҏ(gu)证书后,利用从CA得到的公?在CA的自{证书中)验证彼此Ҏ(gu)的证书是否有效,如果有效Q那么就得到了彼此的公钥。利用对方的公钥Q可以加密数据,也可以用来验证对方的数字{֐?

本文Z方便说明Qƈ没有使用从CA获得的证书,而是通信双方各自产生自签证书Q也是说图1的A和Bq没有经qCAQ不q前提是A和B之间是互相拥有对方的证书?

证书的内容和意义如表1所C(q里以通用X .509证书格式ZQ?

? 证书内容和意?/center>

证书内容意义
Version告诉q个X.509证书是哪个版本的Q目前有v1、V2、v3
Serial Numberp书分发机构设|证书的序列?/td>
Signature Algorithm Identifier证书采用什么样的签名算?/td>
Issuer Name证书发行者名Q也是l这个证书签名的机构?/td>
Validity Period证书有效旉范围
Subject Name被证书发行机构签名后的公钥拥有者或实体的名字,采用X.500协议Q在Internet上的标志是惟一的。例如:CN=Java,OU=Infosec,O=Infosec Lab,C=CN表示一个subject name?/td>


对证书的详细定义及其应用相关的各U协议,q里不加详细说明Q详l细节请查看RFC2450、RFC2510、RFC2511、RFC2527、RFC2528、RFC2559、RFC2560、RFC2585、RFC2587{文档?

生成自签证书



个h或机构可以从信Q的证书分发机构申请得到证书,比如_可以从http://ca.pku.edu.cn 得到一个属于个人的证书。这里可以利用J2SDK的安全工具keytool手工产生自签证书Q所谓自{证书是指证书中的“Subject Name”和“Issuer Name”相同的证书?

下面产生一个自{证书。安装完J2SDKQ这里用的是J2SDK1.4Q后Q在J2SDK安装目录的bin目录下,有一个keytool的可执行E序。利用keytool产生自签证书的步骤如下:

W一步,?genkey命o选项Q生公U密钥对。在控制台界面输入:keytool -genkey -alias testkeypair -keyalg RSA -keysize 1024 -sigalg MD5withRSA。这里的-alias表示使用q对公私密钥产生新的keystore入口的别?keystore是用来存攄理密钥对和证书链的,~省位置是在使用者主目录下,?keystore为名的隐藏文Ӟ当然也可指定某个路径存放.keystore文g)Q?keyalg是生公U钥Ҏ(gu)用的法Q这里是RSAQ?keysize定义密钥的长度;-sigalg是签名算法,选择MD5withRSAQ即用RSA{֐Q然后用MD5哈希法摘要。接下来Q系l会提示q行一些输入:

输入keystore密码Q? abc123(zhn)的名字与姓氏是什么?  [Unknown]Q? Li(zhn)的l织单位名称是什么?  [Unknown]Q? InfosecLab(zhn)的l织名称是什么?  [Unknown]Q? InfosecLab Group(zhn)所在的城市或区域名U是什么?  [Unknown]Q? Beijing(zhn)所在的州或省䆾名称是什么?  [Unknown]Q? Beijing该单位的两字母国家代码是什? [Unknown]Q? CNCN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN 正确吗?[否]Q? y输入<testkeypair>的主密码 (如果?keystore 密码相同Q按回RQ:


W二步,产生自签证书Q输入以下命令:

keytool -selfcert -alias testkeypair -dname "CN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN" 输入keystore密码Q? abc123


W三步,导出自签证书Q由上面两步产生的证书,已经存放在以“testkeypair”ؓ别名的keystore入口了,如果使用其文Ӟ必须导出证书。输?

keytool -export -rfc -alias testkeypair -file mycert.crt  输入keystore密码Q? abc123保存在文件中的认?<mycert.crt>


q样Q就得到了一个自{证书mycert.crt。注意,选项rfc是把证书输出为RFC1421定义的、用Base64最l编码的格式?

d证书



Java为安全应用提供了丰富的APIQJ2SDK1.4 的JSSE (JavaTM Secure Socket Extension) 包括javax.security.certificate包,q且提供对证书的操作Ҏ(gu)。而对证书的读操作Q只用java.security.cert. CertificateFactory和java.security.cert.X509Certificate可以了。下面是d证书内容的部分代码:

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 = {"证书字段标记","内容" }; public CARead(String CertName) {  CA_Name=CertName;  /* 三个Panel用来昄证书内容*/  JTabbedPane tabbedPane = new JTabbedPane();  JPanel panelNormal = new JPanel();  tabbedPane.addTab("普通信?, panelNormal);     JPanel panelAll=new JPanel();  panelAll.setLayout(new BorderLayout());  tabbedPane.addTab("所有信?,panelAll);  JPanel panelBase64=new JPanel();  panelBase64.setLayout(new BorderLayout());  tabbedPane.addTab("Base64~码信息",panelBase64);  /* d证书常规信息 */  Read_Normal(panelNormal);  /* d证书文g字符串表C内?*/  Read_Bin(panelAll);  /* d证原始Base64~码形式的证书文?*/  Read_Raw(panelBase64);  tabbedPane.setSelectedIndex(0);  setLayout(new GridLayout(1, 1));   add(tabbedPane); }  /*以下是定义的Read_Normal()QRead_Bin(),Read_Raw()以及main()   q里省略...   */  }



定义证书信息的读取函数如下:

												
												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]="cd";  CA_ItemData[0][1]=Field;  Field=Integer.toString(x509certificate.getVersion());  CA_ItemData[1][0]="版本";  CA_ItemData[1][1]=Field;	  Field=x509certificate.getSubjectDN().getName();  CA_ItemData[2][0]="标题";  CA_ItemData[2][1]=Field;  /* 以下cMQ这里省?  Field=x509certificate.getNotBefore().toString();得到开始有效日? Field=x509certificate. getNotAfter().toString();得到截止日期  Field=x509certificate.getSerialNumber().toString(16);得到序列? Field=x509certificate.getIssuerDN().getName();得到发行者名  Field=x509certificate.getSigAlgName();得到{֐法  Field=x509certificate.getPublicKey().getAlgorithm();得到公钥法 */  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;}



如果以字W串形式d证书Q加入下面Read_Binq个函数。其中CertificateFactory.generateCertificate() q个函数可以从证书标准编?RFC1421定义)中解出可M息。Read_Bin函数代码如下Q?

												
												private int Read_Bin(JPanel panel){ try{  FileInputStream file_inputstream=new FileInputStream(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;	}



如果要得到原始证书编码后的信息,则可用如下代码:

												
												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;	}



最后用q个程序看一看刚才生成的证书mycert.crt内容Q把文g名写入main()中:

												
												public static void main(String[] args) { JFrame frame = new JFrame("证书阅读?); frame.addWindowListener(new WindowAdapter() {  public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.getContentPane().add(new CARead("mycert.crt"),BorderLayout.CENTER); frame.setSize(700, 425); frame.setVisible(true);}



证书mycert.crt的内Ҏ(gu)C如?所C,所有信息和Base64的显C内容,q里不再列D?

现在已经d了证书的一些内容,那么怎样使用证书呢?我们可以假设A和B要共享一个绝密的文gFQB信Qq拥有A的证书,也就是说B拥有A的公钥。那么A通过A和Bq的加密算?对称密钥法Q比如DES法)先加密文件FQ然后对加密后的Fq行{֐和散列摘?比如MD5法Q目的是保证文g的完整?Q然后把F发送到B。B收到文g后,先用A的证书中的公钥验证签名,然后再用通过q的加密算法解密,可以得到原文g了。这里用的数字{֐Q可以保证B得到的文Ӟ是A的,A不能否认其不拥有文gFQ因为只有A拥有可以让A的公钥验证其{֐的私钥,同时q里使用DES法加密Q得文件有保密性?

使用DES法的加密解密函数类|q里不对加密法做进一步讨论,详细LJ2SDK的JSE部分内容Q加密签名、解密验证文件结构见??



? 加密{֐、解密验证文件结构图



加密函数中的desKeyData存放DES加密密钥Q如果要在程序中指定Q可以设|ؓQ?

static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };


加密函数写成Q?

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(); }}


其中ct是加密后的内容,outFileName保存加密后文件的文g名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)是解密文g了?

文g加密后就要对文g{֐Q保证A发送到B的文件不可伪造。下面是用存攑֜.keystore中的U钥q行{֐的函敎ͼ{֐使用的摘要算法是MD5。其中sigText是被{֐内容的输入数l,outFileName是保存签名后输出文g的名UͼKeyPassword是读取Keystore使用的密码,KeyStorePath是存?keystore文g的\径,函数代码如下Q?

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 is done");  try{   FileOutputStream out=new FileOutputStream(outFileName);   out.write(sig);   out.close();  }catch(IOException e){   e.printStackTrace();  }     }catch(Exception e){  e.printStackTrace(); }}


验证{֐需要存攄名文件和被签名的文g以及证书Q其中,updateData存放被签名文件的内容QsigedText存放得到的签名内容,CertName是证书名。验证签名代码如下:

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();	           		 }}


可以用keytool产生两个自签的签名证书,或者到某个CAȝ请两个证书。用Java~写加密和验证程序,上述例子只是一个非常简单的证书应用Q实际协议对证书的?比如SSL)要比q个复杂多了?



? 加密{֐、解密验证文件结构图



加密函数中的desKeyData存放DES加密密钥Q如果要在程序中指定Q可以设|ؓQ?

												
												static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };


加密函数写成Q?

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(); }}


其中ct是加密后的内容,outFileName保存加密后文件的文g名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)是解密文g了?

文g加密后就要对文g{֐Q保证A发送到B的文件不可伪造。下面是用存攑֜.keystore中的U钥q行{֐的函敎ͼ{֐使用的摘要算法是MD5。其中sigText是被{֐内容的输入数l,outFileName是保存签名后输出文g的名UͼKeyPassword是读取Keystore使用的密码,KeyStorePath是存?keystore文g的\径,函数代码如下Q?

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 is done");  try{   FileOutputStream out=new FileOutputStream(outFileName);   out.write(sig);   out.close();  }catch(IOException e){   e.printStackTrace();  }     }catch(Exception e){  e.printStackTrace(); }}


验证{֐需要存攄名文件和被签名的文g以及证书Q其中,updateData存放被签名文件的内容QsigedText存放得到的签名内容,CertName是证书名。验证签名代码如下:

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();	           		 }}


可以用keytool产生两个自签的签名证书,或者到某个CAȝ请两个证书。用Java~写加密和验证程序,上述例子只是一个非常简单的证书应用Q实际协议对证书的?比如SSL)要比q个复杂多了?

d证书



Java为安全应用提供了丰富的APIQJ2SDK1.4 的JSSE (JavaTM Secure Socket Extension) 包括javax.security.certificate包,q且提供对证书的操作Ҏ(gu)。而对证书的读操作Q只用java.security.cert. CertificateFactory和java.security.cert.X509Certificate可以了。下面是d证书内容的部分代码:

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 = {"证书字段标记","内容" }; public CARead(String CertName) {  CA_Name=CertName;  /* 三个Panel用来昄证书内容*/  JTabbedPane tabbedPane = new JTabbedPane();  JPanel panelNormal = new JPanel();  tabbedPane.addTab("普通信?, panelNormal);     JPanel panelAll=new JPanel();  panelAll.setLayout(new BorderLayout());  tabbedPane.addTab("所有信?,panelAll);  JPanel panelBase64=new JPanel();  panelBase64.setLayout(new BorderLayout());  tabbedPane.addTab("Base64~码信息",panelBase64);  /* d证书常规信息 */  Read_Normal(panelNormal);  /* d证书文g字符串表C内?*/  Read_Bin(panelAll);  /* d证原始Base64~码形式的证书文?*/  Read_Raw(panelBase64);  tabbedPane.setSelectedIndex(0);  setLayout(new GridLayout(1, 1));   add(tabbedPane); }  /*以下是定义的Read_Normal()QRead_Bin(),Read_Raw()以及main()   q里省略...   */  }



定义证书信息的读取函数如下:

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]="cd";  CA_ItemData[0][1]=Field;  Field=Integer.toString(x509certificate.getVersion());  CA_ItemData[1][0]="版本";  CA_ItemData[1][1]=Field;	  Field=x509certificate.getSubjectDN().getName();  CA_ItemData[2][0]="标题";  CA_ItemData[2][1]=Field;  /* 以下cMQ这里省?  Field=x509certificate.getNotBefore().toString();得到开始有效日? Field=x509certificate. getNotAfter().toString();得到截止日期  Field=x509certificate.getSerialNumber().toString(16);得到序列? Field=x509certificate.getIssuerDN().getName();得到发行者名  Field=x509certificate.getSigAlgName();得到{֐法  Field=x509certificate.getPublicKey().getAlgorithm();得到公钥法 */  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;}



如果以字W串形式d证书Q加入下面Read_Binq个函数。其中CertificateFactory.generateCertificate() q个函数可以从证书标准编?RFC1421定义)中解出可M息。Read_Bin函数代码如下Q?

private int Read_Bin(JPanel panel){ try{  FileInputStream file_inputstream=new FileInputStream(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;	}



如果要得到原始证书编码后的信息,则可用如下代码:

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;	}



最后用q个程序看一看刚才生成的证书mycert.crt内容Q把文g名写入main()中:

public static void main(String[] args) { JFrame frame = new JFrame("证书阅读?); frame.addWindowListener(new WindowAdapter() {  public void windowClosing(WindowEvent e) {System.exit(0);} }); frame.getContentPane().add(new CARead("mycert.crt"),BorderLayout.CENTER); frame.setSize(700, 425); frame.setVisible(true);}



证书mycert.crt的内Ҏ(gu)C如?所C,所有信息和Base64的显C内容,q里不再列D?

现在已经d了证书的一些内容,那么怎样使用证书呢?我们可以假设A和B要共享一个绝密的文gFQB信Qq拥有A的证书,也就是说B拥有A的公钥。那么A通过A和Bq的加密算?对称密钥法Q比如DES法)先加密文件FQ然后对加密后的Fq行{֐和散列摘?比如MD5法Q目的是保证文g的完整?Q然后把F发送到B。B收到文g后,先用A的证书中的公钥验证签名,然后再用通过q的加密算法解密,可以得到原文g了。这里用的数字{֐Q可以保证B得到的文Ӟ是A的,A不能否认其不拥有文gFQ因为只有A拥有可以让A的公钥验证其{֐的私钥,同时q里使用DES法加密Q得文件有保密性?

使用DES法的加密解密函数类|q里不对加密法做进一步讨论,详细LJ2SDK的JSE部分内容Q加密签名、解密验证文件结构见??



? 加密{֐、解密验证文件结构图



加密函数中的desKeyData存放DES加密密钥Q如果要在程序中指定Q可以设|ؓQ?

static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };


加密函数写成Q?

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(); }}


其中ct是加密后的内容,outFileName保存加密后文件的文g名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)是解密文g了?

文g加密后就要对文g{֐Q保证A发送到B的文件不可伪造。下面是用存攑֜.keystore中的U钥q行{֐的函敎ͼ{֐使用的摘要算法是MD5。其中sigText是被{֐内容的输入数l,outFileName是保存签名后输出文g的名UͼKeyPassword是读取Keystore使用的密码,KeyStorePath是存?keystore文g的\径,函数代码如下Q?

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 is done");  try{   FileOutputStream out=new FileOutputStream(outFileName);   out.write(sig);   out.close();  }catch(IOException e){   e.printStackTrace();  }     }catch(Exception e){  e.printStackTrace(); }}


验证{֐需要存攄名文件和被签名的文g以及证书Q其中,updateData存放被签名文件的内容QsigedText存放得到的签名内容,CertName是证书名。验证签名代码如下:

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();	           		 }}


可以用keytool产生两个自签的签名证书,或者到某个CAȝ请两个证书。用Java~写加密和验证程序,上述例子只是一个非常简单的证书应用Q实际协议对证书的?比如SSL)要比q个复杂多了?



? 加密{֐、解密验证文件结构图



加密函数中的desKeyData存放DES加密密钥Q如果要在程序中指定Q可以设|ؓQ?

static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };


加密函数写成Q?

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(); }}


其中ct是加密后的内容,outFileName保存加密后文件的文g名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)是解密文g了?

文g加密后就要对文g{֐Q保证A发送到B的文件不可伪造。下面是用存攑֜.keystore中的U钥q行{֐的函敎ͼ{֐使用的摘要算法是MD5。其中sigText是被{֐内容的输入数l,outFileName是保存签名后输出文g的名UͼKeyPassword是读取Keystore使用的密码,KeyStorePath是存?keystore文g的\径,函数代码如下Q?

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 is done");  try{   FileOutputStream out=new FileOutputStream(outFileName);   out.write(sig);   out.close();  }catch(IOException e){   e.printStackTrace();  }     }catch(Exception e){  e.printStackTrace(); }}


验证{֐需要存攄名文件和被签名的文g以及证书Q其中,updateData存放被签名文件的内容QsigedText存放得到的签名内容,CertName是证书名。验证签名代码如下:

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();	           		 }}


可以用keytool产生两个自签的签名证书,或者到某个CAȝ请两个证书。用Java~写加密和验证程序,上述例子只是一个非常简单的证书应用Q实际协议对证书的?比如SSL)要比q个复杂多了?


archangel 2007-09-05 15:18 发表评论
]]>不同格式证书导入keystoreҎ(gu) http://www.aygfsteel.com/Archangelsy/articles/142894.htmlarchangelarchangelWed, 05 Sep 2007 06:42:00 GMThttp://www.aygfsteel.com/Archangelsy/articles/142894.htmlhttp://www.aygfsteel.com/Archangelsy/comments/142894.htmlhttp://www.aygfsteel.com/Archangelsy/articles/142894.html#Feedback0http://www.aygfsteel.com/Archangelsy/comments/commentRss/142894.htmlhttp://www.aygfsteel.com/Archangelsy/services/trackbacks/142894.html阅读全文

archangel 2007-09-05 14:42 发表评论
]]>
bouncycastle jcehttp://www.aygfsteel.com/Archangelsy/articles/142841.htmlarchangelarchangelWed, 05 Sep 2007 03:01:00 GMThttp://www.aygfsteel.com/Archangelsy/articles/142841.htmlhttp://www.aygfsteel.com/Archangelsy/comments/142841.htmlhttp://www.aygfsteel.com/Archangelsy/articles/142841.html#Feedback0http://www.aygfsteel.com/Archangelsy/comments/commentRss/142841.htmlhttp://www.aygfsteel.com/Archangelsy/services/trackbacks/142841.html阅读全文

archangel 2007-09-05 11:01 发表评论
]]>
使用eclipse生成文档http://www.aygfsteel.com/Archangelsy/articles/141523.htmlarchangelarchangelThu, 30 Aug 2007 13:40:00 GMThttp://www.aygfsteel.com/Archangelsy/articles/141523.htmlhttp://www.aygfsteel.com/Archangelsy/comments/141523.htmlhttp://www.aygfsteel.com/Archangelsy/articles/141523.html#Feedback0http://www.aygfsteel.com/Archangelsy/comments/commentRss/141523.htmlhttp://www.aygfsteel.com/Archangelsy/services/trackbacks/141523.html1Q在目列表中按右键Q选择ExportQ导出)Q然后在Export(导出)对话框中选择java下的javadocQ提交到下一步?br />在Javadoc Generation对话框中有两个地方要注意的:
javadoc command:应该选择jdk的bin/javadoc.exe
destination:为生成文档的保存路径Q可自由选择?br />按finish(完成)提交卛_开始生成文档?br />2Q用菜单选择QFile->Export(文gQ?gt;导出)Q?br />剩下的步骤和W一U方法是一L?br />3Q选中要生成文档的目Q然后用菜单选择Q?br />Project->Generate Javadoc直接q入Javadoc Generation对话框,剩余的步骤就和第一U方法在Javadoc Generation对话框开始是一L?img src ="http://www.aygfsteel.com/Archangelsy/aggbug/141523.html" width = "1" height = "1" />

archangel 2007-08-30 21:40 发表评论
]]>
վ֩ģ壺 Ѯ| | | | | ͨɽ| | ĩ| | | | | ̰| ɣ| ¤| | ɽ| Ϸ| | ɾ| | | | ľ| | ޵| | | | | | | | | Ͳ| ʼ| | ԰| | ˹| |