private byte[] DecryptKey(EncryptedType encryptedKey) { var cipherText = encryptedKey.CipherData.CipherValue; var symmetricKey = DecryptRsaOaep(cipherText); if (symmetricKey.Length != 32) { throw new SecurityException("Unexcepted length of decrypted symmetric key: " + symmetricKey.Length); } return(symmetricKey); }
private IEnumerable <SecurityKey> GetSecurityKeys(EncryptedType encryptedType) { var keys = new List <SecurityKey>(); foreach (var clause in encryptedType.KeyInfo.Cast <KeyInfoClause>()) { if (clause is KeyInfoEncryptedKey encryptedKey && TryDecrypt(encryptedKey.EncryptedKey, out var symmetricKey)) { keys.Add(new SymmetricSecurityKey(symmetricKey)); } if (clause is KeyInfoName name) { keys.AddRange(_tokenValidationParameters.ResolveDecryptionKeys(kid: name.Value)); } if (clause is KeyInfoX509Data x509) { keys.AddRange(x509.Certificates.Cast <X509Certificate2>().Select(cert => new X509SecurityKey(cert))); } if (clause is RSAKeyValue rsa) { var key = new RsaSecurityKey(rsa.Key); keys.AddRange(_tokenValidationParameters.ResolveDecryptionKeys(kid: key.KeyId)); if (key.PrivateKeyStatus != PrivateKeyStatus.DoesNotExist) { keys.Add(key); } } if (clause is KeyInfoNode node) { if (node.Value.LocalName == "SecurityTokenReference") { keys.AddRange(_tokenValidationParameters.ResolveDecryptionKeys(kid: node.Value.InnerText)); } } } return(keys); }
private bool TryDecrypt(EncryptedType encryptedType, out byte[] plainText) { var xml = new EncryptedXml(); var keys = GetSecurityKeys(encryptedType); var algorithm = encryptedType.EncryptionMethod.KeyAlgorithm; foreach (var key in keys) { var crypto = GetCrypto(key); if (!crypto.IsSupportedAlgorithm(algorithm, key)) { continue; } var symmetric = null as SymmetricAlgorithm; try { if (encryptedType is EncryptedData encryptedData) { if (!(key is SymmetricSecurityKey symmetricKey)) { continue; } symmetric = crypto.CreateSymmetricAlgorithm(symmetricKey, algorithm); symmetric.IV = xml.GetDecryptionIV(encryptedData, algorithm); var pt = xml.DecryptData(encryptedData, symmetric); plainText = pt; return(true); } if (encryptedType is EncryptedKey encryptedKey) { var pt = null as byte[]; var keyWrapAlgorithm = encryptedKey.EncryptionMethod.KeyAlgorithm; if (crypto.IsSupportedAlgorithm(algorithm, key)) { var keyWrap = crypto.CreateKeyWrapProviderForUnwrap(key, encryptedKey.EncryptionMethod.KeyAlgorithm); try { pt = keyWrap.UnwrapKey(encryptedKey.CipherData.CipherValue); plainText = pt; return(true); } finally { crypto.ReleaseKeyWrapProvider(keyWrap); } } } } catch (Exception ex) { } finally { if (symmetric != null) { crypto.ReleaseSymmetricAlgorithm(symmetric); symmetric = null; } } } return(Out.False(out plainText)); }