/**
* @param certInfo 证书链.P7B文件的文本内容
* @param rootCA 用户信任的顶级根证书PEM文件文本内容,头尾不能少
* @param subjectName 当前证书的使用者
* @return Boolean
* @throws Exception
*/
public static boolean verifyCerChains(String certInfo, String rootCA, String subjectName) throws Exception {
//用户信任的顶级根证书
X509Certificate X509certificateRoot = getRootCA(rootCA);
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
CMSSignedData sd = new CMSSignedData(Base64.decodeBase64(certInfo));
Store<X509CertificateHolder> store = sd.getCertificates();
Collection<X509CertificateHolder> certChains = store.getMatches(null);
//获取证书链长度
int nSize = certChains.size();
//将证书链转化为数组
X509Certificate[] arX509certificate = new X509Certificate[certChains.size()];
int j = 0;
for (X509CertificateHolder holder : certChains) {
arX509certificate[j++] = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder);
}
//声明list,存储证书链中证书主体信息
ArrayList list = new ArrayList();
//沿证书链自上而下,验证证书的所有者是下一个证书的颁布者
Principal principalLast = null;
//遍历arX509certificate
for (int i = 0; i < nSize; i++) {
X509Certificate x509Certificate = arX509certificate[i];
//获取发布者标识
Principal principalIssuer = x509Certificate.getIssuerDN();
//获取证书的主体标识
Principal principalSubject = x509Certificate.getSubjectDN();
//保存证书的序列号
list.add(x509Certificate.getSerialNumber());
//使用者
String certchainsUsers = String.valueOf(x509Certificate.getSubjectDN().getName());
System.out.println(certchainsUsers);
if (principalLast != null) {
//验证证书的颁布者是上一个证书的所有者
if (principalIssuer.equals(principalLast)) {
try {
//获取上个证书的公钥
PublicKey publickey = arX509certificate[i - 1].getPublicKey();
//验证是否已使用与指定公钥相应的私钥签署了此证书
arX509certificate[i].verify(publickey);
} catch (Exception e) {
return false;
}
} else {
return false;
}
}
principalLast = principalSubject;
}
//证明证书链中的第一个证书由用户所信任的CA颁布
try {
PublicKey publickey = X509certificateRoot.getPublicKey();
arX509certificate[0].verify(publickey);
} catch (Exception e) {
return false;
}
//证明证书链中的最后一个证书的所有者正是现在通信对象
Principal principalSubject = arX509certificate[nSize - 1].getSubjectDN();
if (!subjectName.equals(principalSubject.getName())) {
return false;
}
//验证证书链里每个证书是否在有效期里
Date date = new Date();
for (int i = 0; i < nSize; i++) {
try {
arX509certificate[i].checkValidity(date);
} catch (Exception e) {
return false;
}
}
return true;
}