Как расшифровать EncryptedAssertion с помощью System.Cryptography

Поставщик Identity шифрует утверждение Saml, используя функции компонента pro

Dim encryptedSamlAssertion As New EncryptedAssertion(samlAssertion, encryptingCert, New System.Security.Cryptography.Xml.EncryptionMethod(SamlKeyAlgorithm.Aes256Cbc))

У поставщика услуг я пытаюсь расшифровать утверждение. Но я не могу использовать компонент Pro. Я должен использовать System.Security.Cryptography

  • X509Сертификат используется для шифрования и дешифрования
  • Aes256Cbc - алгоритм шифрования

Помогите, пожалуйста, предоставить мне больше информации о том, как я могу добиться расшифровки SamlAssertions с использованием алгоритма X509Certificate и Aes256Cbc.

1 ответ

Решение

Я использовал EncryptedXml для расшифровки своих утверждений. Вот мой код

EncryptedXmlWithPreconfiguredAsymmetricKey encXml = new EncryptedXmlWithPreconfiguredAsymmetricKey (_xmlDoc,_certificate);
while (_xmlDoc.GetElementsByTagName("EncryptedData").Count > 0)
{
    XmlElement encryptedDataElement = _xmlDoc.GetElementsByTagName("EncryptedData")[0] as XmlElement;
    EncryptedData encryptedData = new EncryptedData();
    encryptedData.LoadXml(encryptedDataElement);

    SymmetricAlgorithm symmKey = encXml.GetDecryptionKey(encryptedData, encryptedData.EncryptionMethod.KeyAlgorithm);
    symmKey.IV = encXml.GetDecryptionIV(encryptedData, encryptedData.EncryptionMethod.KeyAlgorithm);
    symmKey.Padding = encXml.Padding;
    symmKey.Mode = encXml.Mode;

    byte[] decryptedData = encXml.DecryptData(encryptedData, symmKey);
    encXml.ReplaceData(encryptedDataElement, decryptedData);
}

Я также переопределил метод GetDecryptionKey(), чтобы использовать предопределенный сертификат

public class EncryptedXmlWithPreconfiguredAsymmetricKey : EncryptedXml
    {
        public readonly X509Certificate2 _encryptionCert;
        public EncryptedXmlWithPreconfiguredAsymmetricKey(XmlDocument xmlDoc, X509Certificate2 encryptionCert) : base(xmlDoc)
        {
            _encryptionCert = encryptionCert;
        }

        public override SymmetricAlgorithm GetDecryptionKey(EncryptedData encryptedData, string symmetricAlgorithmUri)
        {
            if (encryptedData == null)
                throw new ArgumentNullException("encryptedData");

            if (encryptedData.KeyInfo == null)
                return null;
            IEnumerator keyInfoEnum = encryptedData.KeyInfo.GetEnumerator();
            KeyInfoRetrievalMethod kiRetrievalMethod;
            KeyInfoName kiName;
            KeyInfoEncryptedKey kiEncKey;
            EncryptedKey ek = null;

            while (keyInfoEnum.MoveNext())
            {
                kiName = keyInfoEnum.Current as KeyInfoName;

                kiRetrievalMethod = keyInfoEnum.Current as KeyInfoRetrievalMethod;

                kiEncKey = keyInfoEnum.Current as KeyInfoEncryptedKey;
                if (kiEncKey != null)
                {
                    ek = kiEncKey.EncryptedKey;
                    break;
                }
            }

            // if we have an EncryptedKey, decrypt to get the symmetric key
            if (ek != null)
            {
                // now process the EncryptedKey, loop recursively
                // If the Uri is not provided by the application, try to get it from the EncryptionMethod 
                if (symmetricAlgorithmUri == null)
                {
                    if (encryptedData.EncryptionMethod == null)
                        throw new CryptographicException("Cryptography_Xml_MissingAlgorithm");
                    symmetricAlgorithmUri = encryptedData.EncryptionMethod.KeyAlgorithm;
                }
                byte[] key = ek.CipherData.CipherValue;
                if (key == null)
                    throw new CryptographicException("Cryptography_Xml_MissingDecryptionKey");

                // Ignore any information about the asymmetric key in the XML, and just use our predefined certificate
                var rsaKey = (RSA)_encryptionCert.PrivateKey;

                byte[] symkey = DecryptKey(key, rsaKey, false);

                SymmetricAlgorithm symAlg = (SymmetricAlgorithm)CryptoConfig.CreateFromName(symmetricAlgorithmUri);
                symAlg.Key = symkey;
                return symAlg;
            }
            return null;
        }
    }
private class Saml2SSOSecurityTokenResolver : SecurityTokenResolver
{
    List<SecurityToken> _tokens;

    public Saml2SSOSecurityTokenResolver(List<SecurityToken> tokens)
    {
        _tokens = tokens;
    }
    protected override bool TryResolveSecurityKeyCore(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause, out System.IdentityModel.Tokens.SecurityKey key)
    {
        var token = _tokens[0] as X509SecurityToken;

        var myCert = token.Certificate;

        key = null;

        var ekec = keyIdentifierClause as EncryptedKeyIdentifierClause;

        if (ekec != null)
        {
            if (ekec.EncryptionMethod == "http://www.w3.org/2001/04/xmlenc#rsa-1_5")
            {
                var encKey = ekec.GetEncryptedKey();
                var rsa = myCert.PrivateKey as RSACryptoServiceProvider;
                var decKey = rsa.Decrypt(encKey, false);
                key = new InMemorySymmetricSecurityKey(decKey);
                return true;
            }

            var data = ekec.GetEncryptedKey();
            var id = ekec.EncryptingKeyIdentifier;
        }

        return true;
    }

    protected override bool TryResolveTokenCore(System.IdentityModel.Tokens.SecurityKeyIdentifierClause keyIdentifierClause, out System.IdentityModel.Tokens.SecurityToken token)
    {
        throw new NotImplementedException();
    }

    protected override bool TryResolveTokenCore(System.IdentityModel.Tokens.SecurityKeyIdentifier keyIdentifier, out System.IdentityModel.Tokens.SecurityToken token)
    {
        throw new NotImplementedException();
    }
}
Другие вопросы по тегам