﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Archangelsy-文章分类-JAVA</title><link>http://www.blogjava.net/Archangelsy/category/20557.html</link><description>LSY</description><language>zh-cn</language><lastBuildDate>Wed, 12 Sep 2007 05:10:36 GMT</lastBuildDate><pubDate>Wed, 12 Sep 2007 05:10:36 GMT</pubDate><ttl>60</ttl><item><title>如何用Java读取使用证书</title><link>http://www.blogjava.net/Archangelsy/articles/142911.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Wed, 05 Sep 2007 07:18:00 GMT</pubDate><guid>http://www.blogjava.net/Archangelsy/articles/142911.html</guid><wfw:comment>http://www.blogjava.net/Archangelsy/comments/142911.html</wfw:comment><comments>http://www.blogjava.net/Archangelsy/articles/142911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Archangelsy/comments/commentRss/142911.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Archangelsy/services/trackbacks/142911.html</trackback:ping><description><![CDATA[
		<span class="myp11">
				<font id="zoom">
						<br />证书(Certificate，也称public-key certificate)是用某种签名算法对某些内容(比如公钥)进行数字签名后得到的、可以用来当成信任关系中介的数字凭证。证书发行机构通过发行证书告知证书使用者或实体其公钥(public-key)以及其它一些辅助信息。证书在电子商务安全交易中有着广泛的应用，证书发行机构也称CA(Certificate Authority)。 <br /><br /><center><font color="#000099"><strong>应用证书</strong></font></center><br /><br />证书在公钥加密应用中的作用是保证公钥在某些可信的机构发布，其在协议SSL、电子交易协议SET等方面有重要的应用。图1显示了一个最简单的证书应用方法： <br /><br /><center></center><br /><br /><center>图1 证书应用方法</center><br /><br />证书的应用步骤是： <br /><br />（1） A把自己的公钥PKA送到CA(Certificate Authority)； <br /><br />（2） CA用自己的私钥和A的公钥生成A的证书，证书内包括CA的数字签名。签名对象包括需要在证书中说明的内容，比如A的公钥、时间戳、序列号等，为了简化这里不妨假设证书中只有三项内容：A的公钥PKA、时间戳TIME1、序列号IDA。那么CA发送给A的简单证书凭证可表达为：CertA=Eca[TIME1,IDA,PKA]； <br /><br />（3） B同样把自己的公钥PKB送到CA； <br /><br />（4） B得到CA发布的证书CertB; <br /><br />（5） A告知B证书CertA； <br /><br />（6） B告知A证书CertB。 <br /><br />A、B各自得到对方证书后，利用从CA得到的公钥(在CA的自签证书中)验证彼此对方的证书是否有效，如果有效，那么就得到了彼此的公钥。利用对方的公钥，可以加密数据，也可以用来验证对方的数字签名。 <br /><br />本文为了方便说明，并没有使用从CA获得的证书，而是通信双方各自产生自签证书，也就是说图1的A和B并没有经过CA，不过前提是A和B之间是互相拥有对方的证书。 <br /><br />证书的内容和意义如表1所示（这里以通用X .509证书格式为例）。 <br /><br /><center>表1 证书内容和意义</center><br /><br /><center><ccid_nobr></ccid_nobr><table class="content" width="502" border="1"><tbody><tr><td>证书内容</td><td>意义</td></tr><tr><td>Version</td><td>告诉这个X.509证书是哪个版本的，目前有v1、V2、v3</td></tr><tr><td>Serial Number</td><td>由证书分发机构设置证书的序列号</td></tr><tr><td>Signature Algorithm Identifier</td><td>证书采用什么样的签名算法</td></tr><tr><td>Issuer Name</td><td>证书发行者名，也就是给这个证书签名的机构名</td></tr><tr><td>Validity Period</td><td>证书有效时间范围</td></tr><tr><td>Subject Name</td><td>被证书发行机构签名后的公钥拥有者或实体的名字，采用X.500协议，在Internet上的标志是惟一的。例如：CN=Java,OU=Infosec,O=Infosec Lab,C=CN表示一个subject name。</td></tr></tbody></table></center><br /><br />对证书的详细定义及其应用相关的各种协议，这里不加详细说明，详细细节请查看RFC2450、RFC2510、RFC2511、RFC2527、RFC2528、RFC2559、RFC2560、RFC2585、RFC2587等文档。 <br /><br /><center><font color="#000099"><strong>生成自签证书</strong></font></center><p><br /><br />个人或机构可以从信任的证书分发机构申请得到证书，比如说，可以从http://ca.pku.edu.cn 得到一个属于个人的证书。这里可以利用J2SDK的安全工具keytool手工产生自签证书，所谓自签证书是指证书中的“Subject Name”和“Issuer Name”相同的证书。 </p></font>
		</span>
		<p>
				<span class="myp11">
						<font id="zoom">下面产生一个自签证书。安装完J2SDK（这里用的是J2SDK1.4）后，在J2SDK安装目录的bin目录下，有一个keytool的可执行程序。利用keytool产生自签证书的步骤如下： <br /><br />第一步，用-genkey命令选项，产生公私密钥对。在控制台界面输入：keytool -genkey -alias testkeypair -keyalg RSA -keysize 1024 -sigalg MD5withRSA。这里的-alias表示使用这对公私密钥产生新的keystore入口的别名(keystore是用来存放管理密钥对和证书链的，缺省位置是在使用者主目录下，以.keystore为名的隐藏文件，当然也可指定某个路径存放.keystore文件)；-keyalg是产生公私钥对所用的算法，这里是RSA；-keysize定义密钥的长度；-sigalg是签名算法，选择MD5withRSA，即用RSA签名，然后用MD5哈希算法摘要。接下来，系统会提示进行一些输入： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>输入keystore密码：  abc123您的名字与姓氏是什么？  [Unknown]：  Li您的组织单位名称是什么？  [Unknown]：  InfosecLab您的组织名称是什么？  [Unknown]：  InfosecLab Group您所在的城市或区域名称是什么？  [Unknown]：  Beijing您所在的州或省份名称是什么？  [Unknown]：  Beijing该单位的两字母国家代码是什么  [Unknown]：  CNCN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN 正确吗？[否]：  y输入&lt;testkeypair&gt;的主密码 (如果和 keystore 密码相同，按回车）：</pre></td></tr></tbody></table><br /><br />第二步，产生自签证书，输入以下命令： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>keytool -selfcert -alias testkeypair -dname "CN=Li, OU=InfosecLab, O=InfosecLab Group, L=Beijing, ST=Beijing, C=CN" 输入keystore密码：  abc123</pre></td></tr></tbody></table><br /><br />第三步，导出自签证书，由上面两步产生的证书，已经存放在以“testkeypair”为别名的keystore入口了，如果使用其文件，必须导出证书。输入: <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>keytool -export -rfc -alias testkeypair -file mycert.crt  输入keystore密码：  abc123保存在文件中的认证 &lt;mycert.crt&gt;</pre></td></tr></tbody></table><br /><br />这样，就得到了一个自签的证书mycert.crt。注意，选项rfc是把证书输出为RFC1421定义的、用Base64最终编码的格式。 <br /><br /><center><font color="#000099"><strong>读取证书</strong></font></center><p><br /><br />Java为安全应用提供了丰富的API，J2SDK1.4 的JSSE (JavaTM Secure Socket Extension) 包括javax.security.certificate包，并且提供对证书的操作方法。而对证书的读操作，只用java.security.cert. CertificateFactory和java.security.cert.X509Certificate就可以了。下面是读取证书内容的部分代码： <br /><br /></p><ccid_nobr></ccid_nobr><p></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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);  /* 读取证书常规信息 */  Read_Normal(panelNormal);  /* 读取证书文件字符串表示内容 */  Read_Bin(panelAll);  /* 读取证原始Base64编码形式的证书文件 */  Read_Raw(panelBase64);  tabbedPane.setSelectedIndex(0);  setLayout(new GridLayout(1, 1));   add(tabbedPane); }  /*以下是定义的Read_Normal()，Read_Bin(),Read_Raw()以及main()   这里省略...   */  }</pre></td></tr></tbody></table></font>
				</span>
		</p>
		<p>
				<br />
				<br />定义证书信息的读取函数如下： <br /><br /></p>
		<ccid_nobr>
		</ccid_nobr>
		<p>
		</p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
				<tbody>
						<tr>
								<td class="code" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_code>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]="类型";  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;  /* 以下类似，这里省略   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;}</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<br />
				<br />如果以字符串形式读取证书，加入下面Read_Bin这个函数。其中CertificateFactory.generateCertificate() 这个函数可以从证书标准编码(RFC1421定义)中解出可读信息。Read_Bin函数代码如下： <br /><br /></p>
		<ccid_nobr>
		</ccid_nobr>
		<p>
		</p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
				<tbody>
						<tr>
								<td class="code" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_code>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()&gt;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;	}</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<br />
				<br />如果要得到原始证书编码后的信息，则可用如下代码： <br /><br /></p>
		<ccid_nobr>
		</ccid_nobr>
		<p>
		</p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
				<tbody>
						<tr>
								<td class="code" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_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&lt;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;	}</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<br />
				<br />最后用这个小程序看一看刚才生成的证书mycert.crt内容，把文件名写入main()中： <br /><br /></p>
		<ccid_nobr>
		</ccid_nobr>
		<p>
		</p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
				<tbody>
						<tr>
								<td class="code" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_code>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);}</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<br />
				<br />证书mycert.crt的内容显示如图2所示，所有信息和Base64的显示内容，这里不再列举。 <br /></p>
		<p>
				<span class="myp11">
						<font id="zoom">现在已经读取了证书的一些内容，那么怎样使用证书呢？我们可以假设A和B要共享一个绝密的文件F，B信任并拥有A的证书，也就是说B拥有A的公钥。那么A通过A和B共知的加密算法(对称密钥算法，比如DES算法)先加密文件F，然后对加密后的F进行签名和散列摘要(比如MD5算法，目的是保证文件的完整性)，然后把F发送到B。B收到文件后，先用A的证书中的公钥验证签名，然后再用通过共知的加密算法解密，就可以得到原文件了。这里使用的数字签名，可以保证B得到的文件，就是A的，A不能否认其不拥有文件F，因为只有A拥有可以让A的公钥验证其签名的私钥，同时这里使用DES算法加密，使得文件有保密性。 <br /><br />使用DES算法的加密解密函数类似，这里不对加密算法做进一步讨论，详细请看J2SDK的JSE部分内容，加密签名、解密验证文件结构见图3。 <br /><br /><center><img alt="" src="http://industry.ccidnet.com/pub/attachment/2003/1/66507.gif" /></center><p><br /><br /></p><center>图3 加密签名、解密验证文件结构图</center><p><br /><br />加密函数中的desKeyData存放DES加密密钥，如果要在程序中指定，可以设置为： <br /><br /><ccid_nobr></ccid_nobr></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };</pre></td></tr></tbody></table><br /><br />加密函数写成： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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(); }}</pre></td></tr></tbody></table><br /><br />其中ct就是加密后的内容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。 <br /><br />文件加密后就要对文件签名，保证A发送到B的文件不可伪造。下面是用存放在.keystore中的私钥进行签名的函数，签名使用的摘要算法是MD5。其中sigText是被签名内容的输入数组，outFileName是保存签名后输出文件的名称，KeyPassword是读取Keystore使用的密码，KeyStorePath是存放.keystore文件的路径，函数代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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&lt;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(); }}</pre></td></tr></tbody></table><br /><br />验证签名需要存放签名文件和被签名的文件以及证书，其中，updateData存放被签名文件的内容，sigedText存放得到的签名内容，CertName是证书名。验证签名代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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();	           		 }}</pre></td></tr></tbody></table><br /><br />可以用keytool产生两个自签的签名证书，或者到某个CA去申请两个证书。用Java编写加密和验证程序，上述例子只是一个非常简单的证书应用，实际协议对证书的使用(比如SSL)要比这个复杂多了。 <br /></font>
				</span>
		</p>
		<p>
		</p>
		<center>
				<img alt="" src="http://industry.ccidnet.com/pub/attachment/2003/1/66507.gif" />
		</center>
		<p>
				<br />
				<br />
		</p>
		<center>图3 加密签名、解密验证文件结构图</center>
		<p>
				<br />
				<br />加密函数中的desKeyData存放DES加密密钥，如果要在程序中指定，可以设置为： <br /><br /><ccid_nobr></ccid_nobr></p>
		<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1">
				<tbody>
						<tr>
								<td class="code" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_code>static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />加密函数写成： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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(); }}</pre></td></tr></tbody></table><br /><br />其中ct就是加密后的内容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。 <br /><br />文件加密后就要对文件签名，保证A发送到B的文件不可伪造。下面是用存放在.keystore中的私钥进行签名的函数，签名使用的摘要算法是MD5。其中sigText是被签名内容的输入数组，outFileName是保存签名后输出文件的名称，KeyPassword是读取Keystore使用的密码，KeyStorePath是存放.keystore文件的路径，函数代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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&lt;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(); }}</pre></td></tr></tbody></table><br /><br />验证签名需要存放签名文件和被签名的文件以及证书，其中，updateData存放被签名文件的内容，sigedText存放得到的签名内容，CertName是证书名。验证签名代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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();	           		 }}</pre></td></tr></tbody></table><br /><br />可以用keytool产生两个自签的签名证书，或者到某个CA去申请两个证书。用Java编写加密和验证程序，上述例子只是一个非常简单的证书应用，实际协议对证书的使用(比如SSL)要比这个复杂多了。 <br /><p></p><center><font color="#000099"><strong>读取证书</strong></font></center><p><br /><br />Java为安全应用提供了丰富的API，J2SDK1.4 的JSSE (JavaTM Secure Socket Extension) 包括javax.security.certificate包，并且提供对证书的操作方法。而对证书的读操作，只用java.security.cert. CertificateFactory和java.security.cert.X509Certificate就可以了。下面是读取证书内容的部分代码： <br /><br /></p><ccid_nobr></ccid_nobr><p></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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);  /* 读取证书常规信息 */  Read_Normal(panelNormal);  /* 读取证书文件字符串表示内容 */  Read_Bin(panelAll);  /* 读取证原始Base64编码形式的证书文件 */  Read_Raw(panelBase64);  tabbedPane.setSelectedIndex(0);  setLayout(new GridLayout(1, 1));   add(tabbedPane); }  /*以下是定义的Read_Normal()，Read_Bin(),Read_Raw()以及main()   这里省略...   */  }</pre></td></tr></tbody></table><p><br /><br />定义证书信息的读取函数如下： <br /><br /></p><ccid_nobr></ccid_nobr><p></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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]="类型";  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;  /* 以下类似，这里省略   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;}</pre></td></tr></tbody></table><p><br /><br />如果以字符串形式读取证书，加入下面Read_Bin这个函数。其中CertificateFactory.generateCertificate() 这个函数可以从证书标准编码(RFC1421定义)中解出可读信息。Read_Bin函数代码如下： <br /><br /></p><ccid_nobr></ccid_nobr><p></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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()&gt;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;	}</pre></td></tr></tbody></table><p><br /><br />如果要得到原始证书编码后的信息，则可用如下代码： <br /><br /></p><ccid_nobr></ccid_nobr><p></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_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&lt;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;	}</pre></td></tr></tbody></table><p><br /><br />最后用这个小程序看一看刚才生成的证书mycert.crt内容，把文件名写入main()中： <br /><br /></p><ccid_nobr></ccid_nobr><p></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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);}</pre></td></tr></tbody></table><p><br /><br />证书mycert.crt的内容显示如图2所示，所有信息和Base64的显示内容，这里不再列举。 <br /></p><p><span class="myp11"><font id="zoom">现在已经读取了证书的一些内容，那么怎样使用证书呢？我们可以假设A和B要共享一个绝密的文件F，B信任并拥有A的证书，也就是说B拥有A的公钥。那么A通过A和B共知的加密算法(对称密钥算法，比如DES算法)先加密文件F，然后对加密后的F进行签名和散列摘要(比如MD5算法，目的是保证文件的完整性)，然后把F发送到B。B收到文件后，先用A的证书中的公钥验证签名，然后再用通过共知的加密算法解密，就可以得到原文件了。这里使用的数字签名，可以保证B得到的文件，就是A的，A不能否认其不拥有文件F，因为只有A拥有可以让A的公钥验证其签名的私钥，同时这里使用DES算法加密，使得文件有保密性。 <br /><br />使用DES算法的加密解密函数类似，这里不对加密算法做进一步讨论，详细请看J2SDK的JSE部分内容，加密签名、解密验证文件结构见图3。 <br /><br /><center><img alt="" src="http://industry.ccidnet.com/pub/attachment/2003/1/66507.gif" /></center><p><br /><br /></p><center>图3 加密签名、解密验证文件结构图</center><p><br /><br />加密函数中的desKeyData存放DES加密密钥，如果要在程序中指定，可以设置为： <br /><br /><ccid_nobr></ccid_nobr></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };</pre></td></tr></tbody></table><br /><br />加密函数写成： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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(); }}</pre></td></tr></tbody></table><br /><br />其中ct就是加密后的内容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。 <br /><br />文件加密后就要对文件签名，保证A发送到B的文件不可伪造。下面是用存放在.keystore中的私钥进行签名的函数，签名使用的摘要算法是MD5。其中sigText是被签名内容的输入数组，outFileName是保存签名后输出文件的名称，KeyPassword是读取Keystore使用的密码，KeyStorePath是存放.keystore文件的路径，函数代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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&lt;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(); }}</pre></td></tr></tbody></table><br /><br />验证签名需要存放签名文件和被签名的文件以及证书，其中，updateData存放被签名文件的内容，sigedText存放得到的签名内容，CertName是证书名。验证签名代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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();	           		 }}</pre></td></tr></tbody></table><br /><br />可以用keytool产生两个自签的签名证书，或者到某个CA去申请两个证书。用Java编写加密和验证程序，上述例子只是一个非常简单的证书应用，实际协议对证书的使用(比如SSL)要比这个复杂多了。 <br /></font></span></p><p></p><center><img alt="" src="http://industry.ccidnet.com/pub/attachment/2003/1/66507.gif" /></center><p><br /><br /></p><center>图3 加密签名、解密验证文件结构图</center><p><br /><br />加密函数中的desKeyData存放DES加密密钥，如果要在程序中指定，可以设置为： <br /><br /><ccid_nobr></ccid_nobr></p><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>static byte[] desKeyData = { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, (byte)0x08 };</pre></td></tr></tbody></table><br /><br />加密函数写成： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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(); }}</pre></td></tr></tbody></table><br /><br />其中ct就是加密后的内容,outFileName保存加密后文件的文件名。把cdes.init(Cipher.ENCRYPT_MODE, secretKey)换成cdes.init(Cipher.DECRYPT_MODE, secretKey)就是解密文件了。 <br /><br />文件加密后就要对文件签名，保证A发送到B的文件不可伪造。下面是用存放在.keystore中的私钥进行签名的函数，签名使用的摘要算法是MD5。其中sigText是被签名内容的输入数组，outFileName是保存签名后输出文件的名称，KeyPassword是读取Keystore使用的密码，KeyStorePath是存放.keystore文件的路径，函数代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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&lt;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(); }}</pre></td></tr></tbody></table><br /><br />验证签名需要存放签名文件和被签名的文件以及证书，其中，updateData存放被签名文件的内容，sigedText存放得到的签名内容，CertName是证书名。验证签名代码如下： <br /><br /><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="550" align="center" bordercolorlight="#000000" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>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();	           		 }}</pre></td></tr></tbody></table><br /><br />可以用keytool产生两个自签的签名证书，或者到某个CA去申请两个证书。用Java编写加密和验证程序，上述例子只是一个非常简单的证书应用，实际协议对证书的使用(比如SSL)要比这个复杂多了。 <br /><img src ="http://www.blogjava.net/Archangelsy/aggbug/142911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Archangelsy/" target="_blank">archangel</a> 2007-09-05 15:18 <a href="http://www.blogjava.net/Archangelsy/articles/142911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不同格式证书导入keystore方法 </title><link>http://www.blogjava.net/Archangelsy/articles/142894.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Wed, 05 Sep 2007 06:42:00 GMT</pubDate><guid>http://www.blogjava.net/Archangelsy/articles/142894.html</guid><wfw:comment>http://www.blogjava.net/Archangelsy/comments/142894.html</wfw:comment><comments>http://www.blogjava.net/Archangelsy/articles/142894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Archangelsy/comments/commentRss/142894.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Archangelsy/services/trackbacks/142894.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 简介																																																												Java																																				自带的																																																	...&nbsp;&nbsp;<a href='http://www.blogjava.net/Archangelsy/articles/142894.html'>阅读全文</a><img src ="http://www.blogjava.net/Archangelsy/aggbug/142894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Archangelsy/" target="_blank">archangel</a> 2007-09-05 14:42 <a href="http://www.blogjava.net/Archangelsy/articles/142894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>bouncycastle jce</title><link>http://www.blogjava.net/Archangelsy/articles/142841.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Wed, 05 Sep 2007 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/Archangelsy/articles/142841.html</guid><wfw:comment>http://www.blogjava.net/Archangelsy/comments/142841.html</wfw:comment><comments>http://www.blogjava.net/Archangelsy/articles/142841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Archangelsy/comments/commentRss/142841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Archangelsy/services/trackbacks/142841.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JAVA安全体系结构分析																																																																						 														下图显示了				JAVA				安全体系结构的标准组件。在图的下半部分，是				JAVA2				安全体系结构的核心和...&nbsp;&nbsp;<a href='http://www.blogjava.net/Archangelsy/articles/142841.html'>阅读全文</a><img src ="http://www.blogjava.net/Archangelsy/aggbug/142841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Archangelsy/" target="_blank">archangel</a> 2007-09-05 11:01 <a href="http://www.blogjava.net/Archangelsy/articles/142841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用eclipse生成文档</title><link>http://www.blogjava.net/Archangelsy/articles/141523.html</link><dc:creator>archangel</dc:creator><author>archangel</author><pubDate>Thu, 30 Aug 2007 13:40:00 GMT</pubDate><guid>http://www.blogjava.net/Archangelsy/articles/141523.html</guid><wfw:comment>http://www.blogjava.net/Archangelsy/comments/141523.html</wfw:comment><comments>http://www.blogjava.net/Archangelsy/articles/141523.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Archangelsy/comments/commentRss/141523.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Archangelsy/services/trackbacks/141523.html</trackback:ping><description><![CDATA[使用eclipse生成文档（javadoc）主要有三种方法：<br />1，在项目列表中按右键，选择Export（导出），然后在Export(导出)对话框中选择java下的javadoc，提交到下一步。<br />在Javadoc Generation对话框中有两个地方要注意的：<br />javadoc command:应该选择jdk的bin/javadoc.exe<br />destination:为生成文档的保存路径，可自由选择。<br />按finish(完成)提交即可开始生成文档。<br />2，用菜单选择：File-&gt;Export(文件－&gt;导出)，<br />剩下的步骤和第一种方法是一样的。<br />3，选中要生成文档的项目，然后用菜单选择，<br />Project-&gt;Generate Javadoc直接进入Javadoc Generation对话框，剩余的步骤就和第一种方法在Javadoc Generation对话框开始是一样的。<img src ="http://www.blogjava.net/Archangelsy/aggbug/141523.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Archangelsy/" target="_blank">archangel</a> 2007-08-30 21:40 <a href="http://www.blogjava.net/Archangelsy/articles/141523.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>