给定对象标识符,我们如何从 ASN.1 DER 编码的二进制文件中读取相应的值?
Given the object identifier, how do we read the corresponding value from a ASN.1 DER encoded binary file?
我正在尝试从 Microsoft 安全目录 (*.cat) 文件中读取与对象标识符对应的值,该文件实际上是 DER 编码的 ASN.1 对象。我正在使用充气城堡创建一个 Asn1Object。当我执行 .ToString() 时,我可以在转储文本中以 ASCII 格式看到我的数据,与对象标识符“1.3.6.1.4.1.311.12.2.1
”相对应,但是有没有办法通过传递此 OID 来专门检索数据?
我看到一个 class Org.BouncyCastle.Asn1.Microsoft,但我不确定如何使用这个 class。任何帮助表示赞赏!到目前为止,我只有这个,我调用 File.ReadAllBytes 并传递给我在下面编写的函数,在此我可以调用 ToString() 并查看 .cat
中的所有数据
private Asn1Object asn1Object(byte[] data)
{
Asn1InputStream asn1InputStream = new Asn1InputStream(data);
if(asn1InputStream != null)
{
return asn1InputStream.ReadObject().;
}
else
{
return null;
}
}
简短的回答:您需要递归地遍历树以找到包含 DerObjectIdentifier 的 DerSequence,然后 returning 下一个同级的 DerObjectIdentifiers。
长答案: 查看 ASN1/DER 结构,对象图中似乎没有一个条目具有 OID 和值.似乎对于特定的 OID,它将是 DerSequence 中的第一个子对象,而该值将是第二个子对象。
将找到包含与您的 OID 匹配的 DerObjectIdentifier 的 DerSequence 的递归方法和 return 您的下一个兄弟是:
public static Asn1Object FindAsn1Value(string oid, Asn1Object obj)
{
Asn1Object result = null;
if (obj is Asn1Sequence)
{
bool foundOID = false;
foreach (Asn1Object entry in (Asn1Sequence)obj)
{
var derOID = entry as DerObjectIdentifier;
if (derOID != null && derOID.Id == oid)
{
foundOID = true;
}
else if (foundOID)
{
return entry;
}
else
{
result = FindAsn1Value(oid, entry);
if (result != null)
{
return result;
}
}
}
}
else if (obj is DerTaggedObject)
{
result = FindAsn1Value(oid, ((DerTaggedObject)obj).GetObject());
if (result != null)
{
return result;
}
}
else
{
if (obj is DerSet)
{
foreach (Asn1Object entry in (DerSet)obj)
{
result = FindAsn1Value(oid, entry);
if (result != null)
{
return result;
}
}
}
}
return null;
}
要调用它,您需要使用您提供的方法加载 Asn1Object,然后调用上面显示的 FindAsn1Value。这应该 return 你是你想要的 Asn1Object(在我的测试猫文件中,这个值是一个 DerOctetString)。
Asn1Object asn = asn1Object(File.ReadAllBytes(@"test_file.cat"));
Asn1Object value = FindAsn1Value("1.3.6.1.4.1.311.12.2.1", asn);
if (value is DerOctetString)
{
UnicodeEncoding unicode = new UnicodeEncoding(true, true);
Console.WriteLine("DerOctetString = {0}", unicode.GetString(((DerOctetString)value).GetOctets()));
}
我不确定该 OID 的值是否始终是 DerOctetString,也不确定我的解码选择是否一定正确,但它为我提供了我的测试所使用的值的最易读版本。
更新
如果同一个 OID 在层次结构中多次出现并且您需要 return 所有可能的值,替代方法可以是:
public static List<Asn1Object> FindAsn1Values(string oid, Asn1Object obj)
{
Asn1Object result = null;
List<Asn1Object> results = new List<Asn1Object>();
if (obj is Asn1Sequence)
{
bool foundOID = false;
foreach (Asn1Object entry in (Asn1Sequence)obj)
{
var derOID = entry as DerObjectIdentifier;
if (derOID != null && derOID.Id == oid)
{
foundOID = true;
}
else if (foundOID)
{
results.Add(entry);
}
else
{
result = FindAsn1Values(oid, entry);
if (result.Count > 0)
{
results.AddRange(result);
}
}
}
}
else if (obj is DerTaggedObject)
{
result = FindAsn1Values(oid, ((DerTaggedObject)obj).GetObject());
if (result.Count > 0)
{
results.AddRange(result);
}
}
else
{
if (obj is DerSet)
{
foreach (Asn1Object entry in (DerSet)obj)
{
result = FindAsn1Values(oid, entry);
if (result.Count > 0)
{
results.AddRange(result);
}
}
}
}
return results;
}
我正在尝试从 Microsoft 安全目录 (*.cat) 文件中读取与对象标识符对应的值,该文件实际上是 DER 编码的 ASN.1 对象。我正在使用充气城堡创建一个 Asn1Object。当我执行 .ToString() 时,我可以在转储文本中以 ASCII 格式看到我的数据,与对象标识符“1.3.6.1.4.1.311.12.2.1
”相对应,但是有没有办法通过传递此 OID 来专门检索数据?
我看到一个 class Org.BouncyCastle.Asn1.Microsoft,但我不确定如何使用这个 class。任何帮助表示赞赏!到目前为止,我只有这个,我调用 File.ReadAllBytes 并传递给我在下面编写的函数,在此我可以调用 ToString() 并查看 .cat
中的所有数据private Asn1Object asn1Object(byte[] data)
{
Asn1InputStream asn1InputStream = new Asn1InputStream(data);
if(asn1InputStream != null)
{
return asn1InputStream.ReadObject().;
}
else
{
return null;
}
}
简短的回答:您需要递归地遍历树以找到包含 DerObjectIdentifier 的 DerSequence,然后 returning 下一个同级的 DerObjectIdentifiers。
长答案: 查看 ASN1/DER 结构,对象图中似乎没有一个条目具有 OID 和值.似乎对于特定的 OID,它将是 DerSequence 中的第一个子对象,而该值将是第二个子对象。
将找到包含与您的 OID 匹配的 DerObjectIdentifier 的 DerSequence 的递归方法和 return 您的下一个兄弟是:
public static Asn1Object FindAsn1Value(string oid, Asn1Object obj)
{
Asn1Object result = null;
if (obj is Asn1Sequence)
{
bool foundOID = false;
foreach (Asn1Object entry in (Asn1Sequence)obj)
{
var derOID = entry as DerObjectIdentifier;
if (derOID != null && derOID.Id == oid)
{
foundOID = true;
}
else if (foundOID)
{
return entry;
}
else
{
result = FindAsn1Value(oid, entry);
if (result != null)
{
return result;
}
}
}
}
else if (obj is DerTaggedObject)
{
result = FindAsn1Value(oid, ((DerTaggedObject)obj).GetObject());
if (result != null)
{
return result;
}
}
else
{
if (obj is DerSet)
{
foreach (Asn1Object entry in (DerSet)obj)
{
result = FindAsn1Value(oid, entry);
if (result != null)
{
return result;
}
}
}
}
return null;
}
要调用它,您需要使用您提供的方法加载 Asn1Object,然后调用上面显示的 FindAsn1Value。这应该 return 你是你想要的 Asn1Object(在我的测试猫文件中,这个值是一个 DerOctetString)。
Asn1Object asn = asn1Object(File.ReadAllBytes(@"test_file.cat"));
Asn1Object value = FindAsn1Value("1.3.6.1.4.1.311.12.2.1", asn);
if (value is DerOctetString)
{
UnicodeEncoding unicode = new UnicodeEncoding(true, true);
Console.WriteLine("DerOctetString = {0}", unicode.GetString(((DerOctetString)value).GetOctets()));
}
我不确定该 OID 的值是否始终是 DerOctetString,也不确定我的解码选择是否一定正确,但它为我提供了我的测试所使用的值的最易读版本。
更新
如果同一个 OID 在层次结构中多次出现并且您需要 return 所有可能的值,替代方法可以是:
public static List<Asn1Object> FindAsn1Values(string oid, Asn1Object obj)
{
Asn1Object result = null;
List<Asn1Object> results = new List<Asn1Object>();
if (obj is Asn1Sequence)
{
bool foundOID = false;
foreach (Asn1Object entry in (Asn1Sequence)obj)
{
var derOID = entry as DerObjectIdentifier;
if (derOID != null && derOID.Id == oid)
{
foundOID = true;
}
else if (foundOID)
{
results.Add(entry);
}
else
{
result = FindAsn1Values(oid, entry);
if (result.Count > 0)
{
results.AddRange(result);
}
}
}
}
else if (obj is DerTaggedObject)
{
result = FindAsn1Values(oid, ((DerTaggedObject)obj).GetObject());
if (result.Count > 0)
{
results.AddRange(result);
}
}
else
{
if (obj is DerSet)
{
foreach (Asn1Object entry in (DerSet)obj)
{
result = FindAsn1Values(oid, entry);
if (result.Count > 0)
{
results.AddRange(result);
}
}
}
}
return results;
}