Stack Overflow en español Asked by fsigu on December 20, 2021
Hols amigos estoy haciendo una aplicacion, que tiene que firmar un archivo xml mediante el algoritmo sha256, usando un archivo .pfx de firma electronica.
el codigo que tengo es el siguiente
public void Firmar()
{
string archivoFirma = @"C:archivosfirma.pfx";
X509Certificate2 cert = new X509Certificate2(archivoFirma, "ClaveFirma", X509KeyStorageFlags.Exportable);
RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)cert.PrivateKey;
CspParameters cspParams = new CspParameters();
cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(@"c:archivosFA076.xml");
SignXml(xmlDoc, crypt);
xmlDoc.Save(@"c:archivosFA076Firmado.xml");
}
public void SignXml(XmlDocument xmlDoc, RSA rsaKey)
{
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (rsaKey == null)
throw new ArgumentException("Key");
SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.SigningKey = rsaKey;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
Reference reference = new Reference();
reference.Uri = "";
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signedXml.AddReference(reference);
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
Justo al ejecutar la linea
signedXml.ComputeSignature();
me da el siguiente mensaje de error
Algoritmo especificado no es válido
Alguien de pronto que me pueda ayudar indicando que estoy haciendo mal??
X509Certificate2
carga la clave privada del archivo pfx file en el Microsoft Enhanced Cryptographic Provider v1.0 (provider type 1 a.k.a. PROV_RSA_FULL)
el cual no tiene soporte para SHA-256
.
Existen otros proveedores de Crypto tales como Microsoft Enhanced RSA and AES Cryptographic Provider (provider type 24 a.k.a. PROV_RSA_AES)
que sí tienen soporte de SHA-256
.
Aquí está la lista de proveedores y sus códigos.
Modifico tu código para cambiar el proveedor.
public void Firmar()
{
string archivoFirma = @"C:archivosfirma.pfx";
X509Certificate2 cert = new X509Certificate2(archivoFirma, "ClaveFirma", X509KeyStorageFlags.Exportable);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(@"c:archivosFA076.xml");
SignXml(xmlDoc, cert);
xmlDoc.Save(@"c:archivosFA076Firmado.xml");
}
public void SignXml(XmlDocument xmlDoc, X509Certificate2 cert)
{
if (xmlDoc == null)
throw new ArgumentException("xmlDoc");
if (cert == null)
throw new ArgumentException("Cert");
var exportedKeyMaterial = cert.PrivateKey.ToXmlString( /* includePrivateParameters = */ true);
var key = new RSACryptoServiceProvider(new CspParameters(24 /* PROV_RSA_AES */));
key.PersistKeyInCsp = false;
key.FromXmlString(exportedKeyMaterial);
SignedXml signedXml = new SignedXml(xmlDoc);
signedXml.SigningKey = key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
}
Answered by Sergio Parra Guerra on December 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP