0

Я потратил 100 часов на изучение этой темы, а другой старший программист, который закодировал исходный проект, также не смог заставить его работать. У меня есть xml с параметром SignatureValue, Certificate (X509Certificate2) и Digest Value. Созданное и заданное значение Подписи, указанное в том же xml, было сделано путем преобразования согласованных полей (равных значениям дайджеста) в хеш (SHA1), а затем зашифрованных через закрытый ключ. Частный ключ извлекается из сертификата для обеспечения конфиденциальности, и у меня есть только открытый ключ. Теперь, независимо от того, как я код вокруг него, я всегда получаю ложное значение обратно (как в VerifyHash/verifyHashResult является ложным). Вот код, который я использую:Не удается проверить значение подписи с помощью открытого ключа сертификата, предоставленного в xml (X509Certificate2)

// Вам нужна ваша помощь.

static void VerifyHash(string sigVal , string digestVal, System.Security.Cryptography.X509Certificates.X509Certificate2 cert) 
     { 
      sigValInBytes = Convert.FromBase64String(sigVal); 
      try 
      { 
using (RSACryptoServiceProvider rsaProviderDecrypt = (RSACryptoServiceProvider)cert.PublicKey.Key) 
       { 
// Line below always return value of FALSE no matter how I code it. Here I want to verify the hashed freshly calculated digest value that is now hashed with the signature value 
        rsaProviderDecrypt.Decrypt(sigValInBytes, false); 

        rsaProviderDecrypt.Dispose(); 
       } 
      } 
     } 


// At the main program I get the certificate from the xml given and call the method above: 

main 
{ 
// Code below gets the certificate details from a given xml, details of each variable confirmed to be accurate. 
char[] Base64_x509ByteArray; 
Base64_x509ByteArray = t.DigitalSignatures.First().X509Data.ToCharArray(); 
byte[] x509ByteArray; 
x509ByteArray = Convert.FromBase64CharArray(Base64_x509ByteArray, 0, Base64_x509ByteArray.Length); 

// Here am creating the certificate from the gathered data/certificate: 
System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(x509ByteArray); 

VerifyHash(t.DigitalSignatures.FirstOrDefault().SignatureValue.Trim(), concatenatedFieldValues, cert); 

} 
+0

Что это за класс 'ByteConverter'? Почему подпись и дайджест строки? –

+0

Любая причина, по которой вы хотите использовать 'X509Certificate2'? Могли бы дать вам другое предложение? – CularBytes

+0

На вопрос №1 я пошел дальше и внес некоторые изменения и удалил преобразование байтов, потому что мне не нужен новый код, опубликованный только сейчас. Я думаю, что я на шаг ближе и делаю правильную вещь при использовании rsaProviderDecrypt.Decrypt (sigValInBytes, false), особенно после преобразования массива sigVal в байты с использованием FromBase64String, потому что это сделало массив байтов не более 256. Но получить новую ошибку «Ключ не существует» – user2771273

ответ

1

Некоторые снимки в темноте:

  1. Найти кусок, который разбивается: Попробуйте сделать все «шифровать/хэш проверки» процесс в коде без перенося ничего над XML. Если вы можете хэшировать строку локально, а хеши совпадают, проблема возникает в XML. В противном случае проблема заключается в сертификате или расшифровке.

  2. Если проблема связана со стороной cert/encryptor, попробуйте сопоставить хэш с локальным классом криптографии .NET. Если это не удается, проблема заключается в настройке шифрования. В противном случае это сертификат.

  3. БОЛЬШОЙ выстрел в темноте: вызов Dispose сразу после проверки хэша. Он не должен иметь значение, но это вызвало проблему при расшифровке с использованием алгоритма Rijndael. Лучше всего предположить, что оптимизатор закрывал поток раньше или что-то странное. Перемещение конструктора из инструкции using и ручное вызов Dispose после доступа к результату исправили «оптимизацию».

  4. Мощный алгоритм шифрования. Rinjdael является родным для .NET и является обратимым. Хорошо подходит для отладки и проверки концепции работы. (Примечание: он использует Time как часть соли, поэтому RJ не соответствует хэшам, он расшифровывается. Поэтому не подходит для паролей в производственных средах.)

  5. Если причина XML, проверьте кодировки. Шифрование очень чувствительно к кодировкам, а XML-сериализаторы - это финишные звери для начала. Строки могут посмотреть то же, но представлены по-другому или добавлены дополнительные управляющие символы. Sql Server nvarchars - это UCS-2, varchars - iso-8859-1, строки C# - utf-8 и т. Д. Легко кодировать неверные совпадения, и изменение кодировки легко приведет к этому. Попробуйте преобразовать исходное значение в utf-16 перед вставкой в ​​Xml и установить кодировку объявления Xml в utf-16. Просто быть в безопасности.

  6. Заметка о NotePad: если вы открыли Xml в блокноте, чтобы быстро просмотреть или отредактировать и сохранить его, на ваших строках, возможно, появятся дополнительные символы «конца строки». Если вы сделали то же самое в Word ... о, мой ... Можете попробовать оригинальную копию.

  7. В противном случае попробуйте создать новые зашифрованные значения и посмотреть, совпадают ли они.

+0

Большое спасибо за приведенные выше пункты, я рассматриваю некоторые моменты, на самом деле я сделал обновление для своего кода и закодировал вызов decrpt (размещен в исходном коде выше), но теперь у меня есть новая ошибка «Key not found «хотя я уверен, что ключ был извлечен и есть (см. мой обновленный код выше). Благодарю. – user2771273

Смежные вопросы