• 175210课设第二次报告


    本周计划

    • 初步完成 asn.1 编解码
    • 进一步学习 asn.1 语法

    完成情况

    使用 ruby 语言实现简单的编解码

    我这几天没有找到满足要求的 java 库, 所以先用 Ruby

    生成一个简单的 asn.1 标准的 der 文件

    require 'openssl'
    
    int = OpenSSL::ASN1::Integer.new(1)
    str = OpenSSL::ASN1::PrintableString.new('abc')
    sequence = OpenSSL::ASN1::Sequence.new([int, str])
    
    der = sequence.to_der
    
    open 'rubytest.der', 'w' do |io|
      io.write der
    end
    

    我感觉这个没啥好说的,调用 ruby openssl库 生成了一个 asn.1 标准的数据结构,再将其写入 der 文件。

    解析这个 der 文件

    一、大体上观察

    require 'openssl'
    
    der = File.binread('rubytest.der')
    OpenSSL::ASN1.traverse der do |depth, offset, header_len, length, constructed, tag_class, tag|
      puts "Depth: #{depth} Offset: #{offset} Length: #{length}"
      puts "Header length: #{header_len} Tag: #{tag} Tag class: #{tag_class} Constructed: #{constructed}"
    end
    

    输出结果是这样的

    Depth: 0 Offset: 0 Length: 8
    Header length: 2 Tag: 16 Tag class: UNIVERSAL Constructed: true
    
    Depth: 1 Offset: 2 Length: 1
    Header length: 2 Tag: 2 Tag class: UNIVERSAL Constructed: false
    
    Depth: 1 Offset: 5 Length: 3
    Header length: 2 Tag: 19 Tag class: UNIVERSAL Constructed: false
    
    • 先看 Constructedtrue 代表其为结构节点,包含子节点; false 代表其为数据节点。

    • 我们来看一看 TagTag classasn.1 标准文件中,每一个节点都有 TagTag class,在不特别指定的情况下,Tag class 默认值为 UniversalTag 默认值由这个节点的数据类型来定,对应关系如下表:

      Type Tag
      INTEGER 2
      BIT STRING 3
      OCTET STRING 4
      NULL 5
      OBJECT IDENTIFIER 6
      SEQUENCE and SEQUENCE OF 16
      SET and SET OF 17
      PrintableString 19
      T61String 20
      IA5String 22
      UTCTime 23
    • offset 表示节点在整个文件中的偏移长度,Length 表示节点数据字节长度

    • Header Length 是节点头部长度,个人认为这个长度把 头字节LEN(存储节点数据长度的字段) 都算了进去

    • 第一个节点(Sequence)的 Length = 8 ,可以由其两个子节点的 Length + Header Length 求得

    二、查看具体内容

    require 'openssl'
    
    der = File.binread('rubytest.der')
    
    asn1 = OpenSSL::ASN1.decode der
    pp asn1
    

    结果如下

    #<OpenSSL::ASN1::Sequence:0x0000555723211270
     @indefinite_length=false,
     @tag=16,
     @tag_class=:UNIVERSAL,
     @tagging=nil,
     @value=
      [#<OpenSSL::ASN1::Integer:0x0000555723211310
        @indefinite_length=false,
        @tag=2,
        @tag_class=:UNIVERSAL,
        @tagging=nil,
        @value=#<OpenSSL::BN 1>>,
       #<OpenSSL::ASN1::PrintableString:0x0000555723211298
        @indefinite_length=false,
        @tag=19,
        @tag_class=:UNIVERSAL,
        @tagging=nil,
        @value="abc">]>
    
    • @indefinite_length=false表示编码长度是有限的(我不确定)
    • @value 可以看到节点的值

    尝试自定义 tag

    require 'openssl'
    
    int = OpenSSL::ASN1::Integer.new(1, 0, :EXPLICIT)
    der = int.to_der
    
    pp OpenSSL::ASN1.decode der
    

    Integer 为例,Integer.new() 第一个参数是这个节点的 value,第二个参数是自定义的 tag 值,第三个参数指定采用 implicit 还是 explicit 模式。

    输出如下

    #<OpenSSL::ASN1::ASN1Data:0x0000564fe9f2db60
     @indefinite_length=false,
     @tag=0,
     @tag_class=:CONTEXT_SPECIFIC,
     @value=
      [#<OpenSSL::ASN1::Integer:0x0000564fe9f2dbb0
        @indefinite_length=false,
        @tag=2,
        @tag_class=:UNIVERSAL,
        @tagging=nil,
        @value=#<OpenSSL::BN 1>>]>
    

    我们可以发现 explicit 模式,是直接在原节点外包裹了一个新节点,新节点的 tag class 默认为 CONTEXT_SPECIFIC

    再试试 implicit 模式

    require 'openssl'
    
    int = OpenSSL::ASN1::Integer.new(1, 0, :IMPLICIT)
    der = int.to_der
    
    pp OpenSSL::ASN1.decode der
    

    输出为

    #<OpenSSL::ASN1::ASN1Data:0x000055a6f86762a0
     @indefinite_length=false,
     @tag=0,
     @tag_class=:CONTEXT_SPECIFIC,
     @value="x01">
    

    我们发现,implicit 模式是直接改变了原节点

    总结

    Rubyopenssl 库对新手非常友好,适合实践解决疑惑。文档也相当齐全,用起来很爽。

  • 相关阅读:
    黄页js-sdk开发总结分享
    最近的shell脚本(updating)
    nginx location 的配置
    nodejs 的安全
    paypal之nodejs 框架 Kraken-js 源码分析
    nodejs express 框架解密5-视图
    nodejs express 框架解密4-路由
    nodejs express 框架解密3-中间件模块
    nodejs express 框架解密2-如何创建一个app
    nodejs express 框架解密1-总体结构
  • 原文地址:https://www.cnblogs.com/mtzf/p/12769923.html
Copyright © 2020-2023  润新知