您好我是SAML和SSO技术的新手。我正在尝试使用签名和加密的断言创建有效的SAML响应。我创建了一个签名的SAML响应,但我无法加密断言并创建标记。我生成的SAML响应是,
<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_88a4cf19-6f41-46ee-9dc3-98ac80168bd9" Version="2.0" IssueInstant="2015-03-26T11:43:13.4468624Z" Destination="Test1" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
<saml:Issuer>Test</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#_49bc8835-7c9a-4ee2-8087-7cfcbe48375f">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>My4iQVO1Oy3i6jV+Jlp0czX0mpA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>GWfdKMCHbiqq6OhyHQ0y2LoDQkmC95fs3SKWyPMzu6jSjbf6vrMRFCrlch+DU1k3+sfsj1tFkJNMPKpxZIx2XksjnEQv3Hdqy7oPSoGiODmrky7CTKEdYbCQqu6a8dwNBLNQTClYAgDz/m5yfbFlJNPy9TtsCl2l1R/qg6dzVkA=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIBwTCCAS6gAwIBAgIQr71oSHfrBKpKpRUTWmBFCzAJBgUrDgMCHQUAMCMxITAfBgNVBAMeGABCAEYASQBcAGQAcwBwAGUAaQBnAGgAdDAeFw0xMDAyMTkxMzI4MzlaFw0xMTAyMTkxOTI4MzlaMCMxITAfBgNVBAMeGABCAEYASQBcAGQAcwBwAGUAaQBnAGgAdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxXmIj8FBaL+94B/fNsBcoNZZraicGsm5+8VtWQIaGdM65q6vgDSQAg4zOkTQCqKh2vlN2NHSZb2XjcrUTWm2Vb279dvkOZfZ1mdQeLjM2LbXvrY4e7qK1dhZy9gZ3Mhvuk3cKPwwPsLNFifOt6OsS8ZzK7/PC+uUKznZtRsCAwEAATAJBgUrDgMCHQUAA4GBADGP1MjZm28GdYy3mQGprHQNDn8fIyBQvhwVwl4SVPxYDTKG7OsUC/QDUzy8vGXm+9qd2Es5creZS1DTAweC60JsJLdmp631FnbG4xJOCRHbR0HWyruhGkN6wPJ0RyJbdUrAcEPG4cfcYwl3oBeL48MfUD56UC0jSfBezUvnOMBX</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<saml:Assertion Version="2.0" ID="_49bc8835-7c9a-4ee2-8087-7cfcbe48375f" IssueInstant="2015-03-26T11:43:13.6835615Z">
<saml:Issuer>Test</saml:Issuer>
<saml:Subject>
<saml:NameID NameQualifier="TestDomain">TestSubject</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2015-03-26T11:48:13.7304370Z" Recipient="Test1" />
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2015-03-26T11:43:13.6835615Z" NotOnOrAfter="2015-03-26T11:48:13.6835615Z">
<saml:AudienceRestriction>
<saml:Audience>TestDomain</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2015-03-26T11:43:13.6835615Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>AuthnContextClassRef</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="UserId" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xmlns:q1="http://www.w3.org/2001/XMLSchema" p7:type="q1:string" xmlns:p7="http://www.w3.org/2001/XMLSchema-instance">1000001</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="UserName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xmlns:q2="http://www.w3.org/2001/XMLSchema" p7:type="q2:string" xmlns:p7="http://www.w3.org/2001/XMLSchema-instance">Manish Pandey</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
任何人都可以建议任何方法来实现这个目标吗?
答案 0 :(得分:3)
它取决于您要使用哪种加密...基本上您必须加密已签名的断言并用EncryptedAssertion节点替换断言节点。
我建议使用对称和非对称加密。 使用Symmetric密钥加密整个断言节点,然后使用非对称(即证书公钥/私钥加密对称密钥)。我使用客户端的证书公钥来加密对称密钥,因此只有他们可以使用他们的私钥解密。
我还指定了我想在web.config中使用的证书......
string samlResponseXml = '<SAML Response Message>'
XmlDocument loginResponseXmlDocument = new XmlDocument();
loginResponseXmlDocument.LoadXml(samlResponseXml);
// Add name spaces
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(loginResponseXmlDocument.NameTable);
namespaceManager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
namespaceManager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
namespaceManager.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
namespaceManager.AddNamespace("xenc", "http://www.w3.org/2001/04/xmlenc#");
Encrypt(loginResponseXmlDocument, namespaceManager);
private void Encrypt(XmlDocument document, XmlNamespaceManager namespaceManager)
{
// create symmetric key
var key = new RijndaelManaged();
key.BlockSize = 128;
key.KeySize = 256;
key.Padding = PaddingMode.ISO10126;
key.Mode = CipherMode.CBC;
XmlElement assertion = (XmlElement)document.SelectSingleNode("/samlp:Response/saml:Assertion", namespaceManager);
EncryptedXml eXml = new EncryptedXml();
byte[] encryptedElement = eXml.EncryptData(assertion, key, false);
EncryptedData edElement = new EncryptedData
{
Type = EncryptedXml.XmlEncAES256Url
};
const string encryptionMethod = EncryptedXml.XmlEncAES256Url;
edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);
edElement.CipherData.CipherValue = encryptedElement;
// edElement = EncryptedData
// Now encrypt symmetric key
string certificateDn = ConfigurationManager.AppSettings["CertificateDN"];
X509Certificate2 x509Certificate = GetCertificate(certificateDn);
RSACryptoServiceProvider rsa = x509Certificate.PublicKey.Key as RSACryptoServiceProvider;
byte[] cryptedData = rsa.Encrypt(key.Key, false);
//string data = Convert.ToBase64String(cryptedData);
//byte[] encryptedKey = EncryptedXml.EncryptKey(key.Key, rsa, true);
EncryptedKey ek = new EncryptedKey();
ek.CipherData = new CipherData(cryptedData);
ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
//EncryptedData edkey = new EncryptedData();
//string data1 = Convert.ToBase64String(encryptedKey);
//edkey.CipherData.CipherValue = System.Text.Encoding.Unicode.GetBytes(data);
rsa.Clear();
XmlDocument encryptedAssertion = new XmlDocument();
// Add name spaces
XmlDeclaration xmlDeclaration = encryptedAssertion.CreateXmlDeclaration("1.0", "UTF-8", null);
XmlElement encryptedRoot = encryptedAssertion.DocumentElement;
encryptedAssertion.InsertBefore(xmlDeclaration, encryptedRoot);
XmlElement encryptedAssertionElement = encryptedAssertion.CreateElement("saml", "EncryptedAssertion", "urn:oasis:names:tc:SAML:2.0:assertion");
encryptedAssertion.AppendChild(encryptedAssertionElement);
string xml = edElement.GetXml().OuterXml;
XmlElement element = AddPrefix(xml, "xenc", "http://www.w3.org/2001/04/xmlenc#");
var encryptedDataNode = encryptedAssertion.ImportNode(element, true);
encryptedAssertionElement.AppendChild(encryptedDataNode);
xml = ek.GetXml().OuterXml;
element = AddPrefix(xml, "xenc", "http://www.w3.org/2001/04/xmlenc#");
var encryptedKeyNode = encryptedAssertion.ImportNode(element, true);
encryptedAssertionElement.AppendChild(encryptedKeyNode);
var root = document.DocumentElement;
var node = root.OwnerDocument.ImportNode(encryptedAssertionElement, true);
root.RemoveChild(assertion);
root.AppendChild(node);
}
断言加密后......这就是它的样子:
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Destination="https://aviva-rpt.distribution-technology.com" ID="_fba2f5af-a430-8001-5cb8-9714f3aeb4bc"
IssueInstant="2015-02-04T16:32:33.446Z" Version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://www.client.sds</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<saml:EncryptedAssertion>
<xenc:EncryptedData>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>zjAgkZ=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
<xenc:EncryptedKey>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<xenc:CipherData>
<xenc:CipherValue>DyA22==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
</saml:EncryptedAssertion>
</samlp:Response>