SHA-512和SHA-256的ASN.1 OID前缀区别

SHA-512SHA-256 的 ASN.1 OID(Object Identifier)前缀的详细对比,包括它们的结构差异、DER 编码以及实际应用中的注意事项。

1. ASN.1 OID 定义对比

SHA-256
  • OID: 2.16.840.1.101.3.4.2.1

DER 编码(19字节):

30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
  • 哈希长度标识04 20(表示哈希值长度为 32字节)。
SHA-512
  • OID: 2.16.840.1.101.3.4.2.3

DER 编码(19字节):

30 51 30 0D 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40
  • 哈希长度标识04 40(表示哈希值长度为 64字节)。

2. 关键区别

字段

SHA-256

SHA-512

OID 值

2.16.840.1.101.3.4.2.1

2.16.840.1.101.3.4.2.3

DER 编码

30 31...04 20

30 51...04 40

总长度

19 字节

19 字节

哈希长度标识

04 20(32字节)

04 40(64字节)

OID 部分差异

最后一位 01

最后一位 03

3. 代码实现(C语言硬编码)

SHA-256 的 ASN.1 OID
const unsigned char SHA256_ASN1_OID[] = {
    0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
    0x00, 0x04, 0x20
    };
SHA-512 的 ASN.1 OID
const unsigned char SHA512_ASN1_OID[] = {
    0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
    0x00, 0x04, 0x40
};

4. 在 PKCS#1 签名填充中的应用

SHA-256 填充示例
// PKCS#1 v1.5 签名填充(SHA-256)
void pad_with_sha256(const unsigned char *hash, unsigned char *padded) {
    const unsigned char SHA256_OID[] = { ... }; // 如上定义
    padded[0] = 0x00;
    padded[1] = 0x01;
    memset(padded + 2, 0xFF, padding_len); // 填充 0xFF
    padded[2 + padding_len] = 0x00;
    memcpy(padded + 3 + padding_len, SHA256_OID, 19); // 写入 ASN.1
    memcpy(padded + 22 + padding_len, hash, 32);      // 写入哈希值
}
SHA-512 填充示例
// PKCS#1 v1.5 签名填充(SHA-512)
void pad_with_sha512(const unsigned char *hash, unsigned char *padded) {
    const unsigned char SHA512_OID[] = { ... }; // 如上定义
    padded[0] = 0x00;
    padded[1] = 0x01;
    memset(padded + 2, 0xFF, padding_len); // 填充 0xFF
    padded[2 + padding_len] = 0x00;
    memcpy(padded + 3 + padding_len, SHA512_OID, 19); // 写入 ASN.1
    memcpy(padded + 22 + padding_len, hash, 64);      // 写入哈希值
}

5. 为什么长度标识不同?

  • 04 20(SHA-256):
    • 04 = OCTET STRING 标签。
    • 20 = 32字节(十六进制的 0x20 = 十进制的 32)。
  • 04 40(SHA-512):
    • 40 = 64字节(十六进制的 0x40 = 十进制的 64)。

6. 动态生成 ASN.1 OID(OpenSSL 示例)

#include <stdio.h>
#include <openssl/x509.h>
#include <openssl/evp.h>

void print_oid(const EVP_MD *md)
{
    X509_ALGOR *algor = X509_ALGOR_new();
    if (!algor)
    {
        printf("Error: X509_ALGOR_new failed.\n");
        return;
    }
    X509_ALGOR_set_md(algor, md);

    unsigned char *buf = NULL;
    int len = i2d_X509_ALGOR(algor, &buf); // DER 编码
    if (len <= 0)
    {
        printf("Error: i2d_X509_ALGOR failed.\n");
        X509_ALGOR_free(algor);
        return;
    }

    printf("OID (DER): ");
    for (int i = 0; i < len; i++)
    {
        printf("%02x ", buf[i]);
    }
    printf("\n");

    OPENSSL_free(buf);
    X509_ALGOR_free(algor);
}

// compile command: gcc sha_256_asn_1_oid.c -lcrypto
int main()
{
    // 初始化 OpenSSL(可选,但推荐)
    OpenSSL_add_all_algorithms();

    printf("SHA-256 OID: ");
    print_oid(EVP_sha256());

    printf("SHA-512 OID: ");
    print_oid(EVP_sha512());

    return 0;
}

7. 总结

  • SHA-256 和 SHA-512 的 ASN.1 OID 前缀长度相同(19字节),但以下部分不同:
    1. OID 的最后一个字节(01 vs 03)。
    2. 哈希长度标识(04 20 vs 04 40)。
  • 实际应用时
    • 硬编码 OID 需严格匹配哈希算法。
    • 签名和验签双方必须使用相同的 OID,否则会验证失败。

如果需要其他哈希算法(如 SHA-384)的 OID,可通过类似方式从 RFC 或 OpenSSL 中获取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值