想要了解证书,必须先了解ASN.1和编码规则。这篇文章简单介绍ASN.1,不过分探讨细节,大家如果有兴趣可以继续深入研究。

一、ASN.1

ASN.1是Abstract Syntax Notation One(抽象文法描述语言)的缩写。计算机系统之间交换的数据消息如果用ASN.1进行描述,可以减少了双方的沟通成本。

ASN.1作为抽象描述文法,将现有的数据类型抽象描述成近20种数据类型。这些数据类型主要分为两大类:基本类型和结构类型。ASN.1的数据类型几乎概括了现实世界中存在的所有数据类型,具有相当的通用性。

基本类型又称为原子类型,是构成其他结构类型的成员类型,如

  1. 布尔值类型:BOOLEAN

  2. 整型:INTEGER

  3. 字符串:OCTET STRING

  4. 空:NULL

结构类型又称为复合类型,如

  1. 有序成员固定结构:SEQUENCE

  2. 无序成员固定结构:SET

1.1实战

通过一个实例我们看看怎样使用ASN.1。

我们先创建一个ASN1格式的schema,该schema表示用户信息,里面有用户名和用户描述。然后填写数据,将数据进行编解码。大家可以用https://asn1.io/asn1playground/default.aspx来做实验。

1.1.1schema

首先创建改结构对应的ASN.1描述。

--<ASN1.HugeInteger World-Schema.Rocket.range>--
World-Schema DEFINITIONS AUTOMATIC TAGS ::=
BEGINRocket ::= SEQUENCE       {name      UTF8String (SIZE(1..16)),message   UTF8String (SIZE(1..16))}
END

1.1.2设置数据

有了schema后,我们对该结构进行赋值,可以使用ASN.1格式或json格式赋值。

# ASN.1格式
value Rocket ::= {name "Falcon",message "hh"
}# Json
{"name":"Falcon","message":"hh"
}

1.1.3编码

然后我们将数据编码为需要的格式,如ber、der、per、uper、oer、coer、xml等,编码结果如下所示:

hh.PDU.ber

hh.PDU.der

hh.PDU.xml

链接: https://pan.baidu.com/s/1Zz8dJCErDe1Fiz57oQF4Pg  密码: 2wdr

1.1.4解码

我们尝试解码der文件,如果没有schema,解析的内容如下图所示:


如果有对应的schema,解析出的内容存放在txt或json中:

hh.PDU.der.json

hh.PDU.der.txt

链接: https://pan.baidu.com/s/1Zz8dJCErDe1Fiz57oQF4Pg  密码: 2wdr

1.2代码实现

如果用代码,如何实现上述功能呢?本次用php实现,大家需要安装https://github.com/fgrosse/PHPASN1。

代码主要包含4部分内容:

  1. 先对结构进行赋值

  2. 然后将数据进行der编码和base64编码

  3. 编写该结构对应的schema(这个其实可以放在最开始编写)

  4. 将编码后的数据进行解析(支持base64编码或der编码的数据),解析完成后,便可获取各个数据

<?php#namespace FG\Test\ASN1;namespace FG\Test\ASN1;use FG\ASN1\Identifier;
use FG\ASN1\TemplateParser;
use FG\ASN1\Universal\BitString;
use FG\ASN1\Universal\Integer;
use FG\ASN1\Universal\ObjectIdentifier;
use FG\ASN1\Universal\Sequence;
use FG\ASN1\Universal\Set;
use FG\ASN1\Universal\CharacterString;
use FG\ASN1\Universal\UTF8String;//use PHPUnit_Framework_TestCase;class TemplateParserTest //extends PHPUnit_Framework_TestCase
{public function testParseBase64(){#1.赋值$sequence = new Sequence(// new Set(//new ObjectIdentifier('ID Number'),new UTF8String("Falcon"),new UTF8String("hh")// ));#2.der编码后,做base64编码$data = base64_encode($sequence->getBinary());var_dump($sequence->getBinary(),$data);#3.schema结构$template = [Identifier::SEQUENCE => [// Identifier::SET => [//Identifier::OBJECT_IDENTIFIER,Identifier::UTF8_STRING,Identifier::UTF8_STRING,// ]]];#4.解析$parser = new TemplateParser();$object = $parser->parseBase64($data, $template);var_dump($object);var_dump("-------------");var_dump($object->getChildren()[0]->getContent());var_dump("-------------");//        $this->assertInstanceOf(Set::class, $object[0]);
//        $this->assertInstanceOf(ObjectIdentifier::class, $object[0][0]);
//        $this->assertInstanceOf(Sequence::class, $object[0][1]);
//        $this->assertInstanceOf(Integer::class, $object[0][1][0]);
//        $this->assertInstanceOf(BitString::class, $object[0][1][1]);$object = $parser->parseBinary($sequence->getBinary(),$template);var_dump($object);}
}
require_once __DIR__ . '/vendor/autoload.php';
$parse = new TemplateParserTest();
$parse->testParseBase64();

输出如下:

➜  myproject php asn1.php
string(14) "0Falconhh"
string(20) "MAwMBkZhbGNvbgwCaGg="
object(FG\ASN1\Universal\Sequence)#8 (4) {["children":protected]=>array(2) {[0]=>object(FG\ASN1\Universal\UTF8String)#9 (5) {["value":protected]=>string(6) "Falcon"["checkStringForIllegalChars":"FG\ASN1\AbstractString":private]=>bool(false)["allowedCharacters":"FG\ASN1\AbstractString":private]=>array(0) {}["contentLength":"FG\ASN1\ASNObject":private]=>int(6)["nrOfLengthOctets":"FG\ASN1\ASNObject":private]=>int(1)}[1]=>object(FG\ASN1\Universal\UTF8String)#10 (5) {["value":protected]=>string(2) "hh"["checkStringForIllegalChars":"FG\ASN1\AbstractString":private]=>bool(false)["allowedCharacters":"FG\ASN1\AbstractString":private]=>array(0) {}["contentLength":"FG\ASN1\ASNObject":private]=>int(2)["nrOfLengthOctets":"FG\ASN1\ASNObject":private]=>int(1)}}["iteratorPosition":"FG\ASN1\Construct":private]=>int(2)["contentLength":"FG\ASN1\ASNObject":private]=>int(12)["nrOfLengthOctets":"FG\ASN1\ASNObject":private]=>int(1)
}
string(13) "-------------"
string(6) "Falcon"
string(13) "-------------"
object(FG\ASN1\Universal\Sequence)#11 (4) {["children":protected]=>array(2) {[0]=>object(FG\ASN1\Universal\UTF8String)#12 (5) {["value":protected]=>string(6) "Falcon"["checkStringForIllegalChars":"FG\ASN1\AbstractString":private]=>bool(false)["allowedCharacters":"FG\ASN1\AbstractString":private]=>array(0) {}["contentLength":"FG\ASN1\ASNObject":private]=>int(6)["nrOfLengthOctets":"FG\ASN1\ASNObject":private]=>int(1)}[1]=>object(FG\ASN1\Universal\UTF8String)#13 (5) {["value":protected]=>string(2) "hh"["checkStringForIllegalChars":"FG\ASN1\AbstractString":private]=>bool(false)["allowedCharacters":"FG\ASN1\AbstractString":private]=>array(0) {}["contentLength":"FG\ASN1\ASNObject":private]=>int(2)["nrOfLengthOctets":"FG\ASN1\ASNObject":private]=>int(1)}}["iteratorPosition":"FG\ASN1\Construct":private]=>int(2)["contentLength":"FG\ASN1\ASNObject":private]=>int(12)["nrOfLengthOctets":"FG\ASN1\ASNObject":private]=>int(1)
}

二、编码规则

ASN.1应用越来越广泛的主要原因之一是这种抽象文法描述与几种标准化编码规则联系在一起。这些编码规则规定了如何在非传输介质下实现ASN.1定义的数据类型与字节流的相互转换。因为编码规则是针对ASN.1的数据类型而制定的,因此可以称这些编码规则为ASN.1的编码规则。

ASN.1的编码规则是把使用ASN.1语言说明的数据转化成一种标准格式的系列规则,同时,保证转换后的数据在任意操作系统中,只要使用相同编码规则的解码器就可以解码获得原始数据。

目前,ASN.1的标准化编码规则有以下几种:BER(Basic Encoding Rules),DER(Distinguished Encoding Rules),PER(Packed Encoding Rules)和CER(Canonical Encoding Rules)等。我们简单介绍一下BER(基本编码规则)和DER(定长编码规则)。

2.1BER

BER编码信息由以下几部分组成:

① 标识串,表示要编码的 ASN.1 类型的标识类和标识码以及使用的编码方法(是简单型还是结构型)。

② 长度串,定长型编码方法中它表示内容串的长度,非定长编码方法中它表示长度不定。

③ 内容串,简单定长型编码方法中它表示要编码类型值的具体内容,结构型编码方法中表示各个成员编码的串联。

④ 内容结束串,只有在结构非定长型编码方法中表示内容串的结束,其他方法中该串省略。

对一个 ASN.1 对象的 BER 编码有三种模式,使用哪一种模式取决于该对象的类型和该类型数据的长度是否已知,

不同模式下编码信息中每个组成部分的编码规则不同。主要为基本类型定长模式、结构类型定长模式、结构类型非定长模式。

hh.PDU.ber

链接: https://pan.baidu.com/s/1Zz8dJCErDe1Fiz57oQF4Pg  密码: 2wdr

2.2DER

DER编码是ASN.1数据类型中具有唯一编码的编码规则。DER编码是BER编码的子集,是将每一个ASN.1抽象对象

类型表示成唯一的1和0码字符串的编码规则。这种编码规则是为需要编码成唯一比特串的应用系统而制定的,特

别是在应用安全技术的应用系统中,由于安全加密技术要求输入数据是字节流的形式,并且是与原数据唯一对应的

字节流,因此需要使用DER编码来实现数据结构的编码。

DER编码称为有关安全技术的应用系统的最佳选择。它基本上继承了BER编码规则,同样,也有三种编码方法。但

为了保证编码结果的唯一性,DER 编码在 BER 编码规则的基础上又附加了一些规则:

① 必须使用定长模式编码。

② 对于内容长度小于127的类型值,长度串编码必须采用短型。

③ 对于内容长度大于128的类型值,长度串编码必须采用长型,同时长度串编码的字节个数必须是最少的。

④ 对于简单字符串类型和从简单字符串类型通过隐式派生得到的类型,必须使用基本类型定长模式编码方法。

⑤ 对于结构类型、从结构类型通过隐式派生得到的类型,以及从任何类型通过显示派生得到的类型,必须使用结

构类型定长模式编码方法。

hh.PDU.der

链接: https://pan.baidu.com/s/1Zz8dJCErDe1Fiz57oQF4Pg  密码: 2wdr

如果Name类型ASN.1描述如下图:

将数据使用基本类型定长模式编码后的结果为:

三、使用

现在很多内容都使用ASN.1描述,如密码算法、数字证书等。

3.1密码算法ASN.1描述

PKCS #7 v1.5描述了密码消息的通用语法。该语法允许嵌套,如一个数字信封可以包含另一个数字信封,或可以对已做数字信封的数据进行签名;该语法也允许扩展各种属性,还可以用于分发证书和CRL。PKCS #7与PEM兼容,可以直接将加密的消息转换成PEM消息,反之亦然。PKCS #7支持多种基于证书的管理系统,PEM就是其中之一。在RFC 5652中有增强定义。该标准主要包括消息通用语法和6种内容类型(明文、签名、信封、签名信封、摘要、密文)。

① 消息通用语法用ASN.1描述如下:Contentlnfo::= SEQUENCE{contentType ContentType,content[0] EXPLICIT ANY DEFINED BY contentType OPTIONAL}ContentType:= OBJECT IDENTIFIER② 明文消息内容用ASN.1描述如下:Data ::= OCTET STRNG③ 签名消息内容用ASN.1描述如下:SignedData ::= SEQUENCE {version Version,digestAlgorithms DigestAlgorithmldentifiers,contentInfo Contentlnfo,certificates [0] IMPLICIT ExtendedCertificatesAndCertificatesOPTIONAL,Crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,signerlnfos Signerlnfos}DigestAlgorithmldentifiers ::= SET OF DigestAlgorithmldentifierSignerlnfos ::= SET OF SignerlnfoSignerlnfo ::= SEQUENCE {version Version,issuerAndSeriaINumber IssuerAndSerialNumber,digestAlgorithm DigestAlgorithmldentifier,authenticatedAttributes [0] IMPLICIT Attributes OPTIONA L,digestEncryptionAlgorithm DigestEncryptionAIgorithmldentitler,encryptedDigest EncryptedDigest,unauthenticatedAttributes [1] IMPLJC.IT Attributes OPTIONAL}EncryptedDigest ::= OC.TET STRINGDigestlnfo ::= SEQUENCE {digestAlgorithum DigestAlgorithmldentifier,digest Digest}Digest ::= OCTET STRING④ 信封消息内容用ASN.1描述如下:EnvelopedData ::= SEQUENCE {version Version,recipientlnfos Recipientlnfos.encryptedContentlnfo EncryptedContentlnfo}Recipientlnlos ::= SET OF RecipientlnfoEncryptedContentInfo ::= SEQUENCE {contentType ContentType,contentEncryptionAlgorithmContentEncryptionAlgorithmldentifier,encryptedContent [0] IMPLICLT EncryptedContent OPTIONAL}EncryptcdContenr ::= OCTET STRINGRecipientlnfo ::= SEQUENCE {version Version,issuerAndSerialNumber IssuerAndSerialNumber,keyEncryptionAlgorithmKeyEncryptionAlgorithmldentifier,encryptedKey EncryptedKey}EncryptedKey ::= OCTET STRING⑤ 签名信封消息内容用 ASN.1描述如下:SignedAndEnvelopedData ::= SEQUENCE {version Version,recipientlnfos Recipientlnfos,digestAlgorithms DigestAlgorithmldetifiers,encryptedContentlnfo EncryptedComentlnfo,certificates [0] IMPLICIT ExtendedCertificatesAndCertificatesOPTIONAL,Crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,signerlnfos Signerlnfos}⑥ 摘要消息内容用 ASN.1描述如下:DigestedData ::= SEQUENCE{version Version,digestAlgorithm DigestAlgorithmldentifier,contentlnfo Contentlnfo,digest Digest}Digest ::= OCTET STRING⑦ 密文消息内容用ASN.1描述如下:EncryptedData ::= SEQUENCE {version Version,encryptedContentlnfo EncryptedContentlnfo}

3.2数字证书ASN.1描述

X.509数字证书用ASN.1描述如下:

 Certificate ::= SEQUENCE {tbsCertificate TBSCertificate,signatureAlgorithm AlgorithmIdentifier,signature BIT STRING}TBSCertificate ::= SEQUENCE {version [0] EXPLICIT Version DEFAULT v1,serialNumber CertificateSerialNumber,signature AlgorithmIdentifier,issuer Name,validity Validity,subject Name,subjectPublicKeyInfo SubjectPublicKeyInfo,issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,-- If present, version must be v2or v3subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,-- If present, version must be v2or v3extensions [3] EXPLICIT Extensions OPTIONAL-- If present, version must be v3}Version ::= INTEGER {v1(0), v2(1), v3(2)}CertificateSerialNumber ::= INTEGERValidity ::= SEQUENCE {notBefore CertificateValidityDate,notAfter CertificateValidityDate}CertificateValidityDate ::= CHOICE {utcTime UTCTime,generalTime GeneralizedTime}UniqueIdentifier ::= BIT STRINGSubjectPublicKeyInfo ::= SEQUENCE {algorithm AlgorithmIdentifier,subjectPublicKey BIT STRING}Extensions ::= SEQUENCE OF ExtensionExtension ::= SEQUENCE {extnID OBJECT IDENTIFIER,critical BOOLEAN DEFAULT FALSE,extnValue OCTET STRING}

四、总结

通过这篇文章,大家应该能够了解ASN.1的价值和使用方法。

发送/接受方或标准化组织等制定好对应的schema,使用方按照该schema进行赋值,然后将数据转换为ber、der等格式,接收方根据指定的schema进行解析,就能获取到对应数据。

五、资料

  1. ASN.1格式数据编解码总结

  2. ASN.1描述与实例

  3. ASN.1编码方式详解

  4. Golang asn1.Marshal函数代码示例

  5. 高效的5G ASN.1编解码工具

  6. 网页版ASN1解码工具使用教程

  7. https://asn1.io/asn1playground/

  8. 如何解析ASN.1值表示法格式

  9. Go - 解码/编码asn.1

  10. PHPASN1:一个PHP库,用于使用ITU-T X.690编码规则对任意ASN.1结构进行编码和解码-源码下载

  11. php asn.1,A PHP library to encode and decode arbitrary ASN.1 structures using ITU-T X.690 encoding r…

  12. GitHub - fgrosse/PHPASN1: A PHP library to encode and decode arbitrary ASN.1 structures using ITU-T

  13. ThinkPHP5——引用vendor或extend里的第三方类(多种方法)

  14. PKCS规范

  15. x509及其ASN.1表示法

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

我的个人博客为:https://shidawuhen.github.io/

往期文章回顾:

  1. 设计模式

  2. 招聘

  3. 思考

  4. 存储

  5. 算法系列

  6. 读书笔记

  7. 小工具

  8. 架构

  9. 网络

  10. Go语言

来了解一下ASN.1?相关推荐

  1. ASN.1简介及OpenSSL中ASN.1接口使用举例

    ASN.1(Abstract Syntax Notation One)是一套标准,是描述数据的表示.编码传输.解码的灵活的记法.它提供了一套正式.无歧义和精确的规则以描述独立于特定计算机硬件的对象结构 ...

  2. ASN.1 Editor

    ASN.1 Editor By Liping Dai, 1 Jul 2008 官方已经无人维护了,我修改了一些bug放在github上.(欢迎star) https://github.com/jift ...

  3. 0X8009310B (ASN:276) win7安装证书时出现错误消息:找不到与此证书文件相关联的证书申请微软官方文档

    原文:http://support.microsoft.com/kb/959216#top 您尝试通过使用 IIS 7.0 管理器安装证书时出现错误消息:"找不到与此证书文件相关联的证书申请 ...

  4. 熊猫直播P2P分享率优化(下):ASN组网

    本文来自熊猫直播基础研发部的投稿,是熊猫直播P2P分享率优化系列文章的第二篇,第一篇请访问这里.本文授权LiveVideoStack发布,重点展示了熊猫直播通过ASN组网提升P2P分享率的实践. 文 ...

  5. 查看pem证书的ASN数据结构的方法

    搞过的同学应该都弄过google 的keybox.xml,里面有google 的attestition key证书内容,类似如下: <Key algorithm="ecdsa" ...

  6. ASN.1编解码:asn1c-ORAN-E2AP编解码示例

    ASN.1编解码:asn1c-ORAN-E2AP编解码示例 荣涛 2021年9月2日 整体代码:https://gitee.com/rtoax/test/tree/master/ASN.1/asn1c ...

  7. ASN.1编解码:asn1c-ORAN-E2AP

    ASN.1编解码:asn1c-ORAN-E2AP 荣涛 2021年8月25日 前面的文档讲述了如何编译asn1c,如何选取合适的asn1c软件版本,及其简单使用方法.本文将对asn1c的详细使用进行介 ...

  8. ASN.1编解码:ORAN-E2AP分析

    ASN.1编解码:ORAN-E2AP分析 荣涛 2021年8月25日 rongtao@sylincom.com 前面的文档讲述了如何编译asn1c,如何选取合适的asn1c软件版本,及其简单使用方法. ...

  9. ASN.1编解码:asn1c、enber和unber

    ASN.1编解码:asn1c.enber和unber 荣涛 2021年8月24日 相关: ASN.1编解码:asn1c的版本分析-诺基亚 1. 编译安装 见之前的文档. 2. asn1c指令 asn1 ...

  10. ASN.1编解码:asn1c的版本分析-诺基亚

    ASN.1编解码:asn1c的版本分析 荣涛 2021年8月24日 前面两个文档,已经对 ASN.1 编码和 asn1c 的使用做出了详细说明,那么如何将 ASN.1编解码与编程 ASN.1编解码:a ...

最新文章

  1. ubuntu 14.04 双显卡安装NVIDIA GPU驱动+CUDA+编译配置caffe
  2. kubernetes集群搭建以及遇到的问题
  3. Intellij页面汉字乱码问题
  4. format函数使用matlab,Matlab基本函数-format函数
  5. TechEd2010
  6. 源码分析参考:Spider
  7. POJ 1113 Wall 求凸包
  8. 为何高于四次的方程没有根式解?
  9. background属性及其应用
  10. 关于使用JAVA进行MIB文件解析
  11. 学习SQL Server这一篇就够了
  12. 爱数私有云盘 AnyShare 部署(一)
  13. 图片识别,人脸识别,植物识别,花卉识别,签到小程序,借助百度AI智能识别功能实现图片识别,人脸识别小程序
  14. linux 中signal机制如何应用(一)
  15. ddns-go搭建ddns(动态域名解析)
  16. 12 道腾讯前端面试真题及答案整理
  17. 《Android源码设计模式解析与实战》读书笔记(十七)
  18. 思科:利用三层交换机实现vlan间路由
  19. FPGA verilog基本外设练习(六)- 以太网通信模块
  20. 【Linux】远程下载 Google Drive 文件方法

热门文章

  1. [转]条码打印机基本设置方法
  2. 没有管理经验,怎么当测试负责人?
  3. RabbitMQ初步学习(Mac)
  4. mac安装Kafka启动 模拟生产者消费者
  5. mysql long raw类型_ORACLE数据库中主要字段类型的读写例子(包括:Long、Raw、Blob)
  6. js9331模块板openwrt刷固件刷usb声卡插件
  7. 【dubbo系列】dubbo协议与http协议对比
  8. 破解企业服务支付难题,SaaS与支付如何深度融合?
  9. 蓝桥杯嵌入式——第七届省赛-模拟液位检测告警系统
  10. 中达优控触摸屏编程视频教程_触摸屏组态编程软件|中达优控触摸屏编程软件(YKBuilder)1.0 官方版_ - 极光下载站...