2017-07-23 30 views
2

我正在嘗試爲重定向綁定創建一個SAML AuthnRequest。我的SAML重定向綁定簽名有什麼問題?

這是我的(匿名)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> 

我有一個的RelayState:

RelayState: 821eea8785134bbc8263be6838eda19d 

而且SigAlg是http://www.w3.org/2001/04/xmldsig-more#rsa-sha256

我放氣,然後採用base64編碼,然後URL - 編碼請求。 (癟,base64編碼結果在SAMLTool Decoder檢查出來。)

結果字符串被用於創建簽名,然後看起來是這樣的:

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

我試圖創建與OpenSSL的簽名:

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

,並用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); 

和(也與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); 

這三種方法都產生相同的base64編碼字符串(除了在OpenSSL結果換行符)。

不幸的是,當我嘗試與經紀人一起使用時,他們說簽名有問題,並且當我向SAMLTool AuthnRequest signing tool提供相同的信息時,我得到了不同的結果。

我在做什麼錯?

+0

從C#代碼的第一個塊替換

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

這是一個編程的問題。我建議你發佈在StackOverflow – pedrofb

+0

從你的例子不清楚你是否簽署了base64版本或原始的xml。你能澄清嗎?我認爲你想要簽署的XML,而不是它的base64。 – explunit

+0

@explunit:根據[規範](https://www.oasis-open.org/committees/download.php)對完整字符串'SAMLRequest = ...&RelayState = ...&SigAlg = ...'進行簽名/56780/sstc-saml-bindings-errata-2.0-wd-06-diff.pdf)第3.4.4.1節第二項3. – Miel

回答

0

問題是需要簽名的字符串是在一個文本文件中,其中(as a rule)在每行的末尾包含一個換行符。但是,應該簽名的字符串不包含換行符。

這意味着解決方案是從字符串中修剪換行符,例如,通過用

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