簡體   English   中英

從PEM文件獲取帶有DSA私鑰的字符串的SHA1符號

[英]Get SHA1 sign of string with DSA private key from PEM file

我有一個PEM文件,其中包含我的DSA私鑰,我需要使用此私鑰對字符串進行簽名,以將其發送給我的合作伙伴API。 (附代碼)

出於某種原因,我總是從我的合作伙伴API獲得Signature Invalid表單。 這意味着標志的格式不佳。

我的合作伙伴讓我使用bouncycastle進行c#但是我找不到任何如何用外部PEM文件用DSA簽名字符串的例子。

我能在這里得到任何例子嗎?

謝謝。

我試着用我寫的方法簽名字符串:

 public string ComputeSignature(string method, string path,string client_id, string timestamp, string username)
        {


        var data = String.Concat(method, path, client_id, timestamp);
        if (!string.IsNullOrEmpty(username))
        {
            data = data + username;
        }


        string sig;
        var encoding = new ASCIIEncoding();
        byte[] dataInBytes = encoding.GetBytes(data);
        using (System.Security.Cryptography.HMAC Hmac = new HMACSHA1())
        {
            Hmac.Key = encoding.GetBytes(privateKeyClean);

            byte[] hash = Hmac.ComputeHash(dataInBytes, 0, dataInBytes.Length);
            sig = Convert.ToBase64String(hash, 0, hash.Length);
        }
        return sig;


    }

我使用bouncycastle解決了這個問題:

    private static string ComputeSignature()
    {
        AsymmetricCipherKeyPair asymmetricCipherKeyPair;
        using (TextReader textReader = new StreamReader("myprivatekey.pem"))
        {
            asymmetricCipherKeyPair = (AsymmetricCipherKeyPair)new PemReader(textReader).ReadObject();
        }
        DsaPrivateKeyParameters parameters = (DsaPrivateKeyParameters)asymmetricCipherKeyPair.Private;
        string text = TEXTTOENC;
        if (!string.IsNullOrEmpty(userName))
        {
            text += userName;
        }
        Console.Out.WriteLine("Data: {0}", text);
        byte[] bytes = Encoding.ASCII.GetBytes(text);
        DsaDigestSigner dsaDigestSigner = new DsaDigestSigner(new DsaSigner(), new Sha1Digest());
        dsaDigestSigner.Init(true, parameters);
        dsaDigestSigner.BlockUpdate(bytes, 0, bytes.Length);
        byte[] inArray = dsaDigestSigner.GenerateSignature();
        string text2 = Convert.ToBase64String(inArray);
        Console.WriteLine("Signature: {0}", text2);
        return text2;
    }

這里DSA簽名失敗的原因是你根本沒有做DSA。 您正在使用密鑰文件的內容作為HMAC密鑰來執行HMAC-SHA-1。

  1. 從文件中讀取DSA密鑰參數。

.NET沒有內在的支持來讀取PEM密鑰文件。 但是你的標題提到了BouncyCastle,所以你可以調整接受的答案如何從.NET讀取PEM RSA私鑰到DSA(使用PemReader)。

或者,您可以使用OpenSSL根據此密鑰創建自簽名證書,並將cert +密鑰放入PFX。 .NET可以很好地加載PFXes。

  1. 填充DSA對象。

如果你去PFX路由, cert.GetDSAPrivateKey()將做正確的事(.NET 4.6.2)。 在早於4.6.2的版本上,您可以使用cert.PrivateKey as DSA ,它僅適用於FIPS 186-2兼容的DSA(DSA在FIPS 186-3中升級)。

如果您正在使用BouncyCastle來讀取PEM關鍵參數,那么您可以堅持使用BouncyCastle或執行類似using (DSA dsa = DSA.Create()) { dsa.ImportParameters(parametersFromTheFile); /* other stuff here */ } using (DSA dsa = DSA.Create()) { dsa.ImportParameters(parametersFromTheFile); /* other stuff here */ } (DSA.Create()將在.NET Framework上提供僅限於FIPS-186-2的對象,但它可以在.NET Core上執行FIPS-186-3)。

  1. 簽署數據

FIPS-186-2僅允許SHA-1作為哈希算法,FIPS-186-3允許SHA-2系列(SHA256,SHA384,SHA512)。 我們假設你使用的是FIPS-186-2 / SHA-1(如果沒有,所需的替換很明顯)。

BouncyCastle:然而他們計算簽名。 (對不起,我不熟悉他們的API)

.NET 4.6.1或更早版本:

using (SHA1 hash = SHA1.Create())
{
    signature = dsa.CreateSignature(hash.ComputeHash(dataInBytes));
}

.NET 4.6.2或更新版本:

signature = dsa.SignData(dataInBytes, HashAlgorithmName.SHA1);

肥皂盒

然后,一旦說完所有(或者,也許,之前):問問自己“我為什么要使用DSA?”。 在FIPS 186-2(和之前的版本)中,DSA限制為1024位密鑰大小和SHA-1哈希。 NIST SP800-57將SHA-1和DSA-1024分類為具有80位安全性(表2和表3)。 NIST將80位安全性分類為2011 - 2013年的“棄用”和2014年及以后的“不允許”(表4)。 DSA的現代使用(適用於受NIST建議的實體)需要FIPS-186-3支持。

ECDSA獲得〜密鑰/ 2位安全性; 因此,最低(通常支持的)ECDSA密鑰大小(基於NIST P-256 / secp256r1的密鑰)獲得128位安全性,NIST對2031+的評級為好。

RSA也是比DSA更好的選擇,因為它對NIST認為安全的簽名有更好的支持。

但是,如果你符合協議,我想沒有很多選擇。

暫無
暫無

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

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