怎么利用数字证书完成身份验证、客户和服务器端的加密和解密。

musicman 2007-01-24

大家好。我现在在学习数字证书。希望能得到你们的帮助。现在的想法,是利用数字证书来完成用户的身份验证,此用户是不是我们信任的用户。(而不是每个登陆者访问服务器都可以或得数字证书,服务器证书就是每个登陆的人只要安装数字证书后,就是信任的)。

服务器端模拟CA。初始化时,给我们信任的用户发放唯一身份标识的数字证书。用户每次登陆时,我们会验证其数字证书是不是此用户(C/S)。

我的思路是,先在信任的用户端发放一个唯一标识的数字证书。用户登陆时,我们来验证数字证书是不是此用户。。这样客户端必定要有一个地方存储数字证书。当用户和服务器交互时,我们怎么利用数字证书来完成加密和解密呢。在程序中怎么利用数字证书的publickey和privatekey对信息进行加密和解密。。。还有在服务器端利用一个根证书来签名的话,生成的数字证书都是trustedCertEntry,而不是keyEntry,当客户端存储此数字证书,必然造成客户发到服务器端的信息无法加密。

publicvoidcreateCert(Stringusername,Stringpassword)

{

Stringname="c:/storeLib";

Stringpass="123456";

StringcertPass="111111";

//根证书

Stringalias="mystore";

StringnewCert=username+password;

System.out.println(newCert);

try{

//载入证书库

FileInputStreamin=newFileInputStream(name);

KeyStoreks=KeyStore.getInstance("JKS");

ks.load(in,pass.toCharArray());

//得到签发者

Certificatec=ks.getCertificate(alias);

byte[]encode1=c.getEncoded();

X509CertImplcimp1=newX509CertImpl(encode1);

X509CertInfocinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);

X500Nameissuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME);

PrivateKeypk=(PrivateKey)ks.getKey(alias,certPass.toCharArray());

Calendarcalendar=Calendar.getInstance();

Datebegindate=calendar.getTime();

calendar.add(Calendar.YEAR,1);

Dateenddate=calendar.getTime();

//设置新证书的有效期

CertificateValiditycv=newCertificateValidity(begindate,enddate);

cinfo1.set(X509CertInfo.VALIDITY,cv);

//设置SN号

intsn=(int)(begindate.getTime()/1000);

CertificateSerialNumbercsn=newCertificateSerialNumber(sn);

cinfo1.set(X509CertInfo.SERIAL_NUMBER,csn);

//设置新证书的签发者

cinfo1.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);

//设置新证书的算法

AlgorithmIdalgorithm=newAlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);

cinfo1.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);

//创建新证书

X509CertImplnewcert=newX509CertImpl(cinfo1);

newcert.sign(pk,"MD5WithRSA");

System.out.println(newcert);

ks.setCertificateEntry(newCert,newcert);

FileOutputStreamout=newFileOutputStream(name);

ks.store(out,pass.toCharArray());

}catch(Exceptione){

e.printStackTrace();

}

}

上面的代码是利用根证书的privatekey完成证书的签发。所以签发的证书都是trustedCertEntry。而不是keyEntry。 google了很多文档。都是和此代码类似。大多是利用ssl来完成加密通信的。而不是利用数字证书的公钥和私钥来完成加密和解密的。。。。

希望能得到大家的帮助。谢谢、

现在实现身份验证,通过数字签名来验证了。利用数字证书的私钥来完成签名,引用发出的公钥来验证签名。也是可以完成身份验证的。。。

Signatures=Signature.getInstance("MD5WithRSA");

//或得数字证书的私钥

PrivateKeyprk=(PrivateKey)ks.getKey(alias,pass.toCharArray());

//用私钥初始化Signature

s.initSign(prk);

//传入要签名的数据

s.update(data)

//执行签名

byte[]signaturedata=s.sign();

//利用公钥验证

PublicKeypbk=c.getPublicKey();

Signatures=Signature.getInstance("MD5WithRSA");

s.initVerify(pbk);

//传入要签名的数据

s.update(mes);

try{

s.verify(signeddata);

return"身份验证成功:"+cinfo1.toString();

}catch(SignatureExceptione){

return"身份验证失败";

}

相关推荐