【问题标题】:Specific decode choice ASN.1具体解码选择ASN.1
【发布时间】:2019-12-23 16:11:28
【问题描述】:

我正在使用 erlang ASN.1 编译器,并且我有以下 ASN.1 定义:

DecryptedCertificate ::= SEQUENCE {
    certificateProfileIdentifier INTEGER(0..255),
    certificateAuthorityReference CertificateAuthority,
    certificateHolderAuthorization CertificateHolderAuthorization,
    endOfValidity TimeReal,
    certificateHolderReference KeyIdentifier,
    rsaPublicKey RsaPublicKey
}

KeyIdentifier ::= CHOICE {
    extendedSerialNumber ExtendedSerialNumber,
    certificateRequestID CertificateRequestID,
    certificationAuthorityKID CertificationAuthorityKID
}

当我解码一个二进制文件时,它总是选择CertificateRequestID 选项,我想为解码器指定一个特定的选项,这可能吗?

PS:我正在使用 PER。

编辑: 我正在提供更多信息以使问题更清楚

CHOICE 类型有:

ExtendedSerialNumber ::= SEQUENCE {
  serialNumber INTEGER(0..2^32-1)
  monthYear BCDString(SIZE(2))
  type OCTET STRING(SIZE(1))
  manufacturerCode ManufacturerCode
}

CertificateRequestID ::= SEQUENCE {
  requestSerialNumber INTEGER(0..2^32-1)
  requestMonthYear BCDString(SIZE(2))
  crIdentifier OCTET STRING(SIZE(1))
  manufacturerCode ManufacturerCode
}
CertificationAuthorityKID ::= SEQUENCE {
  nationNumeric NationNumeric
  nationAlpha NationAlpha
  keySerialNumber INTEGER(0..255)
  additionalInfo OCTET STRING(SIZE(2))
  caIdentifier OCTET STRING(SIZE(1))
}

ManufacturerCode ::= INTEGER(0..255)
NationNumeric ::= INTEGER(0..255)
NationAlpha ::= IA5String(SIZE(3))

有一些确定性的东西,例如:

  1. caIdentifier 始终等于 1;
  2. crIdentifier 始终等于 0xFF。

我尝试使用caIdentifier INTEGER(1)crIdentifier INTEGER(255) 指定数字,但它总是选择第一个选项并引发解析错误。

【问题讨论】:

    标签: erlang elixir asn.1


    【解决方案1】:

    当我解码一个二进制文件时,它总是选择 CertificateRequestID 选项,我想为解码器指定一个特定的选项,这可能吗?

    无法指定要解码的内容。当您解码特定的二进制消息/记录/PDU 时,解码器将根据 ASN.1 定义和 UPER/APER 编码规则选择二进制中包含的任何内容。

    二进制文件中的某处有两个位确定KeyIdentifier 包含的内容,如果您能够找到并更改它们,解码器将尝试解码不同的字段,但很可能会失败,因为您的二进制消息实际上包含不同的字段。

    您可以尝试创建一个KeyIdentifier,填充您想要的任何值,然后对其进行编码,以了解这个不同的二进制文件会是什么样子。

    更新

    PER 格式不包含选项类型的标题。

    在 PER 编码中,CHOICE 确实包含一个指定编码类型的索引(标头)。见X.691 23 Encoding the choice type

    23 Encoding the choice type
    NOTE – (Tutorial) A choice type is encoded by encoding an index specifying the
    chosen alternative. This is encoded as for a constrained integer (unless the 
    extension marker is present in the choice type, in which case it is a normally
    small non-negative whole number) and would therefore typically occupy a fixed
    length bit-field of the minimum number of bits needed to encode the index.
    Although it could in principle be arbitrarily large.) This is followed by the
    encoding of the chosen alternative, with alternatives that are extension 
    additions encoded as if they were the value of an open type field. Where the
    choice has only one alternative, there is no encoding for the index.
    

    【讨论】:

    • PER 格式不包含选项类型的标题。从我在 erlang 文档中读到的内容来看,解码特定选择的唯一方法是使用 Specialized Decodes,出于某种原因提到它们仅适用于 BER。
    • 我分析了二进制文件,我可以确认没有头文件,可能是创建结构时没有遵循规范。
    • 当 PER 解码器解码 KeyIdentifier 时,它将解码一个索引,告诉解码器存在哪些替代方案。我不知道您如何确定不存在标题。当解码器去解码 CHOICE 类型时,无论有什么位都将被解释为选择索引。如果您先验地知道应该编码的数据是什么,那么您可以确定它是否被正确编码。否则,这些位就是解码规则所说的。
    【解决方案2】:

    您似乎走错了路来解决您的问题:您不能修改 ASN.1 规范来解决它。

    在您的问题中,您应该添加有关您为解码输入而编写的 erlang 代码的更多信息。

    要么 erlang 编译器有错误,要么你没有正确使用它...

    您还可以使用https://asn1.io/asn1playground/ 作为测试来解码您的 PER 数据

    【讨论】:

    • 没有编写用于解码的自定义代码,模式的编写与我的问题完全相同。我正在使用内置的 erlang asn.1 编译器。 erlang.org/doc/apps/asn1/asn1_getting_started.html
    • 您确定 erlang ASN.1 编译器在编译您的 ASN.1 模式时不会产生任何错误消息吗?您的 ASN.1 架构包含多个语法错误(例如,每个组件末尾缺少逗号,以及 ASN.1 中不存在的表达式“2^32-1”)。
    • 这些是为了美观而改变的,以便于阅读。
    【解决方案3】:

    在深入研究 Asn.1 异构系统之间的通信后,我发现了一个很好的段落,名为 Selecting a CHOICE alternative,它准确地说明了我在寻找什么:

    选择的类型可以通过左尖括号“

    所以我的结构的解决方案是使用:

    DecryptedCertificate ::= SEQUENCE {
        certificateProfileIdentifier INTEGER(0..255),
        certificateAuthorityReference CertificateAuthority,
        certificateHolderAuthorization CertificateHolderAuthorization,
        endOfValidity TimeReal,
        certificateHolderReference certificationAuthorityKID < KeyIdentifier,
        rsaPublicKey RsaPublicKey
    }
    

    当然,我可以自己硬编码类型,但是在规范修改和可读性方面这更灵活。

    【讨论】:

    • 这不是向后兼容的更改,这样做您的实现将与本规范的其他实现不兼容。
    • 瓦西尔是正确的。如果您尝试使用实际规范与某人交换消息,您不想进行此更改。它消除了 CHOICE 类型,这从根本上改变了编码。在 PER 中,CHOICE 类型的编码不仅仅是所选替代的编码。
    • 是的,这个我很理解,但是当前的编码没有标头。
    猜你喜欢
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多