He visto otras publicaciones aquí con respecto a este problema y ninguno de ellos parece abordar mi situación.SignedXml checksignature devuelve falso
He intentado verificar una afirmación de SAML durante la última semana y tengo 2 clientes que me han enviado SAML pero no puedo verificarlo.
El proceso principal es obtener una aserción codificada en base64 y decodificarla. Cargarlo en un XmlDocment con PreserveWhitespace = true.
El método es verificar
public static bool Verify(X509Certificate2 cert, XmlElement xmlElement, SignedXml signedXml)
{
bool flag;
try
{
KeyInfo keyInfo = new KeyInfo();
var clause = new KeyInfoX509Data(cert);
keyInfo.AddClause(clause);
XmlElement signatureElement = GetSignatureElement(xmlElement);
if (signatureElement == null)
{
string message = "The XML does not contain a signature.";
throw new SAMLSignatureException(message);
}
signedXml.LoadXml(signatureElement);
if (keyInfo != null)
{
signedXml.KeyInfo = keyInfo;
}
SetSigningKeyFromKeyInfo(signedXml);
flag = signedXml.CheckSignature(cert.PublicKey.Key);
}
catch (Exception exception)
{
throw new SAMLSignatureException("Failed to verify the XML signature.", exception);
}
return flag;
}
private static void SetSigningKeyFromKeyInfo(SignedXml signedXml)
{
IEnumerator enumerator = signedXml.KeyInfo.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Current is KeyInfoX509Data)
{
var current = (KeyInfoX509Data) enumerator.Current;
if (current.Certificates.Count != 0)
{
var certificate = (X509Certificate) current.Certificates[0];
var certificate2 = new X509Certificate2(certificate);
AsymmetricAlgorithm key = certificate2.PublicKey.Key;
signedXml.SigningKey = key;
return;
}
}
else
{
if (enumerator.Current is RSAKeyValue)
{
var value2 = (RSAKeyValue) enumerator.Current;
signedXml.SigningKey = value2.Key;
return;
}
if (enumerator.Current is DSAKeyValue)
{
var value3 = (DSAKeyValue) enumerator.Current;
signedXml.SigningKey = value3.Key;
return;
}
}
}
throw new SAMLSignatureException("No signing key could be found in the key info.");
}
tengo el certificado del cliente que he leído desde Web.Config (almacenado su cadena como base64) XmlElement es el elemento firmado, SignedXml es un objeto que SignedXml se creó con el nuevo SignedXml (xmlElement)
Ambos clientes obtienen un falso devuelto por el signo de verificación, pero cuando creo mi propio saml firmado con mi certificado, se devuelve verdadero.
¿Qué me falta aquí?
EDIT: Sí, tanto de los clientes están en Java y he publicado el método SetSigningKeyFromKeyInfo
Déjeme adivinar, ¿la afirmación que recibe ha sido generada en un lenguaje que no es de.net, como Java? –
¿Qué hace 'SetSigningKeyFromKeyInfo (signedXml);' do? –
Cuando ha codificado base64 la aserción, ¿puede volcar el xml en un archivo y compararlo con una de sus propias afirmaciones para verificar inconsistencias estructurales (sutiles)? –