Как расшифровать 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();
}
}