Rat*_*lle 5 xml saml-2.0 xml-signature itfoxtec-identity-saml2
我通过HTTP重定向绑定收到SAML请求,SAML请求的内容如下所示
{ "SigAlg"=> " http://www.w3.org/2000/09/xmldsig#rsa-sha1 ", "SAMLRequest"=>"lVLLaoQwFP0VyT5jEqPG4AiFoSDMtNApXXQzxDxaQRObRDqfX3XoolAKXd7DPQ/uuXUQ4zDxo3tzc3zSH7MOMWkPe3DpcixzVVVQl4RBqoiCncEYEmkoY7k00hCQvGgfemf3gOwQSNoQZt3aEIWNC4RwCRGGiD6jkmPMs2KHUPYKksPi0lsRN + Z7jFPgafqpvejtbtQpSK7jYAPfsu3B7C13IvSBWzHqwKPk57vTkS + WfPIuOukG0NSbub9R/yaJELRfzUGzrhmtFut15qdeeheciY926K2u05toUz8sIu0huXd + FPFv9RXpFTTbKp/WA4WobQT/jEYrykwhNaQ66yDNMwY7wijEtMCmysqqo6xOb8Ga + tbjWYe1jtYqfW0uCucoYwWCHS3F0kRGoajWTpAiiJRZJRmu01 Y3 + CPt2i + AA =="}
它还具有Signature值
WkDaGzC6vPTlzh + EnFA5/8IMmV7LviyRh2DA5EHF0K0nl + xzBlKfNCYRnunpwoEvGhereGdI5xBpv + mc9IguiCaLZSZjDh6lIDdpvctCnmSNzORqzWQwQGeZ9vjgtCLjUn35VZLNs3WgEqbi2cL + ObrUDS2gV1XvBA3Q3RRhoDmi + XE89Ztnd1cNpR3XdA + EL2ENbMI2XAD9qSgMufUJY/3GBBpT7Vg1ODtPxBudq + sXrgPh/+ + WtUUitLkkfC8tdRTCS1EZPv h27I5g/VNza23Xl8w2HdAuYP0F2FjREo8VV2aUtaOUd/jAF9 + bfkGV93y1PzFttLxdBbFoxp6qBg ==
但我不明白如何验证此签名是否正确.
有关SAML绑定的第3.4.4.1节https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
To construct the signature, a string consisting of the concatenation of the RelayState (if present),
SigAlg, and SAMLRequest (or SAMLResponse) query string parameters (each one URLencoded)
is constructed in one of the following ways (ordered as below):
SAMLRequest=value&RelayState=value&SigAlg=value
SAMLResponse=value&RelayState=value&SigAlg=value
Run Code Online (Sandbox Code Playgroud)
我试过这个方法但是
我使用私钥生成的签名与我从SP收到的签名不匹配.(上面发布)
此外,我无法使用私钥解密签名的邮件(我假设签名是使用我联合的公共创建的.)
<samlp:LogoutRequest ID="_36167d94-d868-4c04-aee3-8bbd4ed91317" Version="2.0" IssueInstant="2017-01-05T16:21:55.704Z" Destination="https://werain.me/" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">urn:federation:MicrosoftOnline</Issuer><NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">4948f6ce-4e3b-4538-b284-1461f9379b48</NameID><samlp:SessionIndex>_eafbb730-b590-0134-a918-00d202739c81</samlp:SessionIndex></samlp:LogoutRequest>Run Code Online (Sandbox Code Playgroud)
这里有任何帮助.
SAML身份验证消息是具有嵌入(封装)XMLDSig签名或缩减编码签名的XML文档
包含XMLDSign签名
<samlp:LogoutRequest>
<...saml message...>
<ds:Signature>
<ds:SignedInfo />
<ds:SignatureValue />
<ds:KeyInfo />
</ds:Signature>
</samlp:LogoutRequest>
Run Code Online (Sandbox Code Playgroud)
<ds:SignatureValue>包含签名,<ds:SignedInfo>签名数据和对消息的引用,<ds:KeyInfo>通常包含带有签名者身份的X509Certificate,或者对该证书的引用
URL中的放缩编码
SAMLRequest=value&RelayState=value&SigAlg=value&Signature=value
Run Code Online (Sandbox Code Playgroud)
每个值都是url编码的
SAMLRequest=urlencode(base64(<samlp:LogoutRequest> <...saml message...> </samlp:LogoutRequest>))
Run Code Online (Sandbox Code Playgroud)
并且使用该算法在查询字符串算法的串联上完成签名 SigAlg
Signature = urlencode( base64 ( SigAlg ("SAMLRequest=value&RelayState=value&SigAlg=value")))
Run Code Online (Sandbox Code Playgroud)
SAML消息的数字签名
SAML消息使用发行者(SP)的私钥进行数字签名(未加密),并且可以使用SP的公钥进行验证.必须使用身份提供商(IdP)的私钥对SAML响应进行签名,并且SP可以使用IdP的公钥验证消息.
如果您充当IdP并且想要验证SP的SAML请求,则需要:
验证数字签名:使用签名与签名消息匹配的SP的公钥进行验证,以确保签名者的身份并且消息未被更改
授权请求:验证签名者的身份是否可以执行请求的操作.通常,您必须将序列号或证书主题与先前存在的列表进行匹配,或者验证证书是否由受信任的证书颁发机构颁发
生成SAML响应:使用SAML数据生成XML消息,并使用您的私钥对其进行签名以发送给SP
大多数编程语言都支持XMLDsig签名,但在您的情况下使用的是缩减的编码,这是SAML绑定的特定特征,因此如果您的SAML库不支持它,则必须手动验证签名.这些或多或少是根据规范遵循的步骤
//get params from query string
String samlrequest = getQueryParam("SAMLRequest");
String relaystate = getQueryParam("RelayState");
String sigalg = getQueryParam("SigAlg");
String signature = getQueryParam("Signature");
//The signature
byte signature[] = URLDecoder.decode(Base64.getDecoder().decode(signature ), "UTF-8");
//The signed data. build the following string checking if RelayState is null
//SAMLRequest=samlrequest&RelayState=relaystate&SigAlg=sigalg
byte signedData[] = concat(samlrequest,relaystate,sigalg);
//The signature algorithm could be "SHA1WithRSA" or "SHA1withDSA" depending on sigalg is http://www.w3.org/2000/09/xmldsig#rsa-sha1 or http://www.w3.org/2000/09/xmldsig#dsa-sha1
String signatureAlgorithm = extractSignatureAlgorithm(sigalg);
//get the public key of the SP. It must be registered before this process
PublicKey publicKey = ...
//Verify the signature
Signature sig = Signature.getInstance(signatureAlgorithm);
sig.initVerify(publicKey);
sig.update(signedData);
boolean verifies = sig.verify(signature);
Run Code Online (Sandbox Code Playgroud)