2017-07-23 2 views
2

J'essaye de créer un SAML AuthnRequest pour la liaison de redirection.Quel est le problème avec ma signature pour une liaison de redirection SAML?

Ceci est mon (anonymisées) AuthRequest:

<samlp:AuthnRequest AssertionConsumerServiceURL="https://tempuri.org/sp/AssertionConsumerService" 
        Destination="https://anothertempuri.org/broker/sso" 
        ID="a18471d18a93430a8b97b05989ae238f" 
        IssueInstant="2017-07-23T14:15:26Z" 
        ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 
        Version="2.0" 
        xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
        xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> 
    <saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">...</saml:Issuer> 
</samlp:AuthnRequest> 

J'ai RelayState:

RelayState: 821eea8785134bbc8263be6838eda19d 

Et le SigAlg est http://www.w3.org/2001/04/xmldsig-more#rsa-sha256

Je dégonfler, puis base64 encode, puis URL -encode la requête. (Le résultat dégonflé, codé en base64 vérifie au SAMLTool Decoder.)

La chaîne résultante à utiliser pour créer la signature ressemble alors quelque chose comme ceci:

SAMLRequest=fZL...5MP&RelayState=821eea8785134bbc8263be6838eda19d&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256 

J'ai essayé de créer la signature avec OpenSSL:

openssl sha -sha256 -sign example.pem -out signed.sha256 theStringInAFile.txt 
openssl base64 -in signed.sha256 

et C#

byte[] data = File.ReadAllBytes(FileToSign); 
data = SignBytes(data); 
X509Certificate2 certificate = new X509Certificate2(CertFile, Password); 
using (RSA rsa = certificate.GetRSAPrivateKey()) 
{ 
    data = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); 
} 
signedData = Convert.ToBase64String(data, Base64FormattingOptions.None); 

Et (aussi avec C#):

var signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); 
HashAlgorithm hashAlg = signatureDescription.CreateDigest(); 
hashAlg.ComputeHash(Encoding.UTF8.GetBytes(signString)); 

X509Certificate2 certificate = new X509Certificate2(CertFile, Password); 

AsymmetricSignatureFormatter asymmetricSignatureFormatter = signatureDescription.CreateFormatter(certificate.GetRSAPrivateKey()); 

byte[] signatureValue = asymmetricSignatureFormatter.CreateSignature(hashAlg); 
return Convert.ToBase64String(signatureValue); 

Les trois méthodes aboutissent à la même chaîne base64 (sauf pour les nouvelles lignes dans le résultat de OpenSSL).

Malheureusement, lorsque j'essaie d'utiliser ceci avec le courtier, ils disent que quelque chose ne va pas avec la signature, et quand je donne la même information au SAMLTool AuthnRequest signing tool, j'obtiens un résultat différent.

Qu'est-ce que je fais mal?

+0

Ceci est un problème de programmation. Je vous suggère de publier dans StackOverflow – pedrofb

+0

il n'est pas clair de votre exemple si vous signez la version base64 ou le xml d'origine. Pouvez-vous clarifier? Je pense que vous voulez signer le XML, pas le base64 de celui-ci. – explunit

+0

@explunit: Je signe la chaîne complète 'SAMLRequest = ... & RelayState = ... & SigAlg = ...' selon [la spécification] (https://www.oasis-open.org/committees/download.php /56780/sstc-saml-bindings-errata-2.0-wd-06-diff.pdf) section 3.4.4.1, deuxième élément 3. – Miel

Répondre

0

Le problème est que la chaîne qui doit être signée est dans un fichier texte, qui (as a rule) inclut un retour à la ligne à la fin de chaque ligne. La chaîne qui doit être signée n'inclut toutefois pas le saut de ligne. Cela signifie que la solution consiste à couper la nouvelle ligne de la chaîne, par ex. en remplaçant

byte[] data = File.ReadAllBytes(FileToSign); 

du premier bloc de code C# avec

string signString = File.ReadAllText(FileToSign); 
signString = signString.TrimEnd('\r', '\n'); 
byte[] data = Encoding.UTF8.GetBytes(signString);