无法使用 public 密钥 C# 验证签名数据
Can't verify signed data with public key C#
我有一个应用程序需要对某些数据进行签名,然后确认签名是否有效。使用的算法是 RSA SHA 256。我在 Windows 证书库中有一个证书及其各自的私钥。我已经在几篇文章和 this 上进行了搜索。我创建签名没有问题。我的问题是,当尝试使用 public 密钥确认签名是否有效时,VerifyData 方法 returns False。我没有很多使用 C# 和加密的经验,我看不出这段代码有什么问题。不幸的是,我正在使用旧框架 (4.5)
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, "XXXXXXXXXXXXXX", false);
var certificate = certificates(0);
store.Close();
var privKey = (RSACryptoServiceProvider)certificate.PrivateKey;
var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo;
var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, privKey.CspKeyContainerInfo.KeyContainerName);
privKey = new RSACryptoServiceProvider(cspparams);
byte[] sig = privKey.SignData(dataToSign, CryptoConfig.MapNameToOID("SHA256"));
bool isValid = privKey.VerifyData(dataToSign, CryptoConfig.MapNameToOID("SHA256"), sig);
string Signbase64String = Convert.ToBase64String(sig, 0, sig.Length);
if (isValid)
{
// Print Signature just to confirm...
// Here the signature validation WORKS! but I am using the private key
}
var publicKey = (RSACryptoServiceProvider)certificate.PublicKey.Key;
bool isValid2 = publicKey.VerifyData(dataToSign, CryptoConfig.MapNameToOID("SHA256"), sig);
// isValid2 returns false. It not works with PUBLIC KEY
我什至这样做过(直接加载.cer文件),响应是一样的
var 509 = new X509Certificate2(File.ReadAllBytes("certificate.cer"));
var publicKey = (RSACryptoServiceProvider)509.PublicKey.Key;
bool isValid2 = publicKey.VerifyData(dataToSign, CryptoConfig.MapNameToOID("SHA256"), sig);
// isValid2 returns false
非常感谢您的支持
在您提供的 link 中,私钥的实现方式不同。我在下面对此进行了测试,并且 VerifyData returns 为真。注意私钥创建的不同。
string certPath = "C:\testing.pfx";
string certPass = "MagicPassword";
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(certPath, certPass, X509KeyStorageFlags.Exportable);
X509Certificate2 cert = collection[0];
RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
RSACryptoServiceProvider privateKey = new RSACryptoServiceProvider();
privateKey.FromXmlString(cert.PrivateKey.ToXmlString(true));
byte[] data = Encoding.UTF8.GetBytes("Hello");
byte[] signature = privateKey.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
bool isValid = publicKey.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), signature);
我有一个应用程序需要对某些数据进行签名,然后确认签名是否有效。使用的算法是 RSA SHA 256。我在 Windows 证书库中有一个证书及其各自的私钥。我已经在几篇文章和 this 上进行了搜索。我创建签名没有问题。我的问题是,当尝试使用 public 密钥确认签名是否有效时,VerifyData 方法 returns False。我没有很多使用 C# 和加密的经验,我看不出这段代码有什么问题。不幸的是,我正在使用旧框架 (4.5)
X509Store store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, "XXXXXXXXXXXXXX", false);
var certificate = certificates(0);
store.Close();
var privKey = (RSACryptoServiceProvider)certificate.PrivateKey;
var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo;
var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, privKey.CspKeyContainerInfo.KeyContainerName);
privKey = new RSACryptoServiceProvider(cspparams);
byte[] sig = privKey.SignData(dataToSign, CryptoConfig.MapNameToOID("SHA256"));
bool isValid = privKey.VerifyData(dataToSign, CryptoConfig.MapNameToOID("SHA256"), sig);
string Signbase64String = Convert.ToBase64String(sig, 0, sig.Length);
if (isValid)
{
// Print Signature just to confirm...
// Here the signature validation WORKS! but I am using the private key
}
var publicKey = (RSACryptoServiceProvider)certificate.PublicKey.Key;
bool isValid2 = publicKey.VerifyData(dataToSign, CryptoConfig.MapNameToOID("SHA256"), sig);
// isValid2 returns false. It not works with PUBLIC KEY
我什至这样做过(直接加载.cer文件),响应是一样的
var 509 = new X509Certificate2(File.ReadAllBytes("certificate.cer"));
var publicKey = (RSACryptoServiceProvider)509.PublicKey.Key;
bool isValid2 = publicKey.VerifyData(dataToSign, CryptoConfig.MapNameToOID("SHA256"), sig);
// isValid2 returns false
非常感谢您的支持
在您提供的 link 中,私钥的实现方式不同。我在下面对此进行了测试,并且 VerifyData returns 为真。注意私钥创建的不同。
string certPath = "C:\testing.pfx";
string certPass = "MagicPassword";
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(certPath, certPass, X509KeyStorageFlags.Exportable);
X509Certificate2 cert = collection[0];
RSACryptoServiceProvider publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key;
RSACryptoServiceProvider privateKey = new RSACryptoServiceProvider();
privateKey.FromXmlString(cert.PrivateKey.ToXmlString(true));
byte[] data = Encoding.UTF8.GetBytes("Hello");
byte[] signature = privateKey.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
bool isValid = publicKey.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), signature);