使用PKCS11Interop进行SHA256哈希并分两步使用RSA签名

7
我有两个应用程序,一个计算文档的SHA-256哈希值,另一个进行RSA签名。尝试了一些不同的方法后,我得出结论:使用CKM_SHA256然后使用CKM_RSA_PKCS与仅对文档本身进行CKM_SHA256_RSA_PKCS会产生不同的结果。
所以我的问题是,这两种实现之间有什么区别?在CKM_SHA256_RSA_PKCS机制中添加了哪些信息,以致于会产生完全不同的签名?
1个回答

10

Mechanims CKM_SHA256_RSA_PKCS 的作用如下:

  1. 类似于 CKM_SHA256,计算数据的 SHA256 哈希值
  2. 构造在RFC 8017中定义的 DER 编码的 DigestInfo 结构
  3. CKM_RSA_PKCS 一样使用私钥对 DigestInfo 结构进行签名

在构建 DER 编码的 DigestInfo 结构时,有多种方法可行:

  1. Pkcs11Admin 应用程序中,我使用了 BouncyCastle 库:
public static byte[] CreateDigestInfo(byte[] hash, string hashOid)
{
    DerObjectIdentifier derObjectIdentifier = new DerObjectIdentifier(hashOid);
    AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(derObjectIdentifier, null);
    DigestInfo digestInfo = new DigestInfo(algorithmIdentifier, hash);
    return digestInfo.GetDerEncoded();
}
  1. Pkcs11Interop.X509Store库中,我使用了预先计算好的数组:
/// <summary>
/// Creates DER encoded PKCS#1 DigestInfo structure defined in RFC 8017
/// </summary>
/// <param name="hash">Hash value</param>
/// <param name="hashAlgorithm">Hash algorithm</param>
/// <returns>DER encoded PKCS#1 DigestInfo structure or null</returns>
private static byte[] CreatePkcs1DigestInfo(byte[] hash, HashAlgorithmName hashAlgorithm)
{
    if (hash == null || hash.Length == 0)
        throw new ArgumentNullException(nameof(hash));

    byte[] pkcs1DigestInfo = null;

    if (hashAlgorithm == HashAlgorithmName.MD5)
    {
        if (hash.Length != 16)
            throw new ArgumentException("Invalid lenght of hash value");

        pkcs1DigestInfo = new byte[] { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
    }
    else if (hashAlgorithm == HashAlgorithmName.SHA1)
    {
        if (hash.Length != 20)
            throw new ArgumentException("Invalid lenght of hash value");

        pkcs1DigestInfo = new byte[] { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
    }
    else if (hashAlgorithm == HashAlgorithmName.SHA256)
    {
        if (hash.Length != 32)
            throw new ArgumentException("Invalid lenght of hash value");

        pkcs1DigestInfo = new byte[] { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
    }
    else if (hashAlgorithm == HashAlgorithmName.SHA384)
    {
        if (hash.Length != 48)
            throw new ArgumentException("Invalid lenght of hash value");

        pkcs1DigestInfo = new byte[] { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
    }
    else if (hashAlgorithm == HashAlgorithmName.SHA512)
    {
        if (hash.Length != 64)
            throw new ArgumentException("Invalid lenght of hash value");

        pkcs1DigestInfo = new byte[] { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        Array.Copy(hash, 0, pkcs1DigestInfo, pkcs1DigestInfo.Length - hash.Length, hash.Length);
    }

    return pkcs1DigestInfo;
}

1
哇,那真是太有帮助了!谢谢。 - Alexander Poschenrieder
@AlexanderPoschenrieder 如果这个答案帮助您解决了问题,请不要忘记将其标记为已接受的答案。 - jariq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接