解密响应仍然看起来错误编码

时间:2016-04-15 16:28:24

标签: c# asp.net encryption encoding saml

在处理解密SAML响应的代码之后,解密的字符串仍然看起来是加密的。我没有用正确的密钥解密它,加密类型,我附加的SAML响应损坏或我做错了什么?很明显,我不了解SAML和加密,足以让这个工作。

以下是我采取的步骤:

  1. 获得X509Certificate的私钥。
  2. 从XML节点获取加密的加密密钥:// xenc:EncryptedKey // xenc:CipherData // xenc:CipherValue。将其从Base64字符串转换为byte []。
  3. 使用私钥使用RSACryptoServiceProvider
  4. 解密加密密钥
  5. 使用了正确的加密方法:128 AES
  6. 使用步骤3中的解密密钥和加密算法从节点解密密码值:// xenc:EncryptedData // xenc:CipherData // xenc:CipherValue
  7. 使用Encoding.UTF8.GetString将解密数据转换为字符串。
  8. 结果如下所示:

      

    CJ | = 9 \ U0003 \ u001f_]bLJ8DE\ u001c = /指p \ u001f \ u0012 \ u0005(@mƇG\ u000eh.f \

    SAML响应(更改的值):

    <?xml version="1.0" encoding="UTF-8"?>
    <saml2p:Response xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://cct.bananaqa.net/SignIn/SamlAcs" ID="_584d6720576184d6a6f7c396f850b019" InResponseTo="Banana_7a26613a-b24e-461c-af39-b5ea8e11be89" IssueInstant="2016-04-13T18:10:00.709Z" Version="2.0">
        <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://scb1.cct.edu/idp/shibboleth</saml2:Issuer>
        <saml2p:Status>
            <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></saml2p:Status>
        <saml2:EncryptedAssertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
            <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="_4cd6916c8c1adc98c371a202c6c50f4f" Type="http://www.w3.org/2001/04/xmlenc#Element">
                <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" />
                <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                    <xenc:EncryptedKey Id="_aa1cb5932dd3ed1a5d968e09f41c79e8" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                        <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                            <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" />
                        </xenc:EncryptionMethod>
                        <ds:KeyInfo>
                            <ds:X509Data>
                                <ds:X509Certificate>MIIFODCCBCCgAwIBAgIJAOqAYZiaSD9SMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2.......BgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4wMwYDVR0RBCwwKoIUKi5hd2FyZHNwcmluZy1xYS5uZXSCEmF3YXJkc3ByaW5nLXFhLm5ldDAdBgNVHQ4EFgQUADqtjmhLN8HW6DDSOJ5PE2UVNKgwDQY.......Eh6G+GMByWVvSi80WXqnzV2oGTthFx3a2hyT3ndcr9RL17GE7wT5nw=</ds:X509Certificate>
                            </ds:X509Data>
                        </ds:KeyInfo>
                        <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                            <xenc:CipherValue>......w8QEZG0qI/asmzbIDcP4ahkfeKQ96pUDg7xTtcPhKseRlOxUW7alwe2PHVYP9O0bWWxz/4Ih6kvl2cVPDql6QRpJAimmdY...==</xenc:CipherValue>
                        </xenc:CipherData>
                    </xenc:EncryptedKey>
                </ds:KeyInfo>
                <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
                    <xenc:CipherValue>.........SEGgqL4Kxr/Ddon78edBK4tSLUyLS12bmYHKQQRCauL9kuIskAQJdx8dMEW0dKC+r+n445Gc5k2fGuvIReIKRU4SgUloWhqme29SYC3La5t1k9QvGFuh7qc1/KrH/UAdtA47NfnxE4ZXdjTmAAwxrf41ARHFCEb5it9F8zvv21vfkACExYVQFY8Kgcww2augZldehH/Ycx4IdDVgGQmLz46HGrHfFM3y9Yy1GET1jELQ/R/HLc35KbFdzHa8fxKB4/boS+Yp2e6Sme62FCVJkSljP1XOGhfX/K+p6X67YR9Atyqova4UqNP+8Fv8qAlPM5kQC75WqKI2LtpjvngTG5MjqCUphZM/wKFKWFjH8D5YatK31xIcG9hqdxpDcq3Eh84tRPWKG+WF2Rl3kmjCy1XvyTPhcAqGna/BRtqcrtFrDY4GyOAJTtj.......</xenc:CipherValue>
                </xenc:CipherData>
            </xenc:EncryptedData>
        </saml2:EncryptedAssertion>
    </saml2p:Response>
    

    整个代码块:

    using System;
    using System.IO;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Cryptography.Xml;
    using System.Text;
    using System.Xml;
    
    namespace Service.SSO
    {
    public class Saml2DecryptResponse
    {
        private XmlNamespaceManager _nsManager;
        private XmlDocument _xmlDoc;
    
        public Saml2DecryptResponse(XmlDocument xmlDocument)
        {
            _xmlDoc = xmlDocument;
    
            _nsManager = new XmlNamespaceManager(_xmlDoc.NameTable);
            _nsManager.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
            _nsManager.AddNamespace("saml", "urn:oasis:names:tc:SAML:2.0:assertion");
            _nsManager.AddNamespace("samlp", "urn:oasis:names:tc:SAML:2.0:protocol");
            _nsManager.AddNamespace("xenc", "http://www.w3.org/2001/04/xmlenc#");
        }
    
        public XmlNode GetDecryptedAssertion(X509Certificate2 myCert)
        {
            RSACryptoServiceProvider privateCsp = (RSACryptoServiceProvider)myCert.PrivateKey;
    
            // load the xmlDoc
            EncryptedXml encXml = new EncryptedXml(_xmlDoc);
            XmlElement encryptedDataElement = _xmlDoc.GetElementsByTagName("xenc:EncryptedData")[0] as XmlElement;
            EncryptedData encryptedData = new EncryptedData();
            encryptedData.LoadXml(encryptedDataElement);
    
            //get your cipher data from the encrypted assertion key info
            byte[] cipherBytes = GetKeyCipherValue();
    
            // use the RSACryptoServiceProvider to decrypt it  
            var symKey = privateCsp.Decrypt(cipherBytes, true);
    
            // get the assertion data
            byte[] dataCipherBytes = GetEncryptedAssertionData();
    
            // and the encryption method
            string encMethod = GetEncryptionMethod();
    
            // build your symmetric algorythm, used to decrypt your assertion data
            SymmetricAlgorithm symAlg = null;
            symAlg = GetAlgorithm(encMethod);
            symAlg.IV = encXml.GetDecryptionIV(encryptedData, encMethod);
    
            // decrypt the assertion data
            byte[] decryptedAssertionData = DecryptBytes(symAlg, dataCipherBytes, symKey, symAlg.IV);
            string rawText = Encoding.UTF8.GetString(decryptedAssertionData);
    
            // clean up the unencrypted text
            int samlStart = rawText.IndexOf("<saml:Assertion");
            int samlEnd = rawText.IndexOf("</saml:Assertion>") + 17 - samlStart;
            string cleanText = rawText.Substring(samlStart, samlEnd);
    
            // turn it into an xml element and return it
            XmlDocumentFragment fragment = _xmlDoc.CreateDocumentFragment();
            fragment.InnerXml = cleanText;
            return fragment;
        }
    
        public static byte[] DecryptBytes(SymmetricAlgorithm algorithm, byte[] encryptedData, byte[] keyBytes, byte[] iv)
        {
            byte[] plainTextBytes;
    
            int decryptedBytesCount;
    
            using (var decryptor = algorithm.CreateDecryptor(keyBytes, iv))
            {
                using (var memoryStream = new MemoryStream(encryptedData))
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        plainTextBytes = new byte[encryptedData.Length];
                        decryptedBytesCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
    
                        memoryStream.Close();
                        cryptoStream.Close();
                    }
                }
            }
    
            return plainTextBytes;
        }
    
        public byte[] GetKeyCipherValue()
        {
            var node = GetNode("//xenc:EncryptedKey//xenc:CipherData//xenc:CipherValue");
            return Convert.FromBase64String(node.InnerText);
        }
    
        public byte[] GetEncryptedAssertionData()
        {
            var node = GetNode("//xenc:EncryptedData//xenc:CipherData//xenc:CipherValue");
            return Convert.FromBase64String(node.InnerText);
        }
    
        public string GetEncryptionMethod()
        {
            XmlNode node = GetNode("//xenc:EncryptionMethod");
            return node.Attributes["Algorithm"].Value.Trim();
        }
    
        public XmlNode GetNode(string xpath)
        {
            return _xmlDoc.SelectSingleNode(xpath, _nsManager);
        }
    
        private static SymmetricAlgorithm GetAlgorithm(string symAlgUri)
        {
            SymmetricAlgorithm symAlg = null;
    
            switch (symAlgUri)
            {
                case EncryptedXml.XmlEncAES128Url:
                case EncryptedXml.XmlEncAES128KeyWrapUrl:
                    symAlg = SymmetricAlgorithm.Create("Rijndael");
                    symAlg.KeySize = 128;
                    symAlg.Padding = PaddingMode.None;
                    break;
                case EncryptedXml.XmlEncAES192Url:
                case EncryptedXml.XmlEncAES192KeyWrapUrl:
                    symAlg = SymmetricAlgorithm.Create("Rijndael");
                    symAlg.KeySize = 192;
                    break;
                case EncryptedXml.XmlEncAES256Url:
                case EncryptedXml.XmlEncAES256KeyWrapUrl:
                    symAlg = SymmetricAlgorithm.Create("Rijndael");
                    symAlg.KeySize = 256;
                    break;
                case EncryptedXml.XmlEncDESUrl:
                    symAlg = SymmetricAlgorithm.Create("DES");
                    break;
                case EncryptedXml.XmlEncTripleDESUrl:
                case EncryptedXml.XmlEncTripleDESKeyWrapUrl:
                    symAlg = SymmetricAlgorithm.Create("TripleDES");
                    break;
                default:
                    throw new ArgumentException("symAlgUri");
            }
    
            return symAlg;
        }
    }
    }
    

    代码主要来自:http://www.bjw.co.nz/developer/misc/82-general-dev/1203-decrypting-a-saml-encrypted-assertion

1 个答案:

答案 0 :(得分:-2)

所以问题在于我如何解密令牌。在下面的文章中找到了解决方案:

https://msdn.microsoft.com/en-us/library/aa967562(v=vs.90).aspx

希望它可以帮助其他人遇到同样的问题。