I get an XML document as a string parameter in my method. XML document:
<Document> <ZipContainer> Zip_File_In_Base64 </ZipContainer> <X509Certificate> Certificate_In_Base64 </X509Certificate> </Document>
From this line, I extract the base64 format ZIP file and the base64 format X509Certificate2 certificate. The zip file contains:
a file that describes the contents of the ZIP file as XML ( packageDescription.xml file);
files with the contents of the transmitted documents (for example, *.doc );
files with the contents of a separate digital signature ( *.p7s files - a separate digital signature);
A signature, signed documentation must be extracted from the archive (there can be more than one separate digital signature). A separate digital signature is stored in files with the extension .p7s . Each signature must be made in order to verify its agreement with the digital signature with which the user has logged into the portal.
It should consist of two steps:
See the certificateValidator() method (see this method below). This is a separate signature contained in .p7s files with their corresponding files that were signed, these *. P7S files.
For example: a couple of related files: ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s and
ZayavUL_3594c921f545406d9b8734bbe28bf894.doc .
See certificateValidator() method: validates a certificate from a .p7s file with a certificate that is extracted from the input line of an XML document.
Questions
The signatureValidator method (see this method below) does not currently use delayed signing of .p7s files. I tried, but to no avail. How to check the selected signature of the .p7s file for the corresponding file?
In the certificateValidator method (see this method below), how can I verify the certificate extracted from the .p7s file using the certificate extracted from the input string in Base64 format?
Line of code foreach (X509Certificate2 x509 in signCms.Certificates) { } ---> The certificate collection is always empty. Why?
Input parameters
Dictionary <string, byte[]> dictP7SFiles (key is the name of the file * .p7s, value is an array of bytes representing the file * .p7s)
Dictionary <string, byte[]> dictNotP7SFiles (key is the name of a file signed using the selected signature from the * .p7s file, value is an array of bytes representing the file)
X509Certificate2 userCertX509 - certificate object extracted from the input xml document (where it has the Base64 format)
code
The following is a verification of the implementation of the verification steps (see above 2 steps):
private bool certificateValidator(Dictionary<string, byte[]> dictP7SFiles, Dictionary<string, byte[]> dictNotP7SFiles, X509Certificate2 userCertX509) { bool isValid = false; try { foreach (KeyValuePair<string, byte[]> pair in dictP7SFiles) { ContentInfo contentInfo = new ContentInfo(pair.Value); SignedCms signCms = new SignedCms(contentInfo, true); if (signCms.Certificates.Count != 0) { //Certificates Collection always is empty. Why? foreach (X509Certificate2 x509 in signCms.Certificates) { if ((x509.SerialNumber != userCertX509.SerialNumber) || (x509.Thumbprint != userCertX509.Thumbprint)) { isValid = false; return isValid; } } isValid = true; return isValid; } } } catch (Exception ex) { //here process exception code } return isValid; } private bool signatureValidator(Dictionary<string, byte[]> dictP7SFiles, Dictionary<string, byte[]> dictNotP7SFiles, X509Certificate2 userCertX509) { bool isValid = false; try { byte[] data = dictP7SFiles["ZayavUL_3594c921f545406d9b8734bbe28bf894.doc"]; byte[] publicKey; byte[] signature; object hasher = SHA1.Create(); // Our chosen hashing algorithm. // Generate a new key pair, then sign the data with it: using (var publicPrivate = new RSACryptoServiceProvider()) { signature = publicPrivate.SignData(data, hasher); publicKey = publicPrivate.ExportCspBlob(false); // get public key } // Create a fresh RSA using just the public key, then test the signature. using (var publicOnly = new RSACryptoServiceProvider()) { publicOnly.ImportCspBlob(publicKey); isValid = publicOnly.VerifyData(data, hasher, signature); // Return True //isValid = ByteArrayCompare(dictP7SStreams["ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s"], signature); byte[] p7sDetachedSignature = File.ReadAllBytes(@"D:\ZayavUL_3594c921f545406d9b8734bbe28bf894.doc_1.p7s"); isValid = ByteArrayCompare(p7sDetachedSignature, signature); } } catch (Exception) { //here process exception code } return isValid; }
source share