17

Я пытаюсь подписать файл XML с помощью сертификата x.509, я могу использовать закрытый ключ для подписи документа, а затем использовать контрольную строку (он имеет перегрузку, которая получает сертификат как параметр), чтобы проверить подпись.В C# подпишите xml с сертификатом x.509 и проверьте подпись

Проблема заключается в том, что пользователь, который проверяет подпись, должен иметь сертификат, моя проблема в том, что если у пользователя есть сертификат, то у него есть доступ к закрытому ключу, и, как я понимаю, это личное и должно быть доступно только для пользователя, который подписывает.

Что мне не хватает?

Благодарим за помощь.

ответ

5

Любой сертификат имеет общественную и частную часть. Вы отправляете только общественную часть. Просто откройте любой веб-сайт с поддержкой SSL в своем браузере, нажмите на символ замка и посмотрите на их сертификат.

+0

Спасибо, это именно то, что у меня не было ясно. Теперь я знаю, что мне нужно использовать сертификат из X509Store, чтобы получить сертификат «signer» и использовать файл .cer в качестве «верификатора». – willvv

19

В .NET Если вы получаете X509 сертификат из файла .pfx, как это:

X509Certificate2 certificate = new X509Certificate2(certFile, pfxPassword); 
RSACryptoServiceProvider rsaCsp = (RSACryptoServiceProvider) certificate.PrivateKey; 

Затем вы можете экспортировать часть открытого ключа следующим образом:

rsaCsp.ToXmlString(false); 

" ложная "часть говорит, только экспортируйте публичный кусок, не экспортируйте частную часть. (Док для RSA.ToXmlString)

А затем в приложении проверочной используйте

RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
csp.FromXmlString(PublicKeyXml); 
bool isValid = VerifyXml(xmlDoc, rsa2); 

И VerifyXml называет CheckSignature(). Это выглядит примерно так:

private Boolean VerifyXml(XmlDocument Doc, RSA Key) 
{ 
    // Create a new SignedXml object and pass it 
    // the XML document class. 
    var signedXml = new System.Security.Cryptography.Xml.SignedXml(Doc); 

    // Find the "Signature" node and create a new XmlNodeList object. 
    XmlNodeList nodeList = Doc.GetElementsByTagName("Signature"); 

    // Throw an exception if no signature was found. 
    if (nodeList.Count <= 0) 
    { 
     throw new CryptographicException("Verification failed: No Signature was found in the document."); 
    } 

    // Though it is possible to have multiple signatures on 
    // an XML document, this app only supports one signature for 
    // the entire XML document. Throw an exception 
    // if more than one signature was found. 
    if (nodeList.Count >= 2) 
    { 
     throw new CryptographicException("Verification failed: More that one signature was found for the document."); 
    } 

    // Load the first <signature> node. 
    signedXml.LoadXml((XmlElement)nodeList[0]); 

    // Check the signature and return the result. 
    return signedXml.CheckSignature(Key); 
} 
+2

Код, кажется, от http://msdn.microsoft.com/en-us/library/ms229950(v=vs.110).aspx. Я думаю, что это круто, что вы включаете код здесь вместо того, чтобы просто ссылаться на него, но, конечно же, дайте им кредит, где это необходимо. –

0

Прежде всего вы должны быть уверены, что PFX-сертификат или .cer , что вы используете предназначен для подписания цели.

 
You can check same in General Tab of a certificate 

*.Proves your identity to a remote computer 
*.Protects e-mail messages 
*.Allows data to be signed with the current time 
*.Allows data on disk to be encrypted 
*.2.16.356.100.2 
**Document Signing** 

Полное консольное приложение для цифровой подписи/проверить XmlDocument в C# написано here.