Как проверить подпись, загружая PUBLIC KEY из файла PEM? - PullRequest
4 голосов
/ 29 июня 2009

Я публикую это в надежде, что это сэкономит кому-то еще часы, которые я потратил на эту действительно глупую проблему, связанную с преобразованием форматов открытых ключей. Если кто-нибудь видит более простое решение или проблему, пожалуйста, дайте мне знать!

Используемая мной система электронной коммерции отправляет мне некоторые данные вместе с подписью. Они также дают мне свой открытый ключ в формате .pem. Файл .pem выглядит так:

----- НАЧАТЬ ПУБЛИЧНЫЙ КЛЮЧ ----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDe + hkicNP7ROHUssGNtHwiT2Ew HFrSk / qwrcq8v5metRtTTFPE / nmzSkRnTs3GMpi57rBdxBBJW5W9cpNyGUh0jNXc VrOSClpD5Ri2hER / GcNrxVRP7RlWOqB1C03q4QYmwjHZ + zlM4OUhCCAtSWflB4wC Ka1g88CjFwRw / PB9kwIDAQAB ----- КОНЕЦ ОБЩЕСТВЕННОГО КЛЮЧА -----

Вот магический код, позволяющий превратить вышеперечисленное в «RSACryptoServiceProvider», который способен проверять подпись. Использует библиотеку BouncyCastle, поскольку .NET, по-видимому (и, к сожалению, не может сделать это без каких-либо серьезных проблем с файлами сертификатов):

RSACryptoServiceProvider thingee;

using (var reader = File.OpenText(@"c:\pemfile.pem"))
{
    var x = new PemReader(reader);
    var y = (RsaKeyParameters)x.ReadObject();

    thingee = (RSACryptoServiceProvider)RSACryptoServiceProvider.Create();
    var pa = new RSAParameters();
    pa.Modulus = y.Modulus.ToByteArray();
    pa.Exponent = y.Exponent.ToByteArray();
    thingee.ImportParameters(pa);
}

А потом код для проверки подлинности подписи:

var signature = ... //reads from the packet sent by the eCommerce system
var data = ... //reads from the packet sent by the eCommerce system
var sha = new SHA1CryptoServiceProvider();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data));
byte[] bSignature = Convert.FromBase64String(signature);

///Verify signature, FINALLY:
var hasValidSig = thingee.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), bSignature);

1 Ответ

2 голосов
/ 29 июня 2009

Потенциальная проблема: использование Encoding.ASCII.GetBytes(data) почти наверняка является неправильным способом получения хэша. Это означает, что они могут только отправлять хэш, для которого не установлены старшие биты.

Если это «пакет», вы должны получить необработанные данные из пакета в виде байтового массива. Если это , представленное в виде текста, оно должно быть в какой-то зашифрованной форме - например, hex или base64. Как выглядит хеш?

...