当前位置: 首页 > 知识库问答 >
问题:

是否可以使用RSA SHA512对哈希进行签名?

顾梓
2023-03-14

我使用OpenSSL创建了一个自签名证书,如下所示:

然后,我在C#.NET4.0中编写了以下代码:

public static bool DSHandler(string operation, string path, string devicePath)
{
    bool result = false;
        CryptoConfig.AddAlgorithm(typeof(USBSaferAppEFB.RsaPkCs1Sha512SignatureDescription),
            "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512");
        string password = "xxxx";
        bool validSignature = false;
        byte[] hashchain = generateHash(path);
        string digSignFile = Utils.RegVarValue(DIGSIGNFILE);
        string subjectDN = Utils.RegVarValue(SUBJECTDN);

        if (operation == "sign")
        {
            byte[] signature = SignFromContainer(hashchain, subjectDN);
            if (signature != null)
            {
                string signaturestring = Convert.ToBase64String(signature);

                File.WriteAllBytes(devicePath + digSignFile, signature);
                result = true;
            }
            else
                result = false;
        }
}

static byte[] SignFromContainer(byte[] hashchain, string certSubject)
{
    try
    {
        X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        my.Open(OpenFlags.ReadOnly);
        RSACryptoServiceProvider csp = null;
        foreach (X509Certificate2 cert in my.Certificates)
        {
            if (cert.Subject.Contains(certSubject))
            {
                // We found it.
                // Get its associated CSP and private key
                csp = (RSACryptoServiceProvider)cert.PrivateKey;
            }
        }

        if (csp == null)
        {
            return null;
        }

        byte[] myHash = { 59,4,248,102,77,97,142,201,
        210,12,224,93,25,41,100,197,
        210,12,224,93};

        // Sign the hash
        return csp.SignHash(hashchain, CryptoConfig.MapNameToOID("SHA-512"));
    }
    catch (Exception e)
    {
        log.Logger("Exception: "+e.Message, "debug");
        log.Logger(e.StackTrace, "debug");
        return null;
    }
}

使用一些文章和答案中的解决方案,我有RSAPKCS1SHA512SignatureDescription类,我试图在其中实现和注册签名描述:

public class RsaPkCs1Sha512SignatureDescription : SignatureDescription
{
    public RsaPkCs1Sha512SignatureDescription()
    {
        KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
        DigestAlgorithm = typeof(SHA512Managed).FullName;
        FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
        DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
    }

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
    {
        var sigProcessor = (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA-512");
        return sigProcessor;
    }

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
    {
        var sigProcessor =
            (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
        sigProcessor.SetKey(key);
        sigProcessor.SetHashAlgorithm("SHA-512");
        return sigProcessor;
    }
}

我已经验证了hash的长度为64字节,它返回一个CryptographicException:Bad hash。但是如果我使用myhashvar(20字节长),尽管signhash中指定的算法是SHA512,但它可以工作,并使用SHA1算法对哈希进行签名。

另外,如果我打印csp.signaturealgorithm,它的值是http://www.w3.org/2000/09/xmldsig#rsa-sha1。如果安装的证书的详细信息显示SHA512RSA为签名算法,为什么签名算法等于http://www.w3.org/2000/09/xmldsig#RSA-SHA1?这一点可能是真正的问题吗?如果是,如何正确创建证书?提前感谢!

共有1个答案

郜琦
2023-03-14

NET 4.6中对此过程进行了简化:

byte[] signature;

using (RSA rsa = cert.GetRSAPrivateKey())
{
    signature = rsa.SignHash(hash, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
}

请注意,.NET4.6RSA类型不再需要强制转换为RSACryptoServiceProvider,如果您使用GetRSAPrivateKey()(而不是PrivateKey属性),返回的对象很可能处理SHA-512签名生成。GetRSAPrivateKey每次还返回一个唯一的对象,因此您应该适当地处理它。

 类似资料:
  • 我正在尝试用DSS签署PDF文档,我的问题是我无法在服务器a中计算文档的哈希值,然后在服务器B中签署它。 知道服务器A包含PDF文档,我们在服务器B中检索用于签名的证书 我的问题是如何在不需要证书的情况下计算服务器a中文档的哈希值。然后在服务器B上发送签名? 更新: ******散列的准备和计算******** ******散列签名******** ********PDF错误:*********

  • 问题内容: 从Redis文档上可以看到: 不应该代表键名 在Redis集群教程中 哈希标签记录在Redis Cluster规范中,但是要点是,如果密钥的{}中的括号之间有一个子字符串,则仅对字符串中的内容进行哈希处理,例如,此{foo}键和另一个{foo} key保证在同一哈希槽中,并且可以在以多个key作为参数的命令中一起使用。 是否可以仅传递哈希标签,或者仅传递带有该哈希标签的一个键?我们希望

  • Im使用OpenSSL的< code>dgst命令执行ECDSA签名,如下所示: 然而,我在这个SO答案中读到,它首先对data_file进行SHA256哈希处理,ASN.1在签名之前对哈希进行编码。 我想创建数据的SHA256哈希,并让ECDSA只对该哈希的原始字节进行签名。(由于这是ECDSA签名,我不能使用如上述SO答案中所述。) 如何使用OpenSSL实现这一点?

  • 我正在使用iText7执行PDF和签名操作。我的场景是,我在本地机器上计算哈希,并将这个哈希发送到签名服务器,作为响应,得到签名的PKCS1(原始签名),然后我将这个签名嵌入到PDF中。我的代码片段如下: 1:从智能卡设备读取公共证书。 3:初始化PdfSigner并设置签名外观: 4:我已经实现了IExternalSignatureContainer接口来获取文档哈希: 5:获取文档哈希: 7:

  • 我可以通过外部签名使用itextpdf库对文档进行签名。 但问题是,最终用户不想发送他的文档,因为它可能包含任何敏感数据。因此,我要求最终用户给出文档哈希,以便与外部服务签署哈希,并将签署后的哈希发回。 但是,问题来了,当他们试图使用itextpdf()用给定的签名散列对文档进行签名时,PDF文档被签名了。但在验证签名时,表明签名是无效的。 因此,问题的发生是因为每次使用(itextpdf库)打开

  • 问题内容: 我了解为什么将可变对象放入字典很危险。但是,将所有列表/集合转换为元组/ frozensets是昂贵的;对于许多类型,根本没有容易获得的不可变版本。因此,有时值得直接散列可变对象,并采取适当的预防措施以确保所讨论的对象永远不会被修改。 在开始为可变对象实现非常复杂的自定义哈希函数之前,我想检查一下用作哈希函数是否存在任何缺点- 无论是在性能,碰撞还是其他方面。 问题答案: 出于类似的原