如何使用java或bouncy castle从CSR解析SAN?

时间:2014-06-27 09:51:46

标签: bouncycastle

我使用openssl生成了CSR。现在我想解析CSR并显示CSR中可用的ipaddress,Othername。

我写了以下代码。它能够正确显示dns,url,但我无法以正确的格式显示ipaddress和othername。

  public static void testReadCertificateSigningRequest()  {
     String csrPEM = null;
     try {
      FileInputStream fis = new FileInputStream("E://test.txt");
      csrPEM = IOUtils.toString(fis);
     } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
     }  

PKCS10CertificationRequest csr = convertPemToPKCS10CertificationRequest(csrPEM);

X500Name x500Name = csr.getSubject();
System.out.println("x500Name is: " + x500Name + "\n");


 Attribute[] certAttributes = csr.getAttributes();
 for (Attribute attribute : certAttributes) {
     if (attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {
         Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));
         //Extension ext = extensions.getExtension(Extension.subjectAlternativeName);
         GeneralNames gns = GeneralNames.fromExtensions(extensions,Extension.subjectAlternativeName);
         GeneralName[] names = gns.getNames();
         for(int k=0; k < names.length; k++) {
             String title = "";
             if(names[k].getTagNo() == GeneralName.dNSName) {
                 title = "dNSName";
             }
             else if(names[k].getTagNo() == GeneralName.iPAddress) {
                 title = "iPAddress";
                 names[k].toASN1Object();
             }
             else if(names[k].getTagNo() == GeneralName.otherName) {
                 title = "otherName";
             }
             System.out.println(title + ": "+ names[k].getName());
         } 
     }
}

}


// Method to convert PEM to PKCS10CertificationRequest
private static PKCS10CertificationRequest convertPemToPKCS10CertificationRequest(String pem) {
    PEMParser pRd = new PEMParser(new StringReader(pem));
    org.bouncycastle.pkcs.PKCS10CertificationRequest csr = null;
    try {
        csr = (org.bouncycastle.pkcs.PKCS10CertificationRequest) pRd.readObject();
    } catch (IOException e) {
        e.printStackTrace();
    } 
    return csr;
}

上面的代码打印iPAddress,otherName如下:

iPAddress:#c0a80701  iPAddress:#00130000000000000000000000000017  otherName:[1.2.3.4,[0]其他标识符]

如何以正确的格式检索ipAdress和othername?

感谢。

2 个答案:

答案 0 :(得分:1)

这是正确的&#39;格式。除了手动转换之外没有其他方法,正如另一个答案所暗示的那样。

BouncyCastle在GeneralName.java类构造函数内部对此进行编码。

  153           else if (tag == iPAddress)
  154           {
  155               byte[] enc = toGeneralNameEncoding(name);
  156               if (enc != null)
  157               {
  158                   this.obj = new DEROctetString(enc);
  159               }
  160               else
  161               {
  162                   throw new IllegalArgumentException("IP Address is invalid");
  163               }
  164           }

请参阅: http://www.docjar.org/html/api/org/bouncycastle/asn1/x509/GeneralName.java.html

当您从CSR中提取GeneralNames以将其合并到证书中时,BouncyCastle也会再次对其进行解码,因此原始值最终会出现在最终证书中。

关于otherName属性: &#34;对于x400Address,otherName和ediPartyName,没有定义常见的字符串格式。&#34; 所以没有正确的&#39;格式化。

请参阅: http://www.eecs.berkeley.edu/~jonah/javadoc/org/bouncycastle/asn1/x509/GeneralName.html

答案 1 :(得分:0)

为了将iPAddress从Hex格​​式转换为点分格式,我找到了这个解决方案: Convert hexadecimal string to IP Address

InetAddress a = InetAddress.getByAddress(DatatypeConverter.parseHexBinary(names[k].getName().toString().substring(1)));

然后

name = a.toString();