我试图读取数字证书的自定义扩展。我知道这个值是DER编码的为GeneralString。有一种简单的方法来正确解码,并得到一个Java字符串?我尝试以下,但“S”包括一些编码元数据作为垃圾字符的字符串的开始。

byte[] ext = cert.getExtensionValue("1.2.3.4");
String s= new String(ext);
System.out.println(s);

是否有一个快速简便的方法来做到这一点?还是我真的需要使用一些羽翼丰满的ASN.1库?

谢谢!

有帮助吗?

解决方案

BouncyCastle的是(一切中):

  

一个用于读取和写入编码对象ASN.1库。

其他提示

使用包含在下页说明我已经做了一些修改和代码工作的罚款和我在一起。

<强>从早期BC释放移植到1.47和后 - 所述快活城堡军团 http://www.bouncycastle.org/维基/显示从早期+ + BC / JA1 /移植+ + +释放到+ 1.47 + +和后来

private String getExtensionValue(X509Certificate X509Certificate, String oid) throws IOException
{
    String decoded = null;
    byte[] extensionValue = X509Certificate.getExtensionValue(oid);

    if (extensionValue != null)
    {
        ASN1Primitive derObject = toDERObject(extensionValue);
        if (derObject instanceof DEROctetString)
        {
            DEROctetString derOctetString = (DEROctetString) derObject;

            derObject = toDERObject(derOctetString.getOctets());
            if (derObject instanceof ASN1String)
            {
                ASN1String s = (ASN1String)derObject;
                decoded = s.getString();
            }

        }
    }
    return decoded;
}

/**
 * From http://stackoverflow.com/questions/2409618/how-do-i-decode-a-der-encoded-string-in-java
 */
private ASN1Primitive toDERObject(byte[] data) throws IOException
{
    ByteArrayInputStream inStream = new ByteArrayInputStream(data);
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream);

    return asnInputStream.readObject();
}

这原来是用BouncyCastle的相当简单:

private String getExtensionValue(X509Certificate X509Certificate, String oid) throws IOException
{
    String decoded = null;
    byte[] extensionValue = X509Certificate.getExtensionValue(oid);

    if (extensionValue != null)
    {
        DERObject derObject = toDERObject(extensionValue);
        if (derObject instanceof DEROctetString)
        {
            DEROctetString derOctetString = (DEROctetString) derObject;

            derObject = toDERObject(derOctetString.getOctets());
            if (derObject instanceof DERUTF8String)
            {
                DERUTF8String s = DERUTF8String.getInstance(derObject);
                decoded = s.getString();
            }

        }
    }
    return decoded;
}

private DERObject toDERObject(byte[] data) throws IOException
{
    ByteArrayInputStream inStream = new ByteArrayInputStream(data);
    ASN1InputStream asnInputStream = new ASN1InputStream(inStream);

    return asnInputStream.readObject();
}

JcaX509ExtensionUtils做什么的答案在一个更简单的方式做以上。

X509Certificate certificate;
byte[] encodedExtensionValue = certificate.getExtensionValue(oid);
if (encodedExtensionValue != null) {
    ASN1Primitive extensionValue = JcaX509ExtensionUtils
            .parseExtensionValue(encodedExtensionValue);
    String values = extensionValue.toString();          
}

在的Oracle VM(JDK 7):

    DerValue val = new DerValue(ext);
    String s = val.getGeneralString();

http://www.docjar.com/docs /api/sun/security/util/DerValue.html

请注意:呼吁建立一个“快速和肮脏”的解决方案原来的问题,所以我认为这是有效的,但今天,因为它依赖于太阳内部API,它不应该再被特别是因为JDK 9使用起。

充气城堡是该适当的解决方案。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top