﻿<?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-夜来风雨声的盒子-文章分类-Java</title><link>http://www.blogjava.net/Nightlee/category/4007.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 07:45:23 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 07:45:23 GMT</pubDate><ttl>60</ttl><item><title>代码中生成数字证书</title><link>http://www.blogjava.net/Nightlee/articles/16170.html</link><dc:creator>夜来风雨声</dc:creator><author>夜来风雨声</author><pubDate>Thu, 20 Oct 2005 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/Nightlee/articles/16170.html</guid><wfw:comment>http://www.blogjava.net/Nightlee/comments/16170.html</wfw:comment><comments>http://www.blogjava.net/Nightlee/articles/16170.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Nightlee/comments/commentRss/16170.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Nightlee/services/trackbacks/16170.html</trackback:ping><description><![CDATA[/**<BR>*代码实例 通过反编译查看keytool的java code获得的数字证书的内部生成方法 <BR>*推荐使用jdk1.5<BR>**/<BR>1。首先生成selfcert<BR>CertAndKeyGen cak = new CertAndKeyGen("RSA","MD5WithRSA",null);<BR>//参数分别为 公钥算法 签名算法 providername（因为不知道确切的 只好使用null 既使用默认的provider）<BR>cak.generate(1024);<BR>//生成一对key 参数为key的长度 对于rsa不能小于512<BR>X500Name subject = new X500Name("CN=simic,o=shanghai");<BR>//subject name<BR>X509Certificate certificate = cak.getSelfCertificate(subject,10);<BR>// 后一个long型参数代表从现在开始的有效期 单位为秒（如果不想从现在开始算 可以在后面改这个域）<BR><BR>BASE64Encoder base64 = new BASE64Encoder();<BR>FileOutputStream fos = new FileOutputStream(new File("d:\\test.crt"));<BR>base64.encodeBuffer(certificate.getEncoded(), fos);<BR>//生成cert文件 base64加密 当然也可以不加密<BR><BR>2。生成非自签的cert<BR>首先按照1走一遍生成一个自签证书<BR>byte certbytes[] = certificate.getEncoded();<BR>X509CertImpl x509certimpl = new X509CertImpl(certbytes);<BR>X509CertInfo x509certinfo = (X509CertInfo)x509certimpl.get("x509.info");<BR>X500Name issuer = new X500Name("CN=fatal,o=shanghai");<BR>x509certinfo.set("issuer.dname",issuer);<BR>//设置issuer域<BR>Date bdate = new Date();<BR>Date edate = new Date();<BR>edate.setTime(bdate.getTime() + validity * 1000L * 24L * 60L * 60L);<BR>//validity为有效时间长度 单位为秒<BR>CertificateValidity certificatevalidity = new CertificateValidity(bdate, edate);<BR>x509certinfo.set("validity", certificatevalidity);<BR>//设置有效期域（包含开始时间和到期时间）域名等同与x509certinfo.VALIDITY <BR>x509certinfo.set("serialNumber", new CertificateSerialNumber((int)(date.getTime() / 1000L)));<BR>//设置序列号域<BR>CertificateVersion cv = new CertificateVersion(CertificateVersion.V3);<BR>x509certinfo.set(X509CertInfo.VERSION,cv);<BR>//设置版本号 只有v1 ,v2,v3这几个合法值 <BR>/**<BR>*以上是证书的基本信息 如果要添加用户扩展信息 则比较麻烦 首先要确定version必须是v3否则不行 然后按照以下步骤<BR>**/ <BR>ObjectIdentifier oid = new ObjectIdentifier(new int[]{1,22});<BR>//生成扩展域的id 是个int数组 第1位最大2 第2位最大39 最多可以几位不明....<BR>byte l = 0x11;//数据总长17位<BR>byte f = 0x04;<BR>String userData = "hohohohohahahahah";<BR>byte[] bs = new byte[userData.length()+2];<BR>bs[0] = f;<BR>bs[1] = l;<BR>for(int i=2;i&lt;bs.length;i++)<BR>{<BR>&nbsp;&nbsp;bs[i] = (byte)userData.charAt(i-2);<BR>}<BR>Extension ext = new Extension(oid,true,bs);<BR>// 生成一个extension对象 参数分别为 oid，是否关键扩展，byte[]型的内容值<BR>//其中内容的格式比较怪异 第一位是flag 这里取4暂时没出错 估计用来说明数据的用处的 第2位是后面的实际数据的长度，然后就是数据 <BR><BR>CertificateExtensions exts = new CertificateExtensions();<BR>exts.set("aa",ext); <BR>//如果有多个extension则都放入CertificateExtensions 类中，<BR>x509certinfo.set(X509CertInfo.EXTENSIONS,exts);<BR>//设置extensions域<BR><BR>X509CertImpl x509certimpl1 = new X509CertImpl(x509certinfo);<BR>x509certimpl1.sign(cak1.getPrivateKey(), "MD5WithRSA");<BR>//使用另一个证书的私钥来签名此证书 这里使用 md5散列 用rsa来加密<BR><BR>BASE64Encoder base64 = new BASE64Encoder();<BR>FileOutputStream fos = new FileOutputStream(new File("d:\\test.crt"));<BR>base64.encodeBuffer(x509certimpl1.getEncoded(), fos);<BR>//生成文件<BR>x509certimpl1.verify(cak.getPublicKey(),null);<BR>//使用某个证书的公钥验证证书 如果验证不通过 则会抛错<BR><BR>很多地方没仔细测过 可能有不正确之处还请多包涵 <BR><BR><img src ="http://www.blogjava.net/Nightlee/aggbug/16170.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Nightlee/" target="_blank">夜来风雨声</a> 2005-10-20 17:03 <a href="http://www.blogjava.net/Nightlee/articles/16170.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> JAVA对数字证书的常用操作</title><link>http://www.blogjava.net/Nightlee/articles/16139.html</link><dc:creator>夜来风雨声</dc:creator><author>夜来风雨声</author><pubDate>Thu, 20 Oct 2005 07:04:00 GMT</pubDate><guid>http://www.blogjava.net/Nightlee/articles/16139.html</guid><wfw:comment>http://www.blogjava.net/Nightlee/comments/16139.html</wfw:comment><comments>http://www.blogjava.net/Nightlee/articles/16139.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Nightlee/comments/commentRss/16139.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Nightlee/services/trackbacks/16139.html</trackback:ping><description><![CDATA[<P>一：需要包含的包<BR>&nbsp;&nbsp;&nbsp; import java.security.*;<BR>&nbsp;&nbsp;&nbsp; import java.io.*;<BR>&nbsp;&nbsp;&nbsp; import java.util.*;<BR>&nbsp;&nbsp;&nbsp; import java.security.*;<BR>&nbsp;&nbsp;&nbsp; import java.security.cert.*;<BR>&nbsp;&nbsp;&nbsp; import sun.security.x509.*<BR>&nbsp;&nbsp;&nbsp; import java.security.cert.Certificate;<BR>&nbsp;&nbsp;&nbsp; import java.security.cert.CertificateFactory;</P>
<P>二：从文件中读取证书<BR>&nbsp;&nbsp;&nbsp; 用keytool将.keystore中的证书写入文件中，然后从该文件中读取证书信息<BR>&nbsp;&nbsp;&nbsp; CertificateFactory cf=CertificateFactory.getInstance("X.509");<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream("out.csr");<BR>&nbsp;&nbsp;&nbsp; Certificate c=cf.generateCertificate(in);</P>
<P>&nbsp;&nbsp;&nbsp; String s=c.toString();<BR>三：从密钥库中直接读取证书<BR>&nbsp;&nbsp;&nbsp; String pass="123456";<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<BR>&nbsp;&nbsp;&nbsp; ks.load(in,pass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c=ks.getCertificate(alias);//alias为条目的别名</P>
<P>四：JAVA程序中显示证书指定信息<BR>&nbsp;&nbsp;&nbsp; System.out.println("输出证书信息:"+c.toString());<BR>&nbsp;&nbsp;&nbsp; System.out.println("版本号:"+t.getVersion());<BR>&nbsp;&nbsp;&nbsp; System.out.println("序列号:"+t.getSerialNumber().toString(16));<BR>&nbsp;&nbsp;&nbsp; System.out.println("主体名："+t.getSubjectDN());<BR>&nbsp;&nbsp;&nbsp; System.out.println("签发者："+t.getIssuerDN());<BR>&nbsp;&nbsp;&nbsp; System.out.println("有效期："+t.getNotBefore());<BR>&nbsp;&nbsp;&nbsp; System.out.println("签名算法："+t.getSigAlgName());<BR>&nbsp;&nbsp;&nbsp; byte [] sig=t.getSignature();//签名值 <BR>&nbsp;&nbsp;&nbsp; PublicKey pk=t.getPublicKey();<BR>&nbsp;&nbsp;&nbsp; byte [] pkenc=pk.getEncoded();&nbsp; <BR>&nbsp;&nbsp;&nbsp; System.out.println("公钥");<BR>&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;pkenc.length;i++)System.out.print(pkenc[i]+",");</P>
<P>五：JAVA程序列出密钥库所有条目<BR>&nbsp;&nbsp;&nbsp; String pass="123456";<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<BR>&nbsp;&nbsp;&nbsp; ks.load(in,pass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; Enumeration e=ks.aliases();<BR>&nbsp;&nbsp;&nbsp; while(e.hasMoreElements())<BR>&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());</P>
<P>六：JAVA程序修改密钥库口令<BR>&nbsp;&nbsp;&nbsp; String oldpass="123456";<BR>&nbsp;&nbsp;&nbsp; String newpass="654321";<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<BR>&nbsp;&nbsp;&nbsp; ks.load(in,oldpass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; in.close();<BR>&nbsp;&nbsp;&nbsp; FileOutputStream output=new FileOutputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; ks.store(output,newpass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; output.close();</P>
<P>七：JAVA程序修改密钥库条目的口令及添加条目<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<BR>&nbsp;&nbsp;&nbsp; ks.load(in,storepass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; Certificate [] cchain=ks.getCertificate(alias);获取别名对应条目的证书链<BR>&nbsp;&nbsp;&nbsp; PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());获取别名对应条目的私钥<BR>&nbsp;&nbsp;&nbsp; ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密钥库中添加条目<BR>&nbsp;&nbsp;&nbsp; 第一个参数指定所添加条目的别名，假如使用已存在别名将覆盖已存在条目，使用新别名将增加一个新条目，第二个参数为条目的私钥，第三个为设置的新口令，第四个为该私钥的公钥的证书链<BR>&nbsp;&nbsp;&nbsp; FileOutputStream output=new FileOutputStream("another");<BR>&nbsp;&nbsp;&nbsp; ks.store(output,storepass.toCharArray())将keystore对象内容写入新文件</P>
<P>八：JAVA程序检验别名和删除条目<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<BR>&nbsp;&nbsp;&nbsp; ks.load(in,storepass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; ks.containsAlias("sage");检验条目是否在密钥库中，存在返回true<BR>&nbsp;&nbsp;&nbsp; ks.deleteEntry("sage");删除别名对应的条目<BR>&nbsp;&nbsp;&nbsp; FileOutputStream output=new FileOutputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; ks.store(output,storepass.toCharArray())将keystore对象内容写入文件,条目删除成功</P>
<P>九：JAVA程序签发数字证书<BR>&nbsp;&nbsp;&nbsp; （1）从密钥库中读取CA的证书<BR>&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(".keystore");<BR>&nbsp;&nbsp;&nbsp; KeyStore ks=KeyStore.getInstance("JKS");<BR>&nbsp;&nbsp;&nbsp; ks.load(in,storepass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c1=ks.getCertificate("caroot");<BR>&nbsp;&nbsp;&nbsp; （2）从密钥库中读取CA的私钥<BR>&nbsp;&nbsp;&nbsp; PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());<BR>&nbsp;&nbsp;&nbsp; （3）从CA的证书中提取签发者的信息<BR>&nbsp;&nbsp;&nbsp; byte[] encod1=c1.getEncoded();&nbsp;&nbsp;&nbsp; 提取CA证书的编码<BR>&nbsp;&nbsp;&nbsp; X509CertImpl cimp1=new X509CertImpl(encod1);&nbsp; 用该编码创建X509CertImpl类型对象<BR>&nbsp;&nbsp;&nbsp; X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);&nbsp; 获取X509CertInfo对象<BR>&nbsp;&nbsp;&nbsp; X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 获取X509Name类型的签发者信息<BR>&nbsp;&nbsp;&nbsp; （4）获取待签发的证书<BR>&nbsp;&nbsp;&nbsp; CertificateFactory cf=CertificateFactory.getInstance("X.509");<BR>&nbsp;&nbsp;&nbsp; FileInputStream in2=new FileInputStream("user.csr");<BR>&nbsp;&nbsp;&nbsp; java.security.cert.Certificate c2=cf.generateCertificate(in);<BR>&nbsp;&nbsp;&nbsp; （5）从待签发的证书中提取证书信息<BR>&nbsp;&nbsp;&nbsp; byte [] encod2=c2.getEncoded();<BR>&nbsp;&nbsp;&nbsp; X509CertImpl cimp2=new X509CertImpl(encod2);&nbsp; 用该编码创建X509CertImpl类型对象<BR>&nbsp;&nbsp;&nbsp; X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);&nbsp; 获取X509CertInfo对象<BR>&nbsp;&nbsp;&nbsp; （6）设置新证书有效期<BR>&nbsp;&nbsp;&nbsp; Date begindate=new Date(); 获取当前时间<BR>&nbsp;&nbsp;&nbsp; Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期为3000天<BR>&nbsp;&nbsp;&nbsp; CertificateValidity cv=new CertificateValidity(begindate,enddate); 创建对象<BR>&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.VALIDITY,cv);&nbsp; 设置有效期<BR>&nbsp;&nbsp;&nbsp; （7）设置新证书序列号<BR>&nbsp;&nbsp;&nbsp; int sn=(int)(begindate.getTime()/1000);&nbsp;&nbsp;&nbsp; 以当前时间为序列号<BR>&nbsp;&nbsp;&nbsp; CertificateSerialNumber csn=new CertificateSerialNumber(sn);<BR>&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);<BR>&nbsp;&nbsp;&nbsp; （8）设置新证书签发者<BR>&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);应用第三步的结果<BR>&nbsp;&nbsp;&nbsp; （9）设置新证书签名算法信息<BR>&nbsp;&nbsp;&nbsp; AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);<BR>&nbsp;&nbsp;&nbsp; cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);<BR>&nbsp;&nbsp;&nbsp; （10）创建证书并使用CA的私钥对其签名<BR>&nbsp;&nbsp;&nbsp; X509CertImpl newcert=new X509CertImpl(cinfo2);<BR>&nbsp;&nbsp;&nbsp; newcert.sign(caprk,"MD5WithRSA"); 使用CA私钥对其签名<BR>&nbsp;&nbsp;&nbsp; （11）将新证书写入密钥库<BR>&nbsp;&nbsp;&nbsp; ks.setCertificateEntry("lf_signed",newcert);<BR>&nbsp;&nbsp;&nbsp; FileOutputStream out=new FileOutputStream("newstore");<BR>&nbsp;&nbsp;&nbsp; ks.store(out,"newpass".toCharArray());&nbsp; 这里是写入了新的密钥库，也可以使用第七条来增加条目</P>
<P>十：数字证书的检验<BR>&nbsp;&nbsp;&nbsp; （1）验证证书的有效期<BR>&nbsp;（a）获取X509Certificate类型对象<BR>&nbsp;CertificateFactory cf=CertificateFactory.getInstance("X.509");<BR>&nbsp;&nbsp;&nbsp; FileInputStream in1=new FileInputStream("aa.crt");<BR>&nbsp; java.security.cert.Certificate&nbsp; c1=cf.generateCertificate(in1);<BR>&nbsp;X509Certificate t=(X509Certificate)c1;<BR>&nbsp; in2.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （b）获取日期<BR>&nbsp;Date TimeNow=new Date();<BR>&nbsp;（c）检验有效性<BR>&nbsp;try{<BR>&nbsp;&nbsp;&nbsp; t.checkValidity(TimeNow);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("OK");<BR>&nbsp;}catch(CertificateExpiredException e){&nbsp; //过期<BR>&nbsp;&nbsp;&nbsp; System.out.println("Expired");<BR>&nbsp;&nbsp;&nbsp; System.out.println(e.getMessage());<BR>&nbsp;}catch((CertificateNotYetValidException e){ //尚未生效<BR>&nbsp;&nbsp;&nbsp; System.out.println("Too early");<BR>&nbsp;&nbsp;&nbsp; System.out.println(e.getMessage());}<BR>&nbsp;&nbsp;&nbsp;&nbsp; （2）验证证书签名的有效性<BR>&nbsp;（a）获取CA证书<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CertificateFactory cf=CertificateFactory.getInstance("X.509");<BR>&nbsp;&nbsp;&nbsp;&nbsp; FileInputStream in2=new FileInputStream("caroot.crt");<BR>&nbsp;&nbsp; java.security.cert.Certificate&nbsp; cac=cf.generateCertificate(in2);<BR>&nbsp; in2.close();<BR>&nbsp;（c）获取CA的公钥<BR>&nbsp; PublicKey pbk=cac.getPublicKey();<BR>&nbsp;（b）获取待检验的证书（上步已经获取了，就是C1）<BR>&nbsp;（c）检验证书<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean pass=false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c1.verify(pbk);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass=true;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }catch(Exception e){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass=false;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(e);<BR>&nbsp; }</P>
<P><BR></P><img src ="http://www.blogjava.net/Nightlee/aggbug/16139.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Nightlee/" target="_blank">夜来风雨声</a> 2005-10-20 15:04 <a href="http://www.blogjava.net/Nightlee/articles/16139.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA SECURITY 中的 KEYTOOL</title><link>http://www.blogjava.net/Nightlee/articles/16123.html</link><dc:creator>夜来风雨声</dc:creator><author>夜来风雨声</author><pubDate>Thu, 20 Oct 2005 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/Nightlee/articles/16123.html</guid><wfw:comment>http://www.blogjava.net/Nightlee/comments/16123.html</wfw:comment><comments>http://www.blogjava.net/Nightlee/articles/16123.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Nightlee/comments/commentRss/16123.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Nightlee/services/trackbacks/16123.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JAVA SECURITY 中的 KEYTOOL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs...&nbsp;&nbsp;<a href='http://www.blogjava.net/Nightlee/articles/16123.html'>阅读全文</a><img src ="http://www.blogjava.net/Nightlee/aggbug/16123.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Nightlee/" target="_blank">夜来风雨声</a> 2005-10-20 13:51 <a href="http://www.blogjava.net/Nightlee/articles/16123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>