RSA Signing using MD5-SHA1 Hash Algorithm

时光毁灭记忆、已成空白 提交于 2019-12-23 19:06:14

问题


From what I can tell, TLS 1.1 requires the contents of the CertificateVerify message to be a digitally signed value using the concatenation of two hash algorithms (MD5 and SHA1). Is this possible to do in .NET using the RSACryptoServiceProvider?

This does not work:

using (var rsa = new RSACryptoServiceProvider())
{
    rsa.ImportParameters(...);
    rsa.SignData(data, new MD5SHA1());
}

This also does not work:

using (var rsa = new RSACryptoServiceProvider())
{
    rsa.ImportParameters(...);
    rsa.SignHash(new MD5SHA1().ComputeHash(data), "MD5SHA1");
}

(MD5SHA1 is an implementation of HashAlgorithm.)

Presumably this does not work because the signature embeds the OID of the hash algorithm, and MD5-SHA1 does not have a valid OID. Is this possible in .NET? Am I misunderstanding TLS 1.1?


回答1:


In case it helps anyone else, I used the BigInteger class to make this work. What is called "signing" in TLS 1.1 is really just private-key encryption, which can be done using BigInteger math.

Sign

var hash = new MD5SHA1().ComputeHash(data);
var input = new BigInteger(hash);
return input.ModPow(new BigInteger(privateExponent),
                    new BigInteger(modulus)).GetBytes();

Verify

var hash = new MD5SHA1().ComputeHash(data);
var input = new BigInteger(signature);
var output = input.ModPow(new BigInteger(publicExponent),
                          new BigInteger(modulus)).GetBytes();
var rehash = SubArray(output, output.Length - 36);
return SequencesAreEqual(hash, rehash);

Note that you still have to add padding yourself to the output. (0x0001FFFFFF...FF00{data})

Signing can be optimized using CRT parameters (p, q, etc.), but that's a problem for another day.



来源:https://stackoverflow.com/questions/19407581/rsa-signing-using-md5-sha1-hash-algorithm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!