【发布时间】:2014-06-22 17:22:54
【问题描述】:
我必须为网络服务签署消息。该服务使用 OpenSSL MD5 签名。我从 PEM 私钥文件生成 OpenSSL:
openssl.exe dgst -md5 -hex -out signature.txt -sign privKey.pem textToSign.txt
生成以下签名:
7078388bd081d4b805feb020ab47352320919e4638e36b59d66a684c9bb12a745aaf172e4da2686c3e3750bf627c980a19700f6d8bbd0b62d8714a965a34be2e9f4147ac054c4af1050cdcebd9b475f0ef28e520681b0d67104b8e633ee592bb3ec2c517fb8cf7b13bd86424f00c89518e063d55e7922adab7cf607c85920862
我想在我的代码中实现这一点。我的实际代码看起来像(pfx 文件中的私钥与 pem 文件中的私钥相同):
private static string Sign(string stringToSign)
{
X509Certificate2 cert = new X509Certificate2("keys.pfx", "", X509KeyStorageFlags.Exportable);
byte[] data = Encoding.UTF8.GetBytes(stringToSign);
byte[] signedData;
using (MD5 hasher = MD5.Create())
using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey)
{
signedData = rsa.SignData(data, hasher);
}
return Convert.ToBase64String(signedData);
}
此代码产生以下签名...
cHg4i9CB1LgF/rAgq0c1IyCRnkY442tZ1mpoTJuxKnRarxcuTaJobD43UL9ifJgKGXAPbYu9C2LYcUqWWjS+Lp9BR6wFTErxBQzc69m0dfDvKOUgaBsNZxBLjmM+5ZK7PsLFF/uM97E72GQk8AyJUY4GPVXnkirat89gfIWSCGI=
...与 OpenSLL 不匹配。 我应该怎么做才能匹配 OpenSSL?我也尝试使用 OpenSSL.NET,但我没有找到任何用于签名的资源/教程。
已解决
正确的代码是:
private static string Sign(string stringToSign)
{
X509Certificate2 cert = new X509Certificate2("#02299991.pfx", "#02299991", X509KeyStorageFlags.Exportable);
byte[] data = Encoding.UTF8.GetBytes(stringToSign);
byte[] signedData;
using (MD5 hasher = MD5.Create())
using (RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey)
{
signedData = rsa.SignData(data, hasher);
}
return ByteArrayToString(signedData); //Convert.ToBase64String(signedData);
}
public static string ByteArrayToString(byte[] signedBytes)
{
StringBuilder hex = new StringBuilder(signedBytes.Length * 2);
foreach (byte b in signedBytes)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
【问题讨论】:
-
考虑将 MD5 替换为 SHA-2。针对 MD5 的碰撞攻击可能导致对构建在 MD5 之上的数字签名的实际攻击。
-
这不是我的选择,我必须与“遗留”服务合作。
标签: c# cryptography openssl md5