簡體   English   中英

C# - 是否可以使用 RSA SHA512 對哈希進行簽名?

[英]C# - Is it possible to Sign hash using RSA SHA512?

我使用 OpenSSL 創建了一個自簽名證書,如下所示:

openssl req -x509 -sha512 -new keyrsa:2048 -keyout key2.pem -out cert2.pem -days 100

openssl pkcs12 -export -out pkcs12_cert_test2.pfx -inkey key2.pem -in cert2.pem

我已經在 Windows 上安裝了pkcs12_cert_test2.pfx並且證書簽名算法值為sha512RSA

然后,我在 C# .NET 4.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;
    }
}

我已經驗證哈希是64字節長,它返回一個CryptographicException: Bad Hash 但是,如果我使用myHash var(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 這可能是真正的問題嗎? 如果是這樣,我該如何正確創建證書? 提前致謝!

此過程已在 .NET 4.6 中簡化:

byte[] signature;

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

請注意,.NET 4.6 RSA 類型不再需要轉換為 RSACryptoServiceProvider,並且如果您使用 GetRSAPrivateKey()(而不是 PrivateKey 屬性),則返回的對象可能會處理 SHA-512 簽名生成。 GetRSAPrivateKey 每次也返回一個唯一的對象,因此您應該適當地處理它。

好的。 沒有必要實現RsaPkCs1Sha512SignatureDescription類或類似的東西,但要指定正確的 CSP 以允許 CryptoAPI 使用 SHA256 或 SHA512:“Microsoft Enhanced RSA and AES Cryptographic Provider”,類型 24。

我們只需要將 CSP 類型作為 CspParameter 並導出/導入密鑰信息:

    byte[] privateKeyBlob;
    CspParameters cp = new CspParameters(24);
    RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PrivateKey;
    privateKeyBlob = csp.ExportCspBlob(true);
    csp = new RSACryptoServiceProvider(cp);
    csp.ImportCspBlob(privateKeyBlob); 

    // Sign the hash
    return csp.SignHash(hashchain, CryptoConfig.MapNameToOID("SHA-512"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM