【问题标题】:PKCS11Interop Hash with SHA256 and Sign with RSA in two stepsPKCS11Interop Hash with SHA256 and Sign with RSA in two steps
【发布时间】:2018-10-20 17:56:22
【问题描述】:

我有两个应用程序,一个计算文档的 SHA-256 哈希值,另一个进行 RSA 签名。 尝试不同的事情后,我得出的结论是,制作 CKM_SHA256 然后制作 CKM_RSA_PKCS 与仅制作文档本身的 CKM_SHA256_RSA_PKCS 产生不同的结果。

所以我的问题是,这两种实现有什么区别? CKM_SHA256_RSA_PKCS 机制中的散列中添加了哪些信息,以生成完全不同的签名?

【问题讨论】:

    标签: rsa sha pkcs#11 pkcs11interop


    【解决方案1】:

    Mechanims CKM_SHA256_RSA_PKCS 做以下事情:

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

    在构建 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;
    }
    

    【讨论】:

    • 哇,这真的很有帮助!谢谢
    • @AlexanderPoschenrieder 如果它帮助您解决问题,请不要忘记将答案标记为已接受。
    猜你喜欢
    • 2020-10-29
    • 2021-05-14
    • 2017-11-02
    • 2022-12-26
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2022-12-02
    • 2020-04-19
    相关资源
    最近更新 更多