Dobrý den, zmigroval jsem jeden server z Win SBS 2003 na Win Server 2003 R2 a né a né přijít na to, proč nefunguje aplikace na podepisování a šifrování XML dokumentů, kterou kdysi napsal kolega ve Visual Basicu .NET 2008. Kód vypadá takto :
Imports System
Imports System.Security.Cryptography
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Cryptography.Xml
Imports System.Text
Imports System.Xml
Imports System.Xml.XPath
Module Module1
Dim cAdresar As String
Dim cSoubor As String
Dim cCertifikaty As String
Sub Main(ByVal args() As String)
Try
If args.Length > 0 Then
cAdresar = args(0)
cSoubor = args(1)
cCertifikaty = args(2)
Console.WriteLine("Mame parametry ... ")
Console.WriteLine(cAdresar)
Else
Console.WriteLine("Nebyly zadany zadne parametry ... pouziju default")
cAdresar = "C:\XML\"
cCertifikaty = "C:\XML\"
cSoubor = "10cz170300g1b20091_15122010113639.xml"
End If
Dim rsaKey As New RSACryptoServiceProvider() 'pro SHA 256
'Dim rsaKey As New SHA256CryptoServiceProvider() 'pro SHA 256 - u WinXP hlaska : Zadaný šifrovací algoritmus není na této platformě podporován.
' Create a new XML document.
Dim xmlDoc As New XmlDocument()
' Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = True
xmlDoc.Load(cAdresar + cSoubor)
Console.WriteLine(xmlDoc.DocumentElement.Name)
' Sign the XML document.
SignXml(xmlDoc)
' Save the document.
xmlDoc.Save(cAdresar + "PODEPSANO\SIG_" + cSoubor)
xmlDoc.Save("C:\SIG_" + cSoubor)
Dim result As Boolean = VerifyXmlFile(cAdresar + "PODEPSANO\SIG_" + cSoubor)
If result Then
Console.WriteLine("XML podpis OK")
Else
Console.WriteLine("XML podpis KO")
End If
Dim EcrDoc As New XmlDocument()
'EcrDoc.Load(cAdresar + "ECROBALKA\ECR_OBALKA.xml")
EcrDoc.Load(cAdresar + "ECROBALKA\OB_" + cSoubor)
Dim yyy As XmlElement = EcrDoc.DocumentElement
yyy = yyy.ChildNodes.Item(3) 'tady se dostanu do ./XmlZprava
yyy = yyy.ChildNodes.Item(0) 'tady se dostanu do ./XmlZprava/Data
'Console.WriteLine(yyy.ChildNodes.Item(0))
Dim newBook As XmlNode = EcrDoc.ImportNode(xmlDoc.DocumentElement, True)
yyy.AppendChild(newBook)
EcrDoc.Save(cAdresar + "PODEPSANO\ECR_SIG_" + cSoubor)
Console.WriteLine("ECR obalka vytvorena...")
Catch e As Exception
Console.WriteLine(e.Message)
End Try
Try
' Create an XmlDocument object.
Console.WriteLine("sifruju soubor...")
Dim xmlDoc As New XmlDocument()
' Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = True
xmlDoc.Load(cAdresar + "PODEPSANO\ECR_SIG_" + cSoubor)
Dim cert As X509Certificate2 = Nothing
Dim certificate1 As New X509Certificate2(cCertifikaty + "kom_public.cer")
cert = certificate1
If cert Is Nothing Then
Throw New CryptographicException("The X.509 certificate could not be found.")
End If
' Encrypt the "creditcard" element.
Encrypt(xmlDoc, "Data", cert)
' Save the XML document.
xmlDoc.Save(cAdresar + "POSLAT\ENC_ECR_SIG_" + cSoubor)
Console.WriteLine("soubor zasifrovan...")
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub 'Main
Sub Encrypt(ByVal Doc As XmlDocument, ByVal ElementToEncryptName As String, ByVal Cert As X509Certificate2)
' Check the arguments.
If Doc Is Nothing Then
Throw New ArgumentNullException("Doc")
End If
If ElementToEncryptName Is Nothing Then
Throw New ArgumentNullException("ElementToEncrypt")
End If
If Cert Is Nothing Then
Throw New ArgumentNullException("Cert")
End If
''''''''''''''''''''''''''''''''''''''''''''''''
' Find the specified element in the XmlDocument
' object and create a new XmlElemnt object.
''''''''''''''''''''''''''''''''''''''''''''''''
Dim elementToEncrypt As XmlElement = Doc.GetElementsByTagName(ElementToEncryptName)(0)
' Throw an XmlException if the element was not found.
If elementToEncrypt Is Nothing Then
Throw New XmlException("The specified element was not found")
End If
''''''''''''''''''''''''''''''''''''''''''''''''
' Create a new instance of the EncryptedXml class
' and use it to encrypt the XmlElement with the
' X.509 Certificate.
''''''''''''''''''''''''''''''''''''''''''''''''
Dim eXml As New EncryptedXml()
' Encrypt the element.
Dim edElement As EncryptedData = eXml.Encrypt(elementToEncrypt, Cert)
''''''''''''''''''''''''''''''''''''''''''''''''
' Replace the element from the original XmlDocument
' object with the EncryptedData element.
''''''''''''''''''''''''''''''''''''''''''''''''
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, False)
End Sub
' Sign an XML file.
' This document cannot be verified unless the verifying
' code has the key with which it was signed.
Sub SignXml(ByVal Doc As XmlDocument)
' Check arguments.
If Doc Is Nothing Then
Throw New ArgumentException("Doc")
End If
Console.WriteLine("Podepisuji soubor....")
' Create a SignedXml object.
Dim signedXml As New SignedXml(Doc)
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
' Create a reference to be signed.
Dim reference As New Reference()
reference.Uri = ""
' Add an enveloped transformation to the reference.
Dim env As New XmlDsigEnvelopedSignatureTransform()
reference.AddTransform(env)
' Add the reference to the SignedXml object.
signedXml.AddReference(reference)
' Compute the signature.
' Create a new KeyInfo object.
Dim keyInfo As New KeyInfo()
'Load the X509 certificate.
Dim certificate2 As New X509Certificate2(cCertifikaty + "certifikat.pfx", "heslo")
' Load the certificate into a KeyInfoX509Data object
' and add it to the KeyInfo object.
keyInfo.AddClause(New KeyInfoX509Data(certificate2))
' Add the KeyInfo object to the SignedXml object.
signedXml.KeyInfo = keyInfo
signedXml.SigningKey = certificate2.PrivateKey
Console.WriteLine("pred ComputeSignature")
signedXml.ComputeSignature()
Console.WriteLine("po ComputeSignature")
' Get the XML representation of the signature and save
' it to an XmlElement object.
Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
' Append the element to the XML document.
Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
Console.WriteLine("XML soubor podepsan....")
End Sub
Function GetCertificateBySubject(ByVal CertificateSubject As String) As X509Certificate2
' Check the args.
If Nothing = CertificateSubject Then
Throw New ArgumentNullException("CertificateSubject")
End If
' Load the certificate from the certificate store.
Dim cert As X509Certificate2 = Nothing
Dim store As New X509Store("My", StoreLocation.CurrentUser)
Try
' Open the store.
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
' Get the certs from the store.
Dim CertCol As X509Certificate2Collection = store.Certificates
' Find the certificate with the specified subject.
Dim c As X509Certificate2
For Each c In CertCol
If c.Subject = CertificateSubject Then
cert = c
Exit For
End If
Next c
' Throw an exception of the certificate was not found.
If cert Is Nothing Then
Throw New CryptographicException("The certificate could not be found.")
End If
Finally
' Close the store even if an exception was thrown.
store.Close()
End Try
Return cert
End Function
Function VerifyXmlFile(ByVal Name As String) As [Boolean]
' Create a new XML document.
Dim xmlDocument As New XmlDocument()
' Format using white spaces.
xmlDocument.PreserveWhitespace = True
' Load the passed XML file into the document.
xmlDocument.Load(Name)
' Create a new SignedXml object and pass it
' the XML document class.
Dim signedXml As New SignedXml(xmlDocument)
' Find the "Signature" node and create a new
' XmlNodeList object.
Dim nodeList As XmlNodeList = xmlDocument.GetElementsByTagName("Signature")
' Load the signature node.
signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Check the signature and return the result.
Return signedXml.CheckSignature()
End Function
End Module
Problém je ten, že aplikace hlásí tuto chybku : Podepisuji soubor.... pred ComputeSignature Pro zadaný podpisový algoritmus nelze vytvořit popis SignatureDescription. Údajně je problém s certifikátem, který byl vygenerován na stroji, kde je trochu jinak pojmenované konkrétní CSP (Cryptographic Service Provider) a tím pádem to nejde na jiném OS. Když se certifikát vygeneruje na WinXP, tak to bude fungovat jen na WinXP. Když na WinSBS2003, tak jen na něm atd. Řešil jste už někdo něco podobného? Je to ta příčina? Lze to nějak obejít? Děkuji mnohokrát. S pozdravem Max Devaine
|