ASN1编解码

2023-10-27

ASN1编码

ASN.1(Abstract Syntax Notation One)是一种用于描述数据结构和编码规则的标记语言,它广泛应用于网络通信、加密和安全领域。ASN.1 定义了一种独立于具体编程语言的数据表示方法,可以确保不同计算机系统之间的数据交换的正确性和一致性。

ASN.1 编码的主要用途包括:

数据结构描述:ASN.1 提供了一种形式化的语法来描述复杂的数据结构,包括记录、序列、集合、数组等。这使得不同系统之间能够对数据结构进行准确的定义和解释,确保数据在传输和存储过程中不会出现歧义。

数据编码和解码:ASN.1 定义了多种编码规则,如基于二进制的 BER(Basic Encoding Rules)、DER(Distinguished Encoding Rules)、CER(Canonical Encoding Rules)等,以及基于 XML 的 XER(XML Encoding Rules)。ASN.1 编码规则将数据结构转换为字节流,方便在网络中传输和存储,并能够实现跨平台和跨语言的数据交换。

网络通信和协议定义:ASN.1 用于定义许多通信协议的数据格式,如 SNMP 数据包格式、LDAP 数据格式、X.509 证书、PKCS 密钥和证书等。ASN.1 的描述能力使得网络通信中的数据格式得以准确定义,并且能够方便地解析和处理。

安全和加密:ASN.1 用于描述和编码数字证书、公钥、私钥等安全相关的数据结构。ASN.1 结合公钥基础设施(PKI)和加密算法,可以支持诸如 SSL/TLS、SSH 和数字签名等安全通信协议,确保数据的机密性、完整性和身份验证。

总之,ASN.1 编码在网络通信、安全、加密以及协议定义等领域发挥着重要作用,通过提供统一的数据描述和编码规则,实现了不同系统间的数据交换和互操作。

数据类型

BIT STRING 位或二进制字符串是任意长度的位数组
BOOLEAN TRUE 或 FALSE
INTEGER 整数
Null
OBJECT 对象标识符
OCTET_STRING 八进制字符串是任意大的字节数组

字符串类型

BMPString
IA5String 国际字母数字 5 (IA5) 通常等效于 ASCII 字母表
PrintableString 可用于大型机输入终端的有限字符集
TeletexString
UTF8String 8 位 UCS/Unicode 转换格式 (UTF-8) 是一种长度可变的字符编码,可以将任何通用字符表示为 Unicode 字符,同时允许初始码位与 ASCII 保持一致

构造类型

SEQUENCE 和 SEQUENCE OF 包含一个或多个类型的有序字段系列 字段可以标记为OPTIONAL 或 DEFAULT

SET 和 SET OF	包含一个或多个类型的无序字段系列
X509.h
ASN1_INTEGER: 表示 ASN.1 编码中的整数类型。
ASN1_ENUMERATED: 表示 ASN.1 编码中的枚举类型。
ASN1_BIT_STRING: 表示 ASN.1 编码中的位串类型。
ASN1_OCTET_STRING: 表示 ASN.1 编码中的八位字节串类型。
ASN1_PRINTABLESTRING: 表示 ASN.1 编码中的可打印字符串类型。
ASN1_T61STRING: 表示 ASN.1 编码中的 T.61 字符串类型。
ASN1_IA5STRING: 表示 ASN.1 编码中的 IA5 字符串类型。
ASN1_GENERALSTRING: 表示 ASN.1 编码中的通用字符串类型。
ASN1_UNIVERSALSTRING: 表示 ASN.1 编码中的通用字符串类型。
ASN1_BMPSTRING: 表示 ASN.1 编码中的 BMP 字符串类型。
ASN1_UTCTIME: 表示 ASN.1 编码中的 UTC 时间类型。
ASN1_TIME: 表示 ASN.1 编码中的时间类型。
ASN1_GENERALIZEDTIME: 表示 ASN.1 编码中的广义时间类型。
ASN1_VISIBLESTRING: 表示 ASN.1 编码中的可见字符串类型。
ASN1_UTF8STRING: 表示 ASN.1 编码中的 UTF-8 字符串类型。
ASN1_STRING: 表示 ASN.1 编码中的字符串类型。
其他常用
X509_ALGOR 算法标识

ASN1方法

ASN1_SEQUENCE 结构体定义

是一种宏定义,用于表示 ASN.1 编码中的序列类型

例子
ASN1_SEQUENCE 宏通常用于定义 ASN.1 编码中的序列类型,并将其映射到相应的结构体类型。以下是使用 ASN1_SEQUENCE 宏的一般步骤:

引入相关的头文件和库:首先,确保引入了适当的头文件和库,以便使用 ASN.1 编码和解码相关的函数和类型。

定义结构体类型:使用 ASN1_SEQUENCE 宏定义结构体类型,该结构体类型将表示 ASN.1 序列的字段和成员。在序列中每个字段都可以使用 ASN1_SIMPLE 宏进行定义,指定字段名称、字段类型和字段标签。

typedef struct {
  ASN1_INTEGER field1;
  ASN1_OCTET_STRING field2;
} MySequence;

ASN1_SEQUENCE(MySequence) = {
  ASN1_SIMPLE(MySequence, field1, ASN1_INTEGER),
  ASN1_SIMPLE(MySequence, field2, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END(MySequence);
DECLARE_ASN1_FUNCTIONS(MySequence);//头文件声明ASN1_SEQUENCE_END的函数
DEFINE_STACK_OF()//用于创建堆栈结构

DEFINE_STACK_OF(X509);
STACK_OF(X509) *certStack;  // 声明一个存储 X509 证书的堆栈对象

在上述示例中,定义了一个名为 MySequence 的结构体类型,其中包含两个字段 field1 和 field2,分别是 ASN1_INTEGER 类型和 ASN1_OCTET_STRING 类型。
编码和解码操作:使用提供的 ASN.1 编码和解码函数对 ASN.1 序列进行编码和解码操作。这些函数通常接受结构体类型的实例作为参数,并根据 ASN.1 规范将其转换为相应的二进制编码或解析二进制编码为结构体类型的实例。
例如,ASN.1 编码函数可能是 i2d_MySequence,用于将 MySequence 类型的实例编码为二进制数据。ASN.1 解码函数可能是 d2i_MySequence,用于将二进制数据解码为 MySequence 类型的实例。
这样,通过使用 ASN1_SEQUENCE 宏定义结构体类型,并使用相应的编码和解码函数,可以方便地进行 ASN.1 编码和解码操作,以便处理和传输符合 ASN.1 规范的数据。

ASN1_SIMPLE 用于定义 ASN.1 编码中的简单类型字段(整数,字符串)。针对 ASN.1 编码的数据传输、存储和处理。
编码:将结构体类型的实例编码为符合 ASN.1 标准的二进制数据。可以使用 OpenSSL 提供的编码函数(例如 i2d_MyStructure)将结构体实例转换为 ASN.1 编码的二进制数据。这是在数据传输和存储中常用的操作,以便将结构化数据转化为可传输的二进制形式。
解码:将 ASN.1 编码的二进制数据解码为对应的结构体类型的实例。使用 OpenSSL 提供的解码函数(例如 d2i_MyStructure)可以将二进制数据解析为结构体实例,以便进行进一步的处理和操作。

ASN1_SIMPLE(type, field, fieldtype)
type:定义包含字段的结构体类型。
field:字段名称。
fieldtype:字段的类型,通常是 ASN.1 中定义的简单类型。

IMPLEMENT_ASN1_FUNCTIONS 编码的结构体的方法定义

IMPLEMENT_ASN1_FUNCTIONS(X509_RSA_PUBLICKEY) 
是 OpenSSL 库中的宏,用于为 X509_RSA_PUBLICKEY 结构体类型实现 ASN.1 编码相关的函数。
这个宏会自动为 X509_RSA_PUBLICKEY 结构体类型生成以下函数:
X509_RSA_PUBLICKEY_new():创建一个新的 X509_RSA_PUBLICKEY 结构体实例,并分配内存空间。
X509_RSA_PUBLICKEY_free(x):释放 X509_RSA_PUBLICKEY 结构体实例 x 所占用的内存空间。
d2i_X509_RSA_PUBLICKEY(bp, x):从文件流 bp 中将 ASN.1 编码的 X509_RSA_PUBLICKEY 数据解码为 X509_RSA_PUBLICKEY 结构体实例 x。
i2d_X509_RSA_PUBLICKEY(bp, x):将 X509_RSA_PUBLICKEY 结构体实例 x 编码为 ASN.1 格式并写入文件流 bp。

使用 IMPLEMENT_ASN1_FUNCTIONS(X509_RSA_PUBLICKEY) 宏可以简化 ASN.1 编码和解码操作的实现。你可以在代码中使用这些生成的函数来处理 X509_RSA_PUBLICKEY 类型的数据,如创建该结构体的实例、释放内存、解码和编码数据。

i2d 表示 “internal to der” d2i 表示 “der to internal”(Der 编码解码为内部数据格式)

举例 编解码使用

#include <stdio.h>
#include <stdlib.h>
#include <openssl/asn1.h>

int main() {
    ASN1_INTEGER *asnInt = NULL;
    unsigned char *derData = NULL;
    int derLen;
    
    // 创建一个 ASN1_INTEGER 对象
    asnInt = ASN1_INTEGER_new();
    if (asnInt == NULL) {
        printf("Failed to create ASN1_INTEGER\n");
        return 1;
    }
    
    // 设置整数值
    ASN1_INTEGER_set(asnInt, 12345);
    
    // 编码 ASN1_INTEGER 为 ASN.1 DER 格式
    derLen = i2d_ASN1_INTEGER(asnInt, &derData);
    if (derLen < 0) {
        printf("Failed to encode ASN1_INTEGER\n");
        return 1;
    }
    
    // 可以将 derData 存储、传输等等操作
    // ...
    
    // 解码 ASN.1 DER 数据为 ASN1_INTEGER 对象
    asnInt = d2i_ASN1_INTEGER(NULL, (const unsigned char **)&derData, derLen);
    if (asnInt == NULL) {
        printf("Failed to decode ASN1_INTEGER\n");
        return 1;
    }
    
    // 从 ASN1_INTEGER 对象中获取整数值
    long value = ASN1_INTEGER_get(asnInt);
    printf("Decoded integer: %ld\n", value);
    
    // 释放相关资源
    ASN1_INTEGER_free(asnInt);
    free(derData);
    
    return 0;
}

常用函数

OpenSSL 库提供了许多用于数据转换的函数。以下是其中一些常用的转换函数:

BIGNUM 转换
BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); 将二进制数据转换为 BIGNUM 对象。

BN_bn2hex: 将 BIGNUM 对象转换为十六进制字符串。
BN_bn2dec: 将 BIGNUM 对象转换为十进制字符串。
BN_hex2bn: 将十六进制字符串转换为 BIGNUM 对象。
BN_dec2bn: 将十进制字符串转换为 BIGNUM 对象。
ASN.1 数据编码/解码

i2d_ASN1_INTEGER: 将 ASN1_INTEGER 对象编码为 ASN.1 DER 格式的数据。
d2i_ASN1_INTEGER: 将 ASN1_INTEGER 对象解码为 ASN.1 DER 格式的数据。
PEM 格式编码/解码

PEM_read_bio_PrivateKey: 从 BIO 中读取 PEM 格式的私钥。
PEM_write_bio_PrivateKey: 将私钥写入 BIO,以 PEM 格式保存。
PEM_read_bio_X509: 从 BIO 中读取 PEM 格式的 X.509 证书。
PEM_write_bio_X509: 将 X.509 证书写入 BIO,以 PEM 格式保存。
Base64 编码/解码

EVP_EncodeBlock: 将二进制数据编码为 Base64 字符串。
EVP_DecodeBlock: 将 Base64 字符串解码为二进制数据。
十六进制字符串转换

OPENSSL_hexstr2buf: 将十六进制字符串转换为二进制数据。
OPENSSL_buf2hexstr: 将二进制数据转换为十六进制字符串。
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
将 大数(BIGNUM)转换为 ASN.1 INTEGER 对象
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASN1编解码 的相关文章

  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • 如何在flutter中绕过SSL证书验证?

    如何在flutter中绕过SSL证书验证 错误 握手异常 客户端中的握手错误 操作系统错误 CERTIFICATE VERIFY FAILED 自签名证书 handshake cc 345 您需要配置 HttpService 以使用自签名
  • IIS 8 HTTPS/需要 SSL 导致超时错误

    尝试通过 IIS 8 通过 SSL 发布网站 但出现超时错误 任何帮助表示赞赏 采取的步骤 已验证该网站可以通过 HTTP 访问 http xxx xxx xxx xxx有效 此时使用 IP 地址 如果重要的话 IIS gt 服务器证书 g
  • 信任库是否需要子 ca 证书?

    我正在尝试设置分层 PKI 我是否可以创建仅包含根 ca 证书的信任库 这是否意味着我的应用程序信任由子 ca 证书签名的证书 而子 ca 证书又由根 ca 签名 顺便说一句 您似乎必须提供整个证书链 包括根 ca 证书 当然 如果根 ca
  • Facebook JavaScript SDK 通过 HTTPS 加载非安全项目

    我有一个 Facebook 应用程序 使用Facebook Connect js https connect facebook net en US all js 我正在通过 HTTPS 运行我的应用程序 网站上的所有内容均来自https 但
  • 在linux上安装python ssl模块,无需重新编译

    是否可以在已经安装了 OpenSSL 的 Linux 机器上安装 python 的 SSL 模块 而无需重新编译 python 我希望它就像复制几个文件并将它们包含在库路径中一样简单 Python版本是2 4 3 谢谢 是否可以在已经安装了
  • Azure 共享计划上的 SSL?

    我有 1 个网站 1 个数据库和 1 个 SSL 托管在 azure 上 我曾经拥有 基本 托管套餐 但每个月要支付 70 美元才能获得基本设置 并且所有内容都具有最小的缩放比例 我意识到我的低流量站点不需要专用计算机 因此我尝试转向共享计
  • 使用 DigitalOcean 在 Kubernetes 集群上为我的 Nginx-Ingress 生成通配符证书

    我遵循了这个 DigitalOcean 指南https www digitalocean com community tutorials how to set up an nginx ingress with cert manager on
  • 使用ssl和socket的python客户端身份验证

    我有一个 python 服务器 需要客户端使用证书进行身份验证 我如何制作一个客户端脚本 使用客户端证书由 python 中的服务器使用 ssl 和套接字模块进行身份验证 有没有仅使用套接字和 ssl 而不扭曲的示例 from OpenSS
  • SSL 速度:128 位与 256 位

    我决定使用 SSL 加密我的整个网站 即使实际上只有部分网站是必要的 最终结果是该网站现在有点慢 所以 我的问题是 我是否应该只加密网站的会员部分 请记住我在首页上有登录表单 我是否应该将加密降低到 128 位 如果站点总体较小 速度差异是
  • 使用 X509Certificate2 签署并验证 ECDSA-SHA256 签名

    I used OpenSSL使用创建 ECC 证书SHA256 现在我想使用这些证书来签署数据并验证现有签名 我尝试使用DSACryptoServiceProvider 但它只支持SHA1 or MD5 但似乎ECDsaCng能够支持ECD
  • 如何显示证书的主题备用名称?

    我发现的最接近的答案是使用 grep gt openssl x509 text noout in cert pem grep DNS 有更好的方法吗 我只喜欢命令行 Thanks 较新版本的 openssl 有一个 ext 选项 允许您仅打
  • node.js 我可以为同一个项目使用多个 ssl 证书和密钥吗?如何?

    我有我的贝宝 SSL 证书 https www webhostingtoolbox com kb how do i generate the needed ssl certificate for paypal ipn html对于为我的代码
  • 使用客户端 hello 消息进行 TLS 协议检测

    我需要检测网络流量中的 https 数据包 到目前为止 我将所有 443 标记为 https 但我不想再在这种情况下使用端口信息 检查客户端问候消息是否足够 Check 22 and version info 0300 0301 or 03
  • 如何在 IIS 中将 WCF 与 basichttpbinding only、SSL 和基本身份验证结合使用?

    是否可以仅使用 IIS 中的 SSL 和基本身份验证来设置 WCF 服务BasicHttpBinding binding 我无法使用wsHttpBinding binding 该站点托管在 IIS 7 上 并设置了以下身份验证 匿名访问 O
  • 带有客户端证书的android webview

    我尝试了几天使用嵌入在应用程序中的客户端证书的Web视图 但在我看来 android sdk没有提供任何方法来做到这一点 是否有回调来拦截服务器发送的质询 有没有办法将 webview 与客户端证书一起使用并发出 https 请求 因为我也
  • SMTP:无法连接套接字:无法找到套接字传输“ssl”

    我一直在尝试在 WAMP 上使用 Pear 发送电子邮件通过 GMail 花了几个小时将其全部设置并找出我遇到的所有错误后 我以为我已经很接近了 直到我开始收到此错误 Failed to connect to ssl smtp gmail
  • Google Firebase SSL 证书 - 我的证书列出了大量其他网站

    问题 我的 Google Firebase SSL 证书中列出了其他域 我创建了一个 firebase 项目来测试来自 Cloud Functions 的 firebase 身份验证电子邮件 firebase jhanley com htt
  • 在 SSLwrapp() 之前在原始套接字上接收/发送,Python

    我想知道在包装原始套接字之前是否可以在原始套接字上接收 发送数据 我已经查看了文档并搜索了它 但找不到任何具体内容 我基本上想做的事情 client addr listeningSocket accept client recv 32 cl
  • 如何使用自签名证书为 TLS 创建 iOS NWConnection?

    我正在尝试将 Apple 的新 NWConnection 类用于我的 MQTT 客户端 为了进行测试 我需要能够创建到本地测试代理的 TLS 连接 该代理具有自签名证书 到目前为止 我只是使用以下命令设置连接 self connection

随机推荐

  • 【Git】Git国内官网下载地址、淘宝镜像下载地址以及卸载安装

    Git官网下载地址 打开官网Git git scm com 进行相对应的操作系统下载即可 官网下载速度 大约需要二十多分钟 2 国内镜像 淘宝 Git下载国内镜像地址 CNPM Binaries Mirror npmmirror com G
  • 5 个有用的 Mac 终端技巧

    深藏在你的Mac 漂亮的界面下面是一个有几十年历史的叫做 UNIX 的骨干 你可以使用它的老式终端来运行无法从应用程序或菜单访问的简单命令 这些不仅对开发人员和黑客有用 即使您以前从未深入研究过终端 也有一些调整可以让您的 Mac 变得更好
  • Linux centos8安装redis

    centos 8 0 redis 安装教程 1 将安装包上传到指定目录 我这里放在 usr local src 目录 2 进入 usr local src 目录 cd usr local src 3 解压源码包 tar zxvf redis
  • hive使基本使用

    文章目录 1 hive创建表 2 查看建表语句 2 hive使用load加载数据到表中 3 hive删除表数据 4 hive查看版本信息 1 hive创建表 0 jdbc hive2 10 0 xxx 162 10000 default g
  • 网络编程 详解

    概述 计算机网络 将不同地理区域的计算机 广义 通过通信线路 光纤 连接起来 通过功能完备的软件实现数据共享 信息传递 网络编程 使程序借助网络在不同计算机间传输数据 Java提供的网络类库 可以实现网络连接 且Java支持网络传输 2 网
  • 你真的会开发测试框架?

    基本概念 库 英文单词叫Library 库是由代码集合成的一个产品 供程序员调用 面向对象的代码组织形成的库叫类库 面向过程的代码组织形成的库叫函数库 框架 英文单词叫Framework 框架是为解决一个或一类问题而开发的产品 用户一般只需
  • 【简单又详细】Unity实现拖拽3D物体旋转,UI面板显示角色

    预览效果 一 创建环境 1 创建一个Panel 把人物放到Panel之下 2 创建一个Camera命名为UICamera UICamera相机添加 physics RayCaster组件 修改遮罩层级 UI 注意 把player的层级也改为
  • windows10下安装docker,并且安装ubuntu环境

    1 系统要求 支持 64 位版本的 Windows 10 Pro 且必须开启 Hyper V 若版本为 v2004 及以上则无需开启 Hyper V 或者 64 位版本的 Windows 10 Home v2004 及以上版本 我的版本 w
  • 如何用一篇文章生成知识图谱

    https www zhihu com question 355473263
  • sockjs-web实时通信协议

    sockjs web实时通信应用解决方案 socksjs 客户端和服务器端api尽可能简洁 尽量靠近websocket api 支持服务端扩展和负载均衡技术 传输层应该全面支持跨域通信 如果受到代理服务器的限制 传输层能优雅地从一种方式回退
  • Unity图集相关问题

    Unity图集相关问题 前言 最近查找图集相关资料的时候看到了Unity论坛上的一篇帖子 其中Unity官方技术人员解释了 Include In Build 究竟有什么作用 Include In Build 简而言之 如果勾选了 就意味着S
  • Centos7.x安装netcat以及netcat连接被拒绝(Ncat: Connection refused.)或者没有反应的解决方法

    一 情况 出现以下情况 Jay localhost001 nc Ncat You must specify a host to connect to QUITTING 或是 Jay localhost002 nc localhost001
  • 统计海量文章内容中出现次数前K大的单词并输出(完整实现)

    统计海量文章内容中出现次数前K大的单词并输出 很经典的问题 解决思路如下 1 遍历所有单词 利用hashmap来统计每一个单词出现的值 得到hashmap示例如下 key value a 3 bc 1 cd 8 2 这时候 问题变成了在海量
  • 代码审计-工具介绍及简单思路

    工具篇之开发环境 仅供参考 0x01 PhpStorm PhpStorm 是 JetBrains 公司开发的一款商业的 PHP 集成开发工具 旨在提高用户效率 可深刻理解用户的编码 提供智能代码补全 快速导航以及即时错误检查 是一个非常不错
  • 基于SpringBoot的器材管理系统

    介绍 有一家实验室 里面有100台实验设备 5个实验员 每个设备使用之前需要对设备进行检查 现在存在以下痛点 实验员检查器材的时候 发现器材不见了 他们都不知道器材是坏了还是其他实验员用到其他器材 非常不方便 希望开发一套软件进行器材的借
  • python写一个实时语音转文字得方法

    可以使用第三方库 SpeechRecognition 进行实时语音识别 首先需要安装这个库 然后可以使用如下代码进行实时语音转文字 import speech recognitionas sr 创建语音识别对象 r sr Recognize
  • Python制作GUI学生管理系统毕设,大学生总会用得到

    有很多可爱的大学生跟我吐槽 咋这个大学跟我想象的不一样呢 老师叫我们自己做 还是那句话 技术才是硬道理 源码 资料电子书文末名片获取 有个经典案例就是 学生管理系统 写完了放在那也是放着 所以今天分享给大家吧 话不多说 咱们直接开始吧 代码
  • redhat6安装mysql8.0.33

    1 下载mysql 官网地址 https downloads mysql com archives community 下载步骤 过滤操作系统版本 下载后 上传到服务器Downloads目录 2 安装mysql8 解压压缩包 tar xvf
  • 背景减除法的研究

    本篇对背景减除法做了一个全面的分析与比较 首先 按照数学模型的不同 把背景减除法分为六大类 然后 在每一类中选取了一些经典的 有代表性的算法进行介绍 最后 通过理论研究与实验比较 从准确性 鲁棒性 内存需求和计算速度的角度 指出了这些种背景
  • ASN1编解码

    ASN1编码 ASN 1 Abstract Syntax Notation One 是一种用于描述数据结构和编码规则的标记语言 它广泛应用于网络通信 加密和安全领域 ASN 1 定义了一种独立于具体编程语言的数据表示方法 可以确保不同计算机