检索java中X.509证书的主题替代名称
我已尝试使用本文提供的解决方案 当我尝试读取X.509证书的主题替代名称时,我遇到以下错误 java.lang.NoSuchMethodError:org.bouncycastle.asn1.ASN1InputStream.readObject()Lorg/bouncycastle/asn1/DERObject 在代码的下面一行 ASN1InputStream解码器=新的ASN1InputStream((字节[])项。toArray() DeRecodable encoded=decoder.readObject() .der文件用于创建证书,如下所示检索java中X.509证书的主题替代名称,java,x509certificate,asn.1,Java,X509certificate,Asn.1,我已尝试使用本文提供的解决方案 当我尝试读取X.509证书的主题替代名称时,我遇到以下错误 java.lang.NoSuchMethodError:org.bouncycastle.asn1.ASN1InputStream.readObject()Lorg/bouncycastle/asn1/DERObject 在代码的下面一行 ASN1InputStream解码器=新的ASN1InputStream((字节[])项。toArray() DeRecodable encoded=decoder.r
X509Certificate cert=null;
fis = new FileInputStream(file.getAbsoluteFile()); //.der file
bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0) {
try{
cert = cf.generateCertificate(bis);
}
catch (CertificateException e) {
e.printStackTrace();
}
List list=getSubjectAlternativeNames((X509Certificate) cert);
下面是我从上面提到的链接得到的解决方案
public static List<String> getSubjectAlternativeNames(X509Certificate certificate) {
List<String> identities = new ArrayList<String>();
try {
Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();
// Check that the certificate includes the SubjectAltName extension
if (altNames == null)
return Collections.emptyList();
// Use the type OtherName to search for the certified server name
for (List item : altNames) {
Integer type = (Integer) item.get(0);
if (type == 0)
// Type OtherName found so return the associated value
try {
// Value is encoded using ASN.1 so decode it to get the server's identity
ASN1InputStream decoder = new ASN1InputStream((byte[]) item.toArray()[1]);
DEREncodable encoded = decoder.readObject();
encoded = ((DERSequence) encoded).getObjectAt(1);
encoded = ((DERTaggedObject) encoded).getObject();
encoded = ((DERTaggedObject) encoded).getObject();
String identity = ((DERUTF8String) encoded).getString();
// Add the decoded server name to the list of identities
identities.add(identity);
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
// log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
}
catch (Exception e) {
// log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
e.printStackTrace();
}
// Other types are not good for XMPP so ignore them
//log.warn("SubjectAltName of invalid type found: " + certificate);
}
}
catch (CertificateParsingException e) {
e.printStackTrace();
// log.error("Error parsing SubjectAltName in certificate: " + certificate + "\r\nerror:" + e.getLocalizedMessage(),e);
}
return identities;
}
公共静态列表getSubjectAlternativeNames(X509证书){
列表标识=新的ArrayList();
试一试{
集合我尝试了你的代码,它正在运行,我使用从internet explorer导出的证书进行了测试
Internet Explorer -> Tools -> Internet Options -> Content -> Certificates -> Untrusted Publishers -> www.google.com
我将其导出为“.cer”,我对您的代码做了一些更改
public static List<String> getSubjectAlternativeNames(X509Certificate certificate) {
List<String> identities = new ArrayList<String>();
try {
Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();
if (altNames == null)
return Collections.emptyList();
for (List item : altNames) {
Integer type = (Integer) item.get(0);
if (type == 0 || type == 2){
try {
ASN1InputStream decoder=null;
if(item.toArray()[1] instanceof byte[])
decoder = new ASN1InputStream((byte[]) item.toArray()[1]);
else if(item.toArray()[1] instanceof String)
identities.add( (String) item.toArray()[1] );
if(decoder==null) continue;
DEREncodable encoded = decoder.readObject();
encoded = ((DERSequence) encoded).getObjectAt(1);
encoded = ((DERTaggedObject) encoded).getObject();
encoded = ((DERTaggedObject) encoded).getObject();
String identity = ((DERUTF8String) encoded).getString();
identities.add(identity);
}
catch (UnsupportedEncodingException e) {
log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
}
catch (Exception e) {
log.error("Error decoding subjectAltName" + e.getLocalizedMessage(),e);
}
}else{
log.warn("SubjectAltName of invalid type found: " + certificate);
}
}
}
catch (CertificateParsingException e) {
log.error("Error parsing SubjectAltName in certificate: " + certificate + "\r\nerror:" + e.getLocalizedMessage(),e);
}
return identities;
}
我得到的输出是[www.google.com,google.com]
请检查您的证书,我认为问题在于您的证书许多示例使用硬编码整数。为了可读性,我更喜欢使用:
GeneralName.dNSName
=2
GeneralName.iPAddress
=7
- …等等
守则:
public static String[] parseHostNames(X509Certificate cert) {
List<String> hostNameList = new ArrayList<>();
try {
Collection<List<?>> altNames = cert.getSubjectAlternativeNames();
if (altNames != null) {
for(List<?> altName : altNames) {
if(altName.size()< 2) continue;
switch((Integer)altName.get(0)) {
case GeneralName.dNSName:
case GeneralName.iPAddress:
Object data = altName.get(1);
if (data instanceof String) {
hostNameList.add(((String)data));
}
break;
default:
}
}
}
System.out.println("Parsed hostNames: " + String.join(", ", hostNameList));
} catch(CertificateParsingException | IOException e) {
System.err.println("Can't parse hostNames from this cert.");
e.printStackTrace();
}
return hostNameList.toArray(new String[hostNameList.size()]);
}
公共静态字符串[]解析主机名(X509证书证书证书){
List hostNameList=new ArrayList();
试一试{
收集感谢您的解决方案。是的,它正在为.cer文件工作,我从IE中获取。我也需要它为.der文件工作。问题只是我的证书。
public static String[] parseHostNames(X509Certificate cert) {
List<String> hostNameList = new ArrayList<>();
try {
Collection<List<?>> altNames = cert.getSubjectAlternativeNames();
if (altNames != null) {
for(List<?> altName : altNames) {
if(altName.size()< 2) continue;
switch((Integer)altName.get(0)) {
case GeneralName.dNSName:
case GeneralName.iPAddress:
Object data = altName.get(1);
if (data instanceof String) {
hostNameList.add(((String)data));
}
break;
default:
}
}
}
System.out.println("Parsed hostNames: " + String.join(", ", hostNameList));
} catch(CertificateParsingException | IOException e) {
System.err.println("Can't parse hostNames from this cert.");
e.printStackTrace();
}
return hostNameList.toArray(new String[hostNameList.size()]);
}