Я пытаюсь подписать простые данные с помощью C# с использованием хэша Sha1 и RSA, а затем проверить его с помощью команды OpenSSL.RSA Подписание с .Net и проверка с помощью команды OpenSSL
Для моих тестов я принял сертификат localhost, который уже существует в Windows.
Вот код, используемый с C#:
static void Main(string[] args)
{
string sValTest = "sampledata";
byte[] signature = Sign(sValTest, "localhost");
string b64 = Convert.ToBase64String(signature);
bool verified = Verify(sValTest, signature, @"pathToCer");
}
static byte[] Sign(string text, string certSubject)
{
X509Store my = new X509Store(StoreName.My, StoreLocation.LocalMachine);
my.Open(OpenFlags.ReadOnly);
RSACryptoServiceProvider csp = null;
foreach (X509Certificate2 cert in my.Certificates)
{
if (cert.Subject.Contains(certSubject))
{
csp = (RSACryptoServiceProvider)cert.PrivateKey;
break;
}
}
SHA1Managed sha1 = new SHA1Managed();
byte[] data = Enconding.ASCII.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1"));
}
static bool Verify(string text, byte[] signature, string certPath)
{
X509Certificate2 cert = new X509Certificate2(certPath);
RSACryptoServiceProvider csp = RSACryptoServiceProvider)cert.PublicKey.Key;
SHA1Managed sha1 = new SHA1Managed();
byte[] data = Encoding.ASCII.GetBytes(text);
byte[] hash = sha1.ComputeHash(data);
return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature);
}
(В этом примере, verified
дает true
)
Я послал публичную часть PFX к моему Linux компьютера, а также подписи в качестве основания 64.
затем я сделал следующее:
base64 --decode sig.b64 > sig
openssl x509 -inform der -in localhost.cer -out localhost.pem
openssl x509 -pubkey -noout -in localhost.pem > localhost.pub.pem
echo -n "sampledata" | openssl dgst -verify localhost.pub.pem -signature sig
Конец: Verification Failure
.
Я проверил серийный номер сертификатов с обеих сторон, и он соответствует. На всякий случай, я также проверил md5 подписи на обеих станциях, все ясно.
Любые указатели на то, где очевидный отказ?
Я предполагаю (и только предположение), что это с использованием 16-битных символов Unicode: 'UnicodeEncoding кодирования = новый UnicodeEncoding'; в то время как это использует 8-битный чистый ASCII: 'echo -n" sampledata "'. – jww
@jww Я использовал UTF8 в другом разделе кода, чтобы убедиться, что я снова попытался с ASCII, не помог –