仍然有点与ASN1混淆。我正在用ruby解析RFC3161时间戳响应,所以我知道规范。我很确定结构是正确加载的,但我对如何找到我想要的碎片/键感到困惑。我知道有序列(有序)和集合(无序/唯一)。
我知道我们可以调用asn1_object.value[0].value[0],但是这是笨拙的,我希望如果我知道键或头,我可以像对待JSON或YAML一样对待它,只需要调用 asn1_object['TSTInfo']['serialNumber']。它不是这样工作的吗?
我们是否应该使用序列的性质,因为我们也有规格和长度,所以应该按照顺序并知道它们的位置吗?这对我来说很奇怪,但可能是因为我以前没有使用过很多TLV格式。不幸的是,openssl只有很少的文档,只有如何用OpenSSL::ASN1.decode(der)加载对象并按索引访问值。还有traverse方法,但这不会产生标题名称或我认为在本例中使用的任何东西。
#<OpenSSL::ASN1::Sequence:0x000055fdee1a2c68
@indefinite_length=false,
@tag=16,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=
[#<OpenSSL::ASN1::ObjectId:0x000055fdee1a2ec0
@indefinite_length=false,
@tag=6,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value="1.2.840.113549.1.9.52">,
#<OpenSSL::ASN1::Set:0x000055fdee1a2c90
@indefinite_length=false,
@tag=17,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=
[#<OpenSSL::ASN1::Sequence:0x000055fdee1a2cb8
@indefinite_length=false,
@tag=16,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=
[#<OpenSSL::ASN1::Sequence:0x000055fdee1a2da8
@indefinite_length=false,
@tag=16,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=
@value=
[#<OpenSSL::ASN1::ObjectId:0x000055fdee1a3190
@indefinite_length=false,
@tag=6,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value="signingTime">,
#<OpenSSL::ASN1::Set:0x000055fdee1a30f0
@indefinite_length=false,
@tag=17,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=
[#<OpenSSL::ASN1::UTCTime:0x000055fdee1a3118
@indefinite_length=false,
@tag=23,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=2018-12-19 01:49:08 UTC>]>]>发布于 2018-12-18 23:35:07
在您链接的示例中,Openssl.ASN1.decode( DER )利用DER的规范性质从有线数据中重构结构,而根本没有使用ASN.1模式。因此,虽然它可以从从有线数据读取的内容中推断出该结构的形状、组成和内容(特别是如果它是用显式标记编码的,这也给出了数据类型),但它不知道原始模式中的字段名会是什么(这些不是有线格式的数据)。
如果您查看RFC3161时间戳的原始ASN.1模式,就可以确定哪些字段在哪里。
使用带有C/C++的ASN.1,Java和C# one通常使用ASN.1编译器生成源代码。此源代码定义包含从架构中获取字段名的字段的类。抱歉,我不知道这在Ruby的Openssl.ASN1中是否可行
隐式/显式.
您提供的示例提供了一个链接,用于使用隐式标记示例进行次要操作。它将值解释为整数;严格地说,应该将其解释为需要解码的更多ASN.1。碰巧的是,这些字节是整数。
发布于 2021-02-09 16:59:25
让我在这里澄清一下,我刚刚发现了一个矛盾。OP说他是knows the specification,但也提到the signingTime value is two below the declaration是strange。
这使我得出结论,OP意味着他知道格式是由规范决定的,但实际上并不知道规范本身。
让我们一起读其中的一些,这样你就知道了。
让我们回答为什么有时间价值的问题?
在RFC5652第11.3节中提到了签名时间;从这里,我们将知道它是一种属性类型(因为它在第11节下)。第5.3节中的同一文档中也提到了属性类型的结构。
属性::=序列{ attrType对象标识符, attrValues集AttributeValue }
因此,它基本上是一个对象标识符的序列,后面跟着一个集合。
第11.3条还指定集合必须包含确切的一个成员。
这正是我们在这里看到的:
[
#<OpenSSL::ASN1::ObjectId:0x000055fdee1a3190
@indefinite_length=false,
@tag=6,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value="signingTime">,
#<OpenSSL::ASN1::Set:0x000055fdee1a30f0
@indefinite_length=false,
@tag=17,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=[
#<OpenSSL::ASN1::UTCTime:0x000055fdee1a3118
@indefinite_length=false,
@tag=23,
@tag_class=:UNIVERSAL,
@tagging=nil,
@value=2018-12-19 01:49:08 UTC>
]>
]正如前面提到的,OpenSSL::ASN1.decode将der解码为仅仅结构化的红宝石对象,并且没有考虑到每个字段的含义。因此,您需要阅读规范并自己制定字段。这是乏味的,但绝不可能是不可能的。
由于官方库提供的遍历功能几乎毫无用处,我最终自己实现了它。不过,它仍然只是一个工作的原型。
class TraverseASN1
class StopIteration < ::StandardError
def initialize(result = nil)
super(nil)
@result = result
end
attr_reader :result
end
def call(
decoded,
_depth: 0,
_sequence: nil,
_parents: [],
&traversal_block
)
traversal_block.call(
decoded,
depth: _depth,
sequence: _sequence,
parents: _parents
)
value = decoded.value
return unless value.is_a?(::Array)
value.each_with_index do |sub_token, sequence|
call(
sub_token,
_depth: (_depth + 1),
_sequence: sequence,
_parents: [*_parents, decoded],
&traversal_block
)
end
end
end我就是这样用它的:
target_element = begin
TraverseASN1.new.call(asn1) do |current, depth:, parents:, **_unused_args|
next unless depth == 2
next unless current.is_a?(::OpenSSL::ASN1::ObjectId)
next unless current.value == 'pkcs7-signedData'
raise TraverseASN1::StopIteration.new(parents.last)
end
rescue TraverseASN1::StopIteration => e
e.result
end一旦你知道了格式,开始黑客攻击是相当微不足道的。
https://stackoverflow.com/questions/53840379
复制相似问题