大家好。我现在在学习数字证书。希望能得到你们的帮助。现在的想法,是利用数字证书来完成用户的身份验证,此用户是不是我们信任的用户。(而不是每个登陆者访问服务器都可以或得数字证书,服务器证书就是每个登陆的人只要安装数字证书后,就是信任的)。
服务器端模拟CA。初始化时,给我们信任的用户发放唯一身份标识的数字证书。用户每次登陆时,我们会验证其数字证书是不是此用户(C/S)。
我的思路是,先在信任的用户端发放一个唯一标识的数字证书。用户登陆时,我们来验证数字证书是不是此用户。。这样客户端必定要有一个地方存储数字证书。当用户和服务器交互时,我们怎么利用数字证书来完成加密和解密呢。在程序中怎么利用数字证书的public key 和private key对信息进行加密和解密。。。还有在服务器端利用一个根证书来签名的话,生成的数字证书都是 trustedCertEntry,而不是 keyEntry,当客户端存储此数字证书,必然造成客户发到服务器端的信息无法加密。
public void createCert(String username,String password)
{
String name = "c:/storeLib";
String pass = "123456";
String certPass = "111111";
//根证书
String alias = "mystore";
String newCert = username+password;
System.out.println(newCert);
try {
//载入证书库
FileInputStream in = new FileInputStream(name);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(in,pass.toCharArray());
//得到签发者
Certificate c = ks.getCertificate(alias);
byte[] encode1 = c.getEncoded();
X509CertImpl cimp1 = new X509CertImpl(encode1);
X509CertInfo cinfo1 = (X509CertInfo) cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);
X500Name issuer = (X500Name) cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME);
PrivateKey pk = (PrivateKey)ks.getKey(alias, certPass.toCharArray());
Calendar calendar = Calendar.getInstance();
Date begindate = calendar.getTime();
calendar.add(Calendar.YEAR, 1);
Date enddate = calendar.getTime();
//设置新证书的有效期
CertificateValidity cv = new CertificateValidity(begindate,enddate);
cinfo1.set(X509CertInfo.VALIDITY, cv);
//设置SN号
int sn = (int)(begindate.getTime()/1000);
CertificateSerialNumber csn = new CertificateSerialNumber(sn);
cinfo1.set(X509CertInfo.SERIAL_NUMBER,csn);
//设置新证书的签发者
cinfo1.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME, issuer);
//设置新证书的算法
AlgorithmId algorithm = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
cinfo1.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM, algorithm);
//创建新证书
X509CertImpl newcert = new X509CertImpl(cinfo1);
newcert.sign(pk,"MD5WithRSA");
System.out.println(newcert);
ks.setCertificateEntry(newCert, newcert);
FileOutputStream out = new FileOutputStream(name);
ks.store(out, pass.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
}
上面的代码是利用根证书的private key 完成证书的签发。所以签发的证书都是trustedCertEntry。而不是keyEntry。 google了很多文档。都是和此代码类似。大多是利用ssl来完成加密通信的。而不是利用数字证书的公钥和私钥来完成加密和解密的。。。。
希望能得到大家的帮助。谢谢、
[color=red]
现在实现身份验证,通过数字签名来验证了。利用数字证书的私钥来完成签名,引用发出的公钥来验证签名。也是可以完成身份验证的。。。
Signature s = Signature.getInstance("MD5WithRSA");
//或得数字证书的私钥
PrivateKey prk = (PrivateKey)ks.getKey(alias, pass.toCharArray());
//用私钥初始化Signature
s.initSign(prk);
//传入要签名的数据
s.update(data)
//执行签名
byte[] signaturedata = s.sign();
//利用公钥验证
PublicKey pbk = c.getPublicKey();
Signature s = Signature.getInstance("MD5WithRSA");
s.initVerify(pbk);
//传入要签名的数据
s.update(mes);
try {
s.verify(signeddata);
return "身份验证成功:" + cinfo1.toString();
} catch (SignatureException e) {
return "身份验证失败";
}
[/color]
服务器端模拟CA。初始化时,给我们信任的用户发放唯一身份标识的数字证书。用户每次登陆时,我们会验证其数字证书是不是此用户(C/S)。
我的思路是,先在信任的用户端发放一个唯一标识的数字证书。用户登陆时,我们来验证数字证书是不是此用户。。这样客户端必定要有一个地方存储数字证书。当用户和服务器交互时,我们怎么利用数字证书来完成加密和解密呢。在程序中怎么利用数字证书的public key 和private key对信息进行加密和解密。。。还有在服务器端利用一个根证书来签名的话,生成的数字证书都是 trustedCertEntry,而不是 keyEntry,当客户端存储此数字证书,必然造成客户发到服务器端的信息无法加密。
public void createCert(String username,String password)
{
String name = "c:/storeLib";
String pass = "123456";
String certPass = "111111";
//根证书
String alias = "mystore";
String newCert = username+password;
System.out.println(newCert);
try {
//载入证书库
FileInputStream in = new FileInputStream(name);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(in,pass.toCharArray());
//得到签发者
Certificate c = ks.getCertificate(alias);
byte[] encode1 = c.getEncoded();
X509CertImpl cimp1 = new X509CertImpl(encode1);
X509CertInfo cinfo1 = (X509CertInfo) cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);
X500Name issuer = (X500Name) cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME);
PrivateKey pk = (PrivateKey)ks.getKey(alias, certPass.toCharArray());
Calendar calendar = Calendar.getInstance();
Date begindate = calendar.getTime();
calendar.add(Calendar.YEAR, 1);
Date enddate = calendar.getTime();
//设置新证书的有效期
CertificateValidity cv = new CertificateValidity(begindate,enddate);
cinfo1.set(X509CertInfo.VALIDITY, cv);
//设置SN号
int sn = (int)(begindate.getTime()/1000);
CertificateSerialNumber csn = new CertificateSerialNumber(sn);
cinfo1.set(X509CertInfo.SERIAL_NUMBER,csn);
//设置新证书的签发者
cinfo1.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME, issuer);
//设置新证书的算法
AlgorithmId algorithm = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
cinfo1.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM, algorithm);
//创建新证书
X509CertImpl newcert = new X509CertImpl(cinfo1);
newcert.sign(pk,"MD5WithRSA");
System.out.println(newcert);
ks.setCertificateEntry(newCert, newcert);
FileOutputStream out = new FileOutputStream(name);
ks.store(out, pass.toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
}
上面的代码是利用根证书的private key 完成证书的签发。所以签发的证书都是trustedCertEntry。而不是keyEntry。 google了很多文档。都是和此代码类似。大多是利用ssl来完成加密通信的。而不是利用数字证书的公钥和私钥来完成加密和解密的。。。。
希望能得到大家的帮助。谢谢、
[color=red]
现在实现身份验证,通过数字签名来验证了。利用数字证书的私钥来完成签名,引用发出的公钥来验证签名。也是可以完成身份验证的。。。
Signature s = Signature.getInstance("MD5WithRSA");
//或得数字证书的私钥
PrivateKey prk = (PrivateKey)ks.getKey(alias, pass.toCharArray());
//用私钥初始化Signature
s.initSign(prk);
//传入要签名的数据
s.update(data)
//执行签名
byte[] signaturedata = s.sign();
//利用公钥验证
PublicKey pbk = c.getPublicKey();
Signature s = Signature.getInstance("MD5WithRSA");
s.initVerify(pbk);
//传入要签名的数据
s.update(mes);
try {
s.verify(signeddata);
return "身份验证成功:" + cinfo1.toString();
} catch (SignatureException e) {
return "身份验证失败";
}
[/color]