对象标识符(OBJECT IDENTIFIER, OID) 的编码规则

对象标识符(OBJECT IDENTIFIER, OID的编码规则

对象标识符类型

       对象标识符(OBJECT IDENTIFIER, OID)类型用层次的形式来表示标准规范.标识符树通过一个点分的十进制符号来定义,这个符号以组织,子部分然后是标准的类型和各自的子标识符开始.

       例如:MD5OID 是 1.2.840.113549.2.5   表示"iso(1) member-body (2) US (840) rsadsi(113549) digestAlgorithm (2) md5 (5)", 所以当解码程序看到这个OID,就知道是MD5散列.

       OID在公钥算法标准中很流行,它指出证书绑定了哪种散列算法同样,也有公钥算法,分组算法,和操作模式的OID它们是一种高效且可移植的表示数据包中所选算法的形式.

       OID的编码规则:

前两部分如果定义x.y, 那么它们将合成一个40*x y, 其余部分单独作一个节进行编码.
每个首先被分割最少数量的没有头零数7位数.这些数big-endian格式进行组织,并且一个接一个地组合成除了编码的最后一个节外,其他所有节的最高位(8)1.
     举例30331 128^2 108 128 123   分割成7位数(0x80){1,108,123}设置最高位后变成{129,236,123}.如果该只有一个7位数,那么最高0.

  

     MD5 OID的编码:

         1. 1.2.840.113549.2.5转换数组 {42, 840, 113549, 2, 5}.

         2. 然后将每个分割带有最高位的7位数{{0x2A},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}.

         3. 最后完整的编码 0x06 08 2A 86 48 86 F7 0D 02 05.

附:

       MD2:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04
                   10 || H.
      MD5:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04
                   10 || H.
      SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
      SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00
                   04 20 || H.
      SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00
                   04 30 || H.
      SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00
                      04 40 || H.

要在 OpenSSL 中加入自定义签名算法的 OID,可以使用以下步骤: 1. 定义 OID 值 将自定义签名算法的 OID 值定义为一个字符串,如 "1.2.3.4"。 2. 注册 OID 使用 `OBJ_create` 函数注册自定义签名算法的 OID,例如: ``` #include <openssl/obj_mac.h> #include <openssl/objects.h> #define CUSTOM_OID "1.2.3.4" void register_custom_oid() { int nid = OBJ_create(CUSTOM_OID, "custom_oid", "Custom OID"); if (nid == NID_undef) { // OID 注册失败 } } ``` 3. 实现签名函数 实现自定义签名算法的签名函数,例如: ``` #include <openssl/evp.h> int custom_sign(const unsigned char *data, size_t data_len, unsigned char *sig, size_t *sig_len, void *key) { // 签名实现 // 返回签名结果和长度,成功返回 1,失败返回 0 } ``` 4. 注册签名函数 使用 `EVP_PKEY_asn1_find_str` 函数查找自定义 OID 对应的签名函数,如果找不到则使用 `EVP_PKEY_asn1_add0` 函数注册自定义 OID 对应的签名函数,例如: ``` void register_custom_sign() { int nid = OBJ_txt2nid(CUSTOM_OID); if (nid == NID_undef) { // OID 未注册 register_custom_oid(); nid = OBJ_txt2nid(CUSTOM_OID); } if (EVP_PKEY_asn1_find_str(NULL, CUSTOM_OID, nid) == NULL) { EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_new(EVP_PKEY_RSA, 0); EVP_PKEY_meth_set_sign(pmeth, NULL, custom_sign); EVP_PKEY_asn1_add0(nid, 0, pmeth); } } ``` 5. 使用自定义签名算法 使用 `EVP_get_digestbyname` 函数获取自定义签名算法的 `EVP_MD` 结构体,使用 `EVP_DigestSignInit` 函数初始化签名上下文,使用 `EVP_DigestSign` 函数进行签名,例如: ``` #include <openssl/digest.h> void custom_sign_data(const unsigned char *data, size_t data_len, unsigned char *sig, size_t *sig_len, EVP_PKEY *key) { EVP_MD *md = EVP_get_digestbyname(CUSTOM_OID); EVP_MD_CTX *ctx = EVP_MD_CTX_new(); EVP_DigestSignInit(ctx, NULL, md, NULL, key); EVP_DigestSign(ctx, sig, sig_len, data, data_len); EVP_MD_CTX_free(ctx); } ``` 6. 解析签名 使用 `EVP_PKEY_verify_init` 函数初始化验签上下文,使用 `EVP_VerifyUpdate` 函数更新验签上下文,使用 `EVP_VerifyFinal` 函数进行验签,例如: ``` #include <openssl/evp.h> int custom_verify(const unsigned char *data, size_t data_len, const unsigned char *sig, size_t sig_len, void *key) { // 验签实现 // 返回验签结果,成功返回 1,失败返回 0 } void verify_custom_sign(const unsigned char *data, size_t data_len, const unsigned char *sig, size_t sig_len, EVP_PKEY *key) { int nid = OBJ_txt2nid(CUSTOM_OID); if (EVP_PKEY_asn1_find_str(NULL, CUSTOM_OID, nid) == NULL) { // OID 未注册 return; } EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_find(key->type); if (pmeth == NULL || pmeth->verify == NULL) { // 签名算法不支持验签 return; } EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(key, NULL); if (ctx == NULL) { // 上下文创建失败 return; } if (EVP_PKEY_verify_init(ctx) <= 0 || EVP_PKEY_CTX_set_signature_md(ctx, EVP_get_digestbyname(CUSTOM_OID)) <= 0 || EVP_PKEY_verify(ctx, sig, sig_len, data, data_len) <= 0) { // 验签失败 } EVP_PKEY_CTX_free(ctx); } ``` 注意,以上代码仅供参考,需要根据实际情况进行修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值