init
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Cryptography.Xml;
|
||||
using System.Xml;
|
||||
using Kreta.Resources;
|
||||
|
||||
namespace Kreta.EESZTInterface.STS
|
||||
{
|
||||
class EncryptHelper
|
||||
{
|
||||
public static RSA TransportKey { get; set; }
|
||||
|
||||
private static SymmetricAlgorithm _sessionKey;
|
||||
private static string _sessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url;
|
||||
private static SymmetricAlgorithm SessionKey
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_sessionKey == null)
|
||||
{
|
||||
_sessionKey = GetKeyInstance(_sessionKeyAlgorithm);
|
||||
_sessionKey.GenerateKey();
|
||||
}
|
||||
|
||||
return _sessionKey;
|
||||
}
|
||||
}
|
||||
|
||||
public static string SessionKeyAlgorithm
|
||||
{
|
||||
get { return _sessionKeyAlgorithm; }
|
||||
set
|
||||
{
|
||||
// Validate that the URI used to identify the algorithm of the session key is probably correct. Not a complete validation, but should catch most obvious mistakes.
|
||||
if (!value.StartsWith(Namespaces.xencNs))
|
||||
{
|
||||
throw new ArgumentException(EESZTInterfaceResource.SessionKeyAlgorithmMustBeSpecified);
|
||||
}
|
||||
_sessionKeyAlgorithm = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static XmlDocument EncryptMessage(XmlDocument mySoap, X509Certificate2 oamcert, string IdBody, string IdTs,
|
||||
string idOamCert)
|
||||
{
|
||||
string encKId = "EK-" + Guid.NewGuid().ToString().Replace("-", "");
|
||||
string encDId = "ED-" + Guid.NewGuid().ToString().Replace("-", "");
|
||||
// Create a symmetric key.
|
||||
|
||||
SessionKeyAlgorithm = EncryptedXml.XmlEncAES128Url;
|
||||
TransportKey = (RSA)oamcert.PublicKey.Key;
|
||||
|
||||
var encryptedData = new EncryptedData
|
||||
{
|
||||
Type = EncryptedXml.XmlEncElementContentUrl,
|
||||
EncryptionMethod = new EncryptionMethod(_sessionKeyAlgorithm),
|
||||
Id = encDId
|
||||
};
|
||||
var body = XmlHelper.GetElement(XmlHelper.BodyElementName, Namespaces.soap12Ns, mySoap.DocumentElement);
|
||||
var requestSecurityToken = XmlHelper.GetElement(XmlHelper.RequestSecurityTokenElementName, Namespaces.nsNs, body);
|
||||
var encryptedXml = new EncryptedXml();
|
||||
var encryptedElement = encryptedXml.EncryptData(requestSecurityToken, SessionKey, false);
|
||||
encryptedData.CipherData.CipherValue = encryptedElement;
|
||||
|
||||
encryptedData.KeyInfo = new KeyInfo();
|
||||
|
||||
var encryptedKey = new EncryptedKey
|
||||
{
|
||||
EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSAOAEPUrl),
|
||||
CipherData = new CipherData(EncryptedXml.EncryptKey(SessionKey.Key, TransportKey, true)),
|
||||
Id = encKId
|
||||
};
|
||||
|
||||
var kInfo = new KeyInfo();
|
||||
kInfo.Id = "KI-" + Guid.NewGuid().ToString().Replace("-", "");
|
||||
XmlElement securityTokenReference = mySoap.CreateElement("wsse", "SecurityTokenReference", Namespaces.wsseNs);
|
||||
securityTokenReference.SetAttribute("Id", Namespaces.wsuNs, "STR-" + Guid.NewGuid().ToString().Replace("-", ""));
|
||||
XmlElement reference = mySoap.CreateElement("wsse", "Reference", Namespaces.wsseNs);
|
||||
reference.SetAttribute("ValueType", STSValues.x509v3Value);
|
||||
reference.SetAttribute("URI", idOamCert);
|
||||
securityTokenReference.AppendChild(reference);
|
||||
KeyInfoNode kInfoNode = new KeyInfoNode();
|
||||
kInfoNode.Value = securityTokenReference;
|
||||
kInfo.AddClause(kInfoNode);
|
||||
encryptedKey.KeyInfo = kInfo;
|
||||
|
||||
DataReference dRef = new DataReference();
|
||||
dRef.Uri = "#" + encDId;
|
||||
encryptedKey.AddReference(dRef);
|
||||
|
||||
var headerSec = XmlHelper.GetElement(XmlHelper.SecurityElementName, Namespaces.wsseNs, mySoap.DocumentElement);
|
||||
var enc = encryptedKey.GetXml();
|
||||
XmlElement encKeyElement = headerSec.OwnerDocument.ImportNode(encryptedKey.GetXml(), true) as XmlElement;
|
||||
|
||||
SetEncPrefix(encKeyElement);
|
||||
|
||||
headerSec.InsertAfter(encKeyElement, XmlHelper.GetElementId(mySoap, idOamCert.Replace("#", "")));
|
||||
|
||||
kInfo = new KeyInfo();
|
||||
securityTokenReference = mySoap.CreateElement("wsse", "SecurityTokenReference", Namespaces.wsseNs);
|
||||
securityTokenReference.SetAttribute("xmlns:wsse11", Namespaces.wsse11Ns);
|
||||
securityTokenReference.SetAttribute("TokenType", Namespaces.wsse11Ns, STSValues.encryptedKeyValue);
|
||||
reference = mySoap.CreateElement("wsse", "Reference", Namespaces.wsseNs);
|
||||
reference.SetAttribute("URI", "#" + encKId);
|
||||
securityTokenReference.AppendChild(reference);
|
||||
|
||||
kInfoNode = new KeyInfoNode();
|
||||
kInfoNode.Value = securityTokenReference;
|
||||
kInfo.AddClause(kInfoNode);
|
||||
encryptedData.KeyInfo = kInfo;
|
||||
|
||||
EncryptedXml.ReplaceElement(body, encryptedData, true);
|
||||
SetEncPrefix(body);
|
||||
|
||||
return mySoap;
|
||||
}
|
||||
|
||||
public static XmlDocument DecryptMessageAll(XmlDocument mySoap, X509Certificate2 userCert)
|
||||
{
|
||||
RSA publicKeyRSA = userCert.PrivateKey as RSA;
|
||||
TransportKey = publicKeyRSA;
|
||||
var bodyElement = XmlHelper.GetElement(XmlHelper.BodyElementName, Namespaces.soap12Ns, mySoap.DocumentElement);
|
||||
var encryptedDataElement = XmlHelper.GetElement(XmlHelper.EncryptedDataElementName, Namespaces.xencNs, bodyElement);
|
||||
var securityElement = XmlHelper.GetElement(XmlHelper.SecurityElementName, Namespaces.wsseNs, mySoap.DocumentElement);
|
||||
|
||||
var encryptedData = new EncryptedData();
|
||||
encryptedData.LoadXml(encryptedDataElement);
|
||||
|
||||
string _sessionKeyAlgorithm;
|
||||
|
||||
SymmetricAlgorithm sessionKey;
|
||||
if (encryptedData.EncryptionMethod != null)
|
||||
{
|
||||
_sessionKeyAlgorithm = encryptedData.EncryptionMethod.KeyAlgorithm;
|
||||
sessionKey = ExtractSessionKey(securityElement, encryptedDataElement, _sessionKeyAlgorithm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionKey = ExtractSessionKey(securityElement, encryptedDataElement, string.Empty);
|
||||
}
|
||||
|
||||
var encryptedXml = new EncryptedXml(mySoap);
|
||||
|
||||
encryptedXml.ReplaceData(encryptedDataElement, encryptedXml.DecryptData(encryptedData, sessionKey));
|
||||
|
||||
return mySoap;
|
||||
}
|
||||
|
||||
private static SymmetricAlgorithm ExtractSessionKey(XmlElement securityElement, XmlElement encryptedData, string keyAlgorithm)
|
||||
{
|
||||
// Check if there are any <EncryptedKey> elements immediately below the EncryptedAssertion element.
|
||||
foreach (XmlNode node in securityElement.ChildNodes)
|
||||
{
|
||||
if (node.LocalName == XmlHelper.EncryptedKeyElementName && node.NamespaceURI == Namespaces.xencNs)
|
||||
{
|
||||
return ToSymmetricKey((XmlElement)node, keyAlgorithm);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the key is embedded in the <EncryptedData> element.
|
||||
if (encryptedData != null)
|
||||
{
|
||||
var encryptedKeyElement = XmlHelper.GetElement(XmlHelper.EncryptedKeyElementName, Namespaces.xencNs, encryptedData);
|
||||
if (encryptedKeyElement != null)
|
||||
{
|
||||
return ToSymmetricKey(encryptedKeyElement, keyAlgorithm);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception(EESZTInterfaceResource.EncryptedKeyNemTalalhato);
|
||||
}
|
||||
|
||||
private static SymmetricAlgorithm ToSymmetricKey(XmlElement encryptedKeyElement, string keyAlgorithm)
|
||||
{
|
||||
var encryptedKey = new EncryptedKey();
|
||||
encryptedKey.LoadXml(encryptedKeyElement);
|
||||
|
||||
var useOaep = true;
|
||||
if (encryptedKey.EncryptionMethod != null)
|
||||
{
|
||||
useOaep = encryptedKey.EncryptionMethod.KeyAlgorithm == EncryptedXml.XmlEncRSAOAEPUrl;
|
||||
}
|
||||
|
||||
if (encryptedKey.CipherData.CipherValue != null)
|
||||
{
|
||||
var key = GetKeyInstance(keyAlgorithm);
|
||||
key.Key = EncryptedXml.DecryptKey(encryptedKey.CipherData.CipherValue, TransportKey, useOaep);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
throw new NotImplementedException(EESZTInterfaceResource.UnableToDecodeCipherData);
|
||||
}
|
||||
|
||||
private static SymmetricAlgorithm GetKeyInstance(string algorithm)
|
||||
{
|
||||
SymmetricAlgorithm result;
|
||||
switch (algorithm)
|
||||
{
|
||||
case EncryptedXml.XmlEncTripleDESUrl:
|
||||
result = TripleDES.Create();
|
||||
break;
|
||||
case EncryptedXml.XmlEncAES128Url:
|
||||
result = new RijndaelManaged { KeySize = 128 };
|
||||
break;
|
||||
case EncryptedXml.XmlEncAES192Url:
|
||||
result = new RijndaelManaged { KeySize = 192 };
|
||||
break;
|
||||
case EncryptedXml.XmlEncAES256Url:
|
||||
default:
|
||||
result = new RijndaelManaged { KeySize = 256 };
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SetEncPrefix(XmlElement encKeyElement)
|
||||
{
|
||||
foreach (XmlNode xnode in encKeyElement.SelectNodes($"descendant-or-self::*[namespace-uri()='{Namespaces.dsNs}']"))
|
||||
{
|
||||
xnode.Prefix = "ds";
|
||||
|
||||
}
|
||||
foreach (XmlNode xnode in encKeyElement.SelectNodes($"descendant-or-self::*[namespace-uri()='{Namespaces.xencNs}']"))
|
||||
{
|
||||
xnode.Prefix = "xenc";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user