如何从含超int最大值组件的OID字符串初始化ASN1ObjectIdentifier?
解决asn1j库处理超大UUID OID节点的问题
我需要构造符合{joint-iso-itu-t(2) uuid(25)}弧的ASN.1 OID,但UUID转换后的数值超出了int最大值,直接用int[]构造Asn1ObjectIdentifier行不通;尝试用字符串OID通过Asn1BerDecodeBuffer解码,结果得到的OID完全错误(输出类似1.10.46.50.53...),用BouncyCastle转码后解码也失败。
错误原因
- 直接用
int[]构造:UUID对应的OID节点数值超过int类型的最大值(2^31-1),无法存入int数组。 - 错误使用
Asn1BerDecodeBuffer:该缓冲区用于解码ASN.1 BER编码的二进制数据,而非字符串形式的OID。你传入的字符串UTF-8字节会被当作BER流解析,每个字符的ASCII码被解析为OID节点,导致结果完全错误。
解决方案
方案1:直接使用字符串构造(推荐)
多数版本的asn1j库提供了直接接受OID字符串的构造函数或setValue方法,无需手动处理二进制编码:
方式1:字符串构造函数
import com.objsys.asn1j.runtime.Asn1ObjectIdentifier; public Asn1ObjectIdentifier getAttributeOID() { String oidStr = "2.25.142312163956071652603888631318689442116"; return new Asn1ObjectIdentifier(oidStr); }
方式2:setValue方法(兼容旧版本)
如果你的asn1j版本没有字符串构造函数,可使用setValue方法:
import com.objsys.asn1j.runtime.Asn1ObjectIdentifier; public Asn1ObjectIdentifier getAttributeOID() { String oidStr = "2.25.142312163956071652603888631318689442116"; Asn1ObjectIdentifier oid = new Asn1ObjectIdentifier(); oid.setValue(oidStr); return oid; }
方案2:通过BouncyCastle生成BER二进制后解码
若必须使用BER解码方式,需先借助BouncyCastle生成正确的BER编码字节,再传入Asn1BerDecodeBuffer:
import com.objsys.asn1j.runtime.Asn1ObjectIdentifier; import com.objsys.asn1j.runtime.Asn1BerDecodeBuffer; import org.bouncycastle.asn1.DERObjectIdentifier; import java.io.IOException; public Asn1ObjectIdentifier getAttributeOID() throws IOException { String oidStr = "2.25.142312163956071652603888631318689442116"; // 用BouncyCastle生成BER编码的OID字节 DERObjectIdentifier bcOid = new DERObjectIdentifier(oidStr); byte[] berEncodedBytes = bcOid.getEncoded(); // 用asn1j解码BER字节 Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(berEncodedBytes); Asn1ObjectIdentifier asn1Oid = new Asn1ObjectIdentifier(); asn1Oid.decode(decodeBuffer, true, berEncodedBytes.length); return asn1Oid; }
内容的提问来源于stack exchange,提问作者Okan Konur
相关产品推荐
相关产品推荐

