2
I use the class x509certificate
of C# to read a certificate A3 for the signature of XML, occurs that it was necessary to renew the certificate and at first nothing changed, continued same type, but trying to sign now is giving the error:
"The key set is not defined"
The error occurs at the exact moment I try to read the private key of it using the "X509Cert.PrivateKey
".
Follows code:
////Seleciona o armazenamento de certificado usado pelo usuário atual.
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection collection1 = (X509Certificate2Collection)collection.Find(X509FindType.FindBySubjectDistinguishedName, _xnome, false);
if (collection1.Count == 0)
{
resultado = 1;
}
else
{
//Certificado ok
X509Cert = collection1[0];
string x;
//Retorna informações do algoritmo para esse certificado X.509v3 como uma cadeia de caracteres. (Herdado de X509Certificate.)
x = X509Cert.GetKeyAlgorithm().ToString();
//Cria um novo documento xml
XmlDocument doc = new XmlDocument();
//Formata o documento para ignorar espaços
doc.PreserveWhitespace = false;
try
{
//Carregar o arquivo XML pelo nome
doc.LoadXml(_conteudoXml);
List<XmlNode> nodes = new List<XmlNode>();
foreach (XmlNode node in doc.SelectNodes("//*['Signature']"))
{
nodes.Add(node);
}
foreach (XmlNode node in nodes)
{
if (Convert.ToString(node.Name) == "Signature")
{
node.ParentNode.RemoveChild(node);
}
}
//Verifica se a tag a ser assinada existe é única
int qtdeRefUri = doc.GetElementsByTagName(_RefUri).Count;
if (qtdeRefUri == 0)
{
//A URI indicada não existe
resultado = 2;
}
//Exsiste mais de uma tag a ser assinada
else
{
try
{
for (int i = 0; i < qtdeRefUri; i++)
{
//Cria o objeto SignedXml.
SignedXml signedXml = new SignedXml(doc);
//Define o objeto de AsymmetricAlgorithm que representa a chave particular associada com um certificado.
signedXml.SigningKey = X509Cert.PrivateKey;
//Cria a referência a ser assinada
Reference reference = new Reference();
//Pega o uri que deve ser assinada
XmlAttributeCollection _Uri = doc.GetElementsByTagName(_RefUri).Item(i).Attributes;
foreach (XmlAttribute _atributo in _Uri)
{
//Verifica se a URI informada possui o Id
if (_atributo.Name == "Id")
{
reference.Uri = "#" + _atributo.InnerText;
}
}
//Adiciona o envelopamento para referência
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
//Adiciona a Canonatização para referência
XmlDsigC14NTransform c14 = new XmlDsigC14NTransform();
reference.AddTransform(c14);
//Adiciona referência para o SignedXml objeto.
signedXml.AddReference(reference);
//Cria novo objeto KeyInfo
KeyInfo keyInfo = new KeyInfo();
//Carrega o certificado e insere KeyInfoX509Data
keyInfo.AddClause(new KeyInfoX509Data(X509Cert));
//Adiciona Keyinfo para o SignedXml.
signedXml.KeyInfo = keyInfo;
//Adiciona a assinatura no XML com autenticação por ser chave privada
signedXml.ComputeSignature();
//Referencia xml, coloca assinatura e salva
XmlElement xmlDigitalSignature = signedXml.GetXml();
//Assina no final da Uri informada.
XmlElement xmlElement = doc.GetElementsByTagName(_RefUri)[i] as XmlElement;
xmlElement.ParentNode.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
XMLDoc = new XmlDocument();
XMLDoc.PreserveWhitespace = false;
XMLDoc = doc;
}
}
catch (CryptographicException ex)
{
resultado = 3;
}
}
I did a search, but I did not find anything related to this. I also tried to check if it was not access permission, but the key is normal.
Check in the certificate properties if it is valid, search for new chains
v7
and install.– rubStackOverflow
Try to change
signedXml.SigningKey = X509Cert.PrivateKey
forsignedXml.SigningKey = certificate.GetRSAPrivateKey();
– Henrique