17

Próbuję podpisać plik XML za pomocą certyfikatu x.509, mogę użyć klucza prywatnego, aby podpisać dokument, a następnie użyć funkcji CheckSignature metoda (ma przeciążenie, które otrzymuje certyfikat jako parametr) w celu zweryfikowania podpisu.W języku C#, zarejestruj xml z certyfikatem x.509 i sprawdź podpis

Problem polega na tym, że użytkownik, który sprawdza poprawność podpisu, musi mieć certyfikat, moim zmartwieniem jest to, że jeśli użytkownik ma certyfikat, to ma on dostęp do klucza prywatnego, a jak rozumiem, jest to prywatne i powinno być dostępne tylko dla użytkownika, który podpisuje.

Czego mi brakuje?

Dzięki za pomoc.

Odpowiedz

5

Każdy certyfikat ma część publiczną i prywatną. Wysyłasz tylko w części publicznej. Wystarczy otworzyć w przeglądarce dowolną witrynę z włączoną obsługą protokołu SSL, kliknąć symbol kłódki i sprawdzić ich certyfikat.

+0

Dziękuję, właśnie to nie było jasne. Teraz wiem, że muszę użyć certyfikatu z X509Store, aby uzyskać certyfikat "osoby podpisującej" i użyć pliku .cer jako "weryfikatora". – willvv

19

W .NET Jeśli masz swoje X509 cert z pliku .pfx, tak:

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

Następnie można wyeksportować część klucza publicznego tak:

rsaCsp.ToXmlString(false); 

The " Fałszywe "część mówi, wyeksportuj tylko kawałek publiczny, nie eksportuj prywatnego kawałka. (Dok dla RSA.ToXmlString)

A potem w aplikacji weryfikującej, użyj

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

A VerifyXml wzywa CheckSignature(). Wygląda to mniej więcej tak:

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

Kod wydaje się pochodzić z http://msdn.microsoft.com/en-us/library/ms229950(v=vs.110).aspx. Wydaje mi się, że fajnie jest umieścić tutaj kod, zamiast tylko go łączyć, ale podać kredyt tam, gdzie jest to konieczne. –

0

Po pierwsze wszystko, czego potrzebujesz, aby mieć pewność, że .pfx certyfikatu lub .cer że używasz przeznaczony jest do podpisania celowi.

 
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** 

kompletnego wniosku konsola do cyfrowego podpisywania/zweryfikować XmlDocument w C# jest napisane here.