//加密 private void btnJiaMi_Click(object sender, EventArgs e) { if (label1.Text == "") { return; } try { //生产对称密钥.该密钥用来对XML加密 RijndaelManaged key = new RijndaelManaged(); keyIv = key.IV; keyKey = key.Key; //加载XML对象,定制加密位置 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(this.label1.Text); XmlElement elementToEncrypt = xmlDoc.GetElementsByTagName("creditcard")[0] as XmlElement; //生产EncrypteData类 EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl;//填充Url标识符 string encryptionMethod = null; if (key is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (key is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (key is Rijndael) { switch (key.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { throw new CryptographicException("没有为XML加密的指定算法!"); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod);//生成具有加密算法的Url标识符 //用EncryptedXml加密xml EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, key, false); //把加密的元素添加到EncryptedData中 edElement.CipherData.CipherValue = encryptedElement; //最后将xml中原始数据和EncrytedXml替换 EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); xmlDoc.Save(this.label1.Text); succes(); } catch (Exception ex) { fail(); } }
public static XmlDocument Encrypt(XmlDocument Doc, string ElementToEncrypt, string KeyName) { CspParameters cspParams = new CspParameters(); cspParams.KeyContainerName = "XML_ENC_RSA_KEY"; RSA Alg = new RSACryptoServiceProvider(cspParams); // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } RijndaelManaged sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Encrypt the session key and add it to an EncryptedKey element. EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); // Set the KeyInfo element to specify the // name of the RSA key. // Create a new KeyInfo element. edElement.KeyInfo = new KeyInfo(); // Create a new KeyInfoName element. KeyInfoName kin = new KeyInfoName(); // Specify a name for the key. kin.Value = KeyName; // Add the KeyInfoName element to the // EncryptedKey object. ek.KeyInfo.AddClause(kin); // Add the encrypted key to the // EncryptedData object. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); return(Doc); }
public void ReplaceElement_XmlElementNull() { Assert.Throws <ArgumentNullException>(() => EncryptedXml.ReplaceElement(null, new EncryptedData(), true)); }
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName) { // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (EncryptionElementID == null) { throw new ArgumentNullException("EncryptionElementID"); } if (Alg == null) { throw new ArgumentNullException("Alg"); } if (KeyName == null) { throw new ArgumentNullException("KeyName"); } //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElemnt object. //////////////////////////////////////////////// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } RijndaelManaged sessionKey = null; try { ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // a new random symmetric key. ////////////////////////////////////////////////// // Create a 256 bit Rijndael key. sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Encrypt the session key and add it to an EncryptedKey element. EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); // Create a new DataReference element // for the KeyInfo element. This optional // element specifies which EncryptedData // uses this key. An XML document can have // multiple EncryptedData elements that use // different keys. DataReference dRef = new DataReference(); // Specify the EncryptedData URI. dRef.Uri = "#" + EncryptionElementID; // Add the DataReference to the EncryptedKey. ek.AddReference(dRef); // Add the encrypted key to the // EncryptedData object. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); // Set the KeyInfo element to specify the // name of the RSA key. // Create a new KeyInfoName element. KeyInfoName kin = new KeyInfoName(); // Specify a name for the key. kin.Value = KeyName; // Add the KeyInfoName element to the // EncryptedKey object. ek.KeyInfo.AddClause(kin); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); } catch (Exception e) { // re-throw the exception. throw e; } finally { if (sessionKey != null) { sessionKey.Clear(); } } }
public Message SecureMessage() { secprop = Message.Properties.Security ?? new SecurityMessageProperty(); SecurityToken encToken = secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken; // FIXME: it might be still incorrect. SecurityToken signToken = Parameters == CounterParameters ? null : security.SigningToken; MessageProtectionOrder protectionOrder = security.MessageProtectionOrder; SecurityBindingElement element = security.Element; SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite; string messageId = "uuid-" + Guid.NewGuid(); int identForMessageId = 1; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; var action = msg.Headers.Action; if (msg.Version.Addressing != AddressingVersion.None) { AddAddressingToHeader(msg.Headers); } // wss:Security WSSecurityMessageHeader header = new WSSecurityMessageHeader(security.TokenSerializer); msg.Headers.Add(header); // 1. [Timestamp] if (element.IncludeTimestamp) { AddTimestampToHeader(header, messageId + "-" + identForMessageId++); } XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("s", msg.Version.Envelope.Namespace); nsmgr.AddNamespace("o", Constants.WssNamespace); nsmgr.AddNamespace("u", Constants.WsuNamespace); nsmgr.AddNamespace("o11", Constants.Wss11Namespace); /*WrappedKey*/ SecurityToken primaryToken = null; SecurityToken actualToken = null; SecurityKeyIdentifierClause actualClause = null; SymmetricAlgorithm masterKey = new RijndaelManaged(); masterKey.KeySize = suite.DefaultSymmetricKeyLength; masterKey.Mode = CipherMode.CBC; masterKey.Padding = PaddingMode.ISO10126; SymmetricAlgorithm actualKey = masterKey; // 2. [Encryption Token] // SecurityTokenInclusionMode // - Initiator or Recipient // - done or notyet. FIXME: not implemented yet // It also affects on key reference output bool includeEncToken = // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken( Security.RecipientParameters.InclusionMode, false); bool includeSigToken = // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken( Security.InitiatorParameters.InclusionMode, false); SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ? CounterParameters.CallCreateKeyIdentifierClause(encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null; MessagePartSpecification encSpec = EncryptionPart; // encryption key (possibly also used for signing) // FIXME: get correct SymmetricAlgorithm according to the algorithm suite if (secprop.EncryptionKey != null) { actualKey.Key = secprop.EncryptionKey; } // FIXME: remove thid hack if (!ShouldOutputEncryptedKey) { primaryToken = secprop.ProtectionToken.SecurityToken as WrappedKeySecurityToken; } else { primaryToken = // FIXME: remove this hack? encToken is SecurityContextSecurityToken ? encToken : new WrappedKeySecurityToken(messageId + "-" + identForMessageId++, actualKey.Key, // security.DefaultKeyWrapAlgorithm, Parameters.InternalHasAsymmetricKey ? suite.DefaultAsymmetricKeyWrapAlgorithm : suite.DefaultSymmetricKeyWrapAlgorithm, encToken, encClause != null ? new SecurityKeyIdentifier(encClause) : null); } // If it reuses request's encryption key, do not output. if (ShouldOutputEncryptedKey) { header.AddContent(primaryToken); } actualToken = primaryToken; // FIXME: I doubt it is correct... WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken; actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause) new LocalIdKeyIdentifierClause(actualToken.Id, typeof(WrappedKeySecurityToken)) : new InternalEncryptedKeyIdentifierClause(SHA1.Create().ComputeHash(requestEncKey.GetWrappedKey())); // generate derived key if needed if (CounterParameters.RequireDerivedKeys) { var dkeyToken = CreateDerivedKey(GenerateId(doc), actualClause, actualKey); actualToken = dkeyToken; actualKey.Key = ((SymmetricSecurityKey)dkeyToken.SecurityKeys [0]).GetSymmetricKey(); actualClause = new LocalIdKeyIdentifierClause(dkeyToken.Id); header.AddContent(dkeyToken); } ReferenceList refList = new ReferenceList(); // When encrypted with DerivedKeyToken, put references // immediately after the derived token (not inside the // primary token). // Similarly, when we do not output EncryptedKey, // output ReferenceList in the same way. if (CounterParameters.RequireDerivedKeys || !ShouldOutputEncryptedKey) { header.AddContent(refList); } else { ((WrappedKeySecurityToken)primaryToken).ReferenceList = refList; } // [Signature Confirmation] if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0) { foreach (string value in secprop.ConfirmedSignatures) { header.AddContent(new Wss11SignatureConfirmation(GenerateId(doc), value)); } } SupportingTokenInfoCollection tokenInfos = Direction == MessageDirection.Input ? security.CollectSupportingTokens(GetAction()) : new SupportingTokenInfoCollection(); // empty foreach (SupportingTokenInfo tinfo in tokenInfos) { header.AddContent(tinfo.Token); } // populate DOM to sign. XPathNavigator nav = doc.CreateNavigator(); using (XmlWriter w = nav.AppendChild()) { msg.WriteMessage(w); } XmlElement body = doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement; string bodyId = null; Collection <WSSignedXml> endorsedSignatures = new Collection <WSSignedXml> (); bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature); // Below are o:Security contents that are not signed... if (includeSigToken && signToken != null) { header.AddContent(signToken); } switch (protectionOrder) { case MessageProtectionOrder.EncryptBeforeSign: // FIXME: implement throw new NotImplementedException(); case MessageProtectionOrder.SignBeforeEncrypt: case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature: var sig = CreateSignature(doc, body, nsmgr, tokenInfos, actualClause, actualKey, signToken, includeSigToken, signatureProtection, header, endorsedSignatures, ref bodyId); // encrypt WSEncryptedXml exml = new WSEncryptedXml(doc); EncryptedData edata = Encrypt(body, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementContentUrl); EncryptedXml.ReplaceElement(body, edata, false); // encrypt signature if (signatureProtection) { XmlElement sigxml = sig.GetXml(); edata = Encrypt(sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); header.AddContent(edata); foreach (WSSignedXml ssxml in endorsedSignatures) { sigxml = ssxml.GetXml(); edata = Encrypt(sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); header.AddContent(edata); } if (security.RequireSignatureConfirmation) { Collection <Wss11SignatureConfirmation> confs = header.FindAll <Wss11SignatureConfirmation> (); int count = 0; foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) { edata = Encrypt(elem, actualKey, confs [count].Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); EncryptedXml.ReplaceElement(elem, edata, false); header.Contents.Insert(header.Contents.IndexOf(confs [count]), edata); header.Contents.Remove(confs [count++]); } } } // encrypt Encrypted supporting tokens foreach (SupportingTokenInfo tinfo in tokenInfos) { if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted) { XmlElement el = exml.GetIdElement(doc, tinfo.Token.Id); tinfo.Encrypted = Encrypt(el, actualKey, actualToken.Id, refList, actualClause, exml, doc, EncryptedXml.XmlEncElementUrl); EncryptedXml.ReplaceElement(el, tinfo.Encrypted, false); header.Contents.Insert(header.Contents.IndexOf(tinfo.Token), tinfo.Encrypted); header.Contents.Remove(tinfo.Token); } } break; } Message ret = new WSSecurityMessage(Message.CreateMessage(msg.Version, action, new XmlNodeReader(doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement)), bodyId); ret.Properties.Security = (SecurityMessageProperty)secprop.CreateCopy(); ret.Properties.Security.EncryptionKey = masterKey.Key; // FIXME: can we support TransportToken here? if (element is AsymmetricSecurityBindingElement) { ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification(encToken, null); // FIXME: second argument ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification(signToken, null); // FIXME: second argument } else { ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification(primaryToken, null); } ret.Headers.Clear(); ret.Headers.CopyHeadersFrom(msg); // Header contents are: // - Timestamp // - SignatureConfirmation if required // - EncryptionToken if included // - derived key token for EncryptionToken // - ReferenceList for encrypted items // - signed supporting tokens // - signed endorsing supporting tokens // (i.e. Signed/SignedEncrypted/SignedEndorsing) // - Signature Token if different from enc token. // - derived key token for sig token if different // - Signature for: // - Timestamp // - supporting tokens (regardless of // its inclusion) // - message parts in SignedParts // - SignatureToken if TokenProtection // (regardless of its inclusion) // - Signatures for the main signature (above), // for every endorsing token and signed // endorsing token. // //MessageBuffer zzz = ret.CreateBufferedCopy (100000); //ret = zzz.CreateMessage (); //Console.WriteLine (zzz.CreateMessage ()); return(ret); }
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, RSA Alg, string KeyName) { // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (Alg == null) { throw new ArgumentNullException("Alg"); } //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElemnt object. //////////////////////////////////////////////// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // a new random symmetric key. ////////////////////////////////////////////////// // Create a 256 bit Aes key. Aes sessionKey = Aes.Create(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Encrypt the session key and add it to an EncryptedKey element. EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); // Set the KeyInfo element to specify the // name of the RSA key. // Create a new KeyInfo element. edElement.KeyInfo = new KeyInfo(); // Create a new KeyInfoName element. KeyInfoName kin = new KeyInfoName(); // Specify a name for the key. kin.Value = KeyName; // Add the KeyInfoName element to the // EncryptedKey object. ek.KeyInfo.AddClause(kin); // Add the encrypted key to the // EncryptedData object. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }
public void ReplaceElement_EncryptedDataNull() { XmlDocument doc = new XmlDocument(); Assert.Throws <ArgumentNullException>(() => EncryptedXml.ReplaceElement(doc.DocumentElement, null, false)); }
public void ReplaceElement_XmlElementNull() { EncryptedXml.ReplaceElement(null, new EncryptedData(), true); }
public void ReplaceElement_EncryptedDataNull() { XmlDocument doc = new XmlDocument(); EncryptedXml.ReplaceElement(doc.DocumentElement, null, false); }
public override XmlNode Encrypt(XmlNode node) { XmlDocument xmlDocument; EncryptedXml exml; byte[] rgbOutput; EncryptedData ed; KeyInfoName kin; EncryptedKey ek; KeyInfoEncryptedKey kek; XmlElement inputElement; RSACryptoServiceProvider rsa = GetCryptoServiceProvider(false, false); // Encrypt the node with the new key xmlDocument = new XmlDocument(); xmlDocument.PreserveWhitespace = true; ProtectedConfigurationProvider.LoadXml(xmlDocument, "<foo>" + node.OuterXml + "</foo>"); exml = new EncryptedXml(xmlDocument); inputElement = xmlDocument.DocumentElement; using (SymmetricAlgorithm symAlg = GetSymAlgorithmProvider()) { rgbOutput = exml.EncryptData(inputElement, symAlg, true); ed = new EncryptedData(); ed.Type = EncryptedXml.XmlEncElementUrl; ed.EncryptionMethod = GetSymEncryptionMethod(); ed.KeyInfo = new KeyInfo(); ek = new EncryptedKey(); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); ek.KeyInfo = new KeyInfo(); ek.CipherData = new CipherData(); ek.CipherData.CipherValue = EncryptedXml.EncryptKey(symAlg.Key, rsa, UseOAEP); } kin = new KeyInfoName(); kin.Value = _KeyName; ek.KeyInfo.AddClause(kin); kek = new KeyInfoEncryptedKey(ek); ed.KeyInfo.AddClause(kek); ed.CipherData = new CipherData(); ed.CipherData.CipherValue = rgbOutput; EncryptedXml.ReplaceElement(inputElement, ed, true); rsa.Clear(); // Get node from the document foreach (XmlNode node2 in xmlDocument.ChildNodes) { if (node2.NodeType == XmlNodeType.Element) { foreach (XmlNode node3 in node2.ChildNodes) // node2 is the "foo" node { if (node3.NodeType == XmlNodeType.Element) { return(node3); // node3 is the "EncryptedData" node } } } } return(null); }
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName) { if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (EncryptionElementID == null) { throw new ArgumentNullException("EncryptionElementID"); } if (Alg == null) { throw new ArgumentNullException("Alg"); } if (KeyName == null) { throw new ArgumentNullException("KeyName"); } XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } Aes sessionKey = null; try { sessionKey = Aes.Create(); EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID; edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); DataReference dRef = new DataReference(); dRef.Uri = "#" + EncryptionElementID; ek.AddReference(dRef); edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); KeyInfoName kin = new KeyInfoName(); kin.Value = KeyName; ek.KeyInfo.AddClause(kin); edElement.CipherData.CipherValue = encryptedElement; EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); } catch (Exception e) { // re-throw the exception. throw e; } finally { if (sessionKey != null) { sessionKey.Clear(); } } }
public ActionResult Index(XmlModel model) { if (model.Action == "encrypt") { var recipientCertificate = LoadCertificate(model.RecipientThumbprint); var signingCertificate = LoadCertificate(model.SenderThumbprint); var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(model.PlainText); var elementToEncrypt = xmlDocument.GetElementsByTagName("message")[0] as XmlElement; var encryptedXml = new EncryptedXml(); // Encrypt the element. var encryptedElement = encryptedXml.Encrypt(elementToEncrypt, recipientCertificate); EncryptedXml.ReplaceElement(elementToEncrypt, encryptedElement, false); // Sign the document var signedXml = new SignedXml(xmlDocument) { SigningKey = signingCertificate.PrivateKey }; var reference = new Reference { Uri = string.Empty }; var transform = new XmlDsigC14NTransform(); reference.AddTransform(transform); var envelope = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelope); signedXml.AddReference(reference); var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(signingCertificate)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); var xmlDigitalSignature = signedXml.GetXml(); xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true)); model.PlainText = ""; model.Envelope = XmlToString(xmlDocument); } else if (model.Action == "decrypt") { var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(model.Envelope); // Validate the signature var signedXml = new SignedXml(xmlDocument); var nodeList = xmlDocument.GetElementsByTagName("Signature"); if (nodeList.Count <= 0) { throw new Exception("No signature found."); } signedXml.LoadXml((XmlElement)nodeList[0]); // XML signatures allows signing only parts of a document or // even worse, can refer to another resource that's not even // part of the document containing the signature. To make // sure that the signature we're validating is actually signing // the document we have to check the reference. An empty // reference refers to the entire enclosing document. if (signedXml.SignedInfo.References.Cast <Reference>().Single().Uri != "") { throw new Exception("Signature does not refer to entire document. Validating signatures for part of the document is not supported by this code."); } AsymmetricAlgorithm signingKey; if (!signedXml.CheckSignatureReturningKey(out signingKey)) { throw new Exception("Invalid Signature"); } else { IEnumerable <X509Certificate2> keyInfoCertificates = signedXml.KeyInfo.OfType <KeyInfoX509Data>() .SelectMany(x => x.Certificates.Cast <X509Certificate2>()); var signingCertificate = keyInfoCertificates.FirstOrDefault(x => x.PublicKey.Key == signingKey); if (signingCertificate == null) { throw new Exception("Signing certificate not found in KeyInfo."); } model.SenderSubject = signingCertificate.Subject; } var encryptedXml = new EncryptedXml(xmlDocument); encryptedXml.DecryptDocument(); model.Envelope = ""; model.PlainText = XmlToString(xmlDocument); } ModelState.Clear(); model.RecipientThumbprint = RecipientThumbprint; model.SenderThumbprint = SenderThumbprint; return(View(model)); }
/** * Doc = documentul xml * ElementToEncrypt = numele elementului de criptat * EncryptionElementID = id-ul elementului ce va fi criptat * RSA = algoritmul de criptare (algoritm asimetric) * KeyNane = numele cheii de criptare */ public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName) { // Verificarea argumentelor if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (EncryptionElementID == null) { throw new ArgumentNullException("EncryptionElementID"); } if (Alg == null) { throw new ArgumentNullException("Alg"); } if (KeyName == null) { throw new ArgumentNullException("KeyName"); } //////////////////////////////////////////////// // Identificarea elementului de criptat //////////////////////////////////////////////// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; // Daca nu este gasit se arunca o exceptie if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } RijndaelManaged sessionKey = null; try { ////////////////////////////////////////////////// // Se creeaza o noua instanta a clasei EncryptedXml // si se foloseste pentru criptarea elementului xml // cu o noua cheie simetrica generata random. ////////////////////////////////////////////////// // Se creaza o cheie de sesiune SIMETRICA Rijndael de 256 de biti sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false); //////////////////////////////////////////////// // Se creeaza un obiect EncryptedData si se populeaza // cu informatia criptata. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; edElement.Id = EncryptionElementID; // Se creeaza un element de tip EncryptionMethod astfel incat // destinatarul sa stie ce algoritm va folosi pentru decriptare. edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); // Cripteaza cheia de sesiune si se adauga intr-un element de tip EncryptedKey. EncryptedKey ek = new EncryptedKey(); byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false); ek.CipherData = new CipherData(encryptedKey); ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); // Din cauza faptului ca un document xml poate avea // mai multe elemente EncrypredData criptate cu mai multe chei // este nevoie de specificarea unui element de tip DataReference // care sa indice elementul criptat cu aceasta cheie DataReference dRef = new DataReference(); // Se specifica URI-ul dRef.Uri = "#" + EncryptionElementID; // Se adauga DataReference la EncryptedKey. ek.AddReference(dRef); // Se adauga cheia criptata la obiectul EncryptedData // EncryptedData object. edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek)); // Se seteaza numele cheii RSA KeyInfoName kin = new KeyInfoName(); kin.Value = KeyName; // Adauga obiectul kin la cheia criptata ek.KeyInfo.AddClause(kin); // Se adauga elementul criptat edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Se inlocuieste elementul original cu elementul criptat //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); } catch (Exception e) { // re-throw the exception. throw e; } finally { if (sessionKey != null) { sessionKey.Clear(); } } }
/// <summary> /// Encrypts the specified XML element. /// </summary> /// <param name="plaintextElement">The plaintext to encrypt.</param> /// <returns> /// An <see cref="EncryptedXmlInfo" /> that contains the encrypted value of /// <paramref name="plaintextElement" /> along with information about how to /// decrypt it. /// </returns> /// <exception cref="System.ArgumentNullException"> /// Thrown if <paramref name="plaintextElement" /> is <see langword="null" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// Thrown if this method is called after <see cref="Dispose()"/> is called. /// </exception> public EncryptedXmlInfo Encrypt(XElement plaintextElement) { if (plaintextElement == null) { throw new ArgumentNullException(nameof(plaintextElement)); } if (this._disposed) { throw new ObjectDisposedException("Unable to encrypt after the object has been disposed."); } this.Logger.LogDebug("Encrypting XML with certificate {0}.", this._keyName); // Create a faux XML document from the XElement so we can use EncryptedXml. var xmlDocument = plaintextElement.ToXmlDocumentWithRootNode(); var elementToEncrypt = xmlDocument.ElementToProcess(); // Do the actual encryption. Algorithm based on MSDN docs: // https://msdn.microsoft.com/en-us/library/ms229746(v=vs.110).aspx var encryptedXml = new EncryptedXml(); var encryptedElement = encryptedXml.EncryptData(elementToEncrypt, this._sessionKey, false); // Build the wrapper elements that provide information about // the algorithms used, the name of the key used, and so on. var encryptedData = new EncryptedData { Type = EncryptedXml.XmlEncElementUrl, Id = EncryptedElementId, EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url), }; var encryptedKey = new EncryptedKey { CipherData = new CipherData(EncryptedXml.EncryptKey(this._sessionKey.Key, this._keyProvider, false)), EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url), }; // "Connect" the encrypted data and encrypted key with // element references. var encryptedElementDataReference = new DataReference { Uri = "#" + EncryptedElementId, }; encryptedKey.AddReference(encryptedElementDataReference); encryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedKey)); var keyName = new KeyInfoName { Value = this._keyName, }; encryptedKey.KeyInfo.AddClause(keyName); encryptedData.CipherData.CipherValue = encryptedElement; // Swap the plaintext element for the encrypted element. EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); return(new EncryptedXmlInfo(xmlDocument.ElementToProcess().ToXElement(), typeof(CertificateXmlDecryptor))); }
/// <summary> /// Encrypts the specified x document. /// </summary> /// <param name="xDoc">The x document.</param> /// <param name="elementToEncrypt">The element to encrypt.</param> /// <param name="algo">The algo.</param> /// <param name="keyName">Name of the key.</param> /// <returns></returns> /// <exception cref="System.Security.Cryptography.CryptographicException"> /// The specified algorithm is not supported for XML Encryption. /// </exception> public static XmlDocument Encrypt(ref XmlDocument xDoc, XmlElement elementToEncrypt, SymmetricAlgorithm algo, string keyName) { var docCopy = (XmlDocument)xDoc.Clone(); docCopy.PreserveWhitespace = xDoc.PreserveWhitespace; var eXml = new EncryptedXml(); var encryptedElement = eXml.EncryptData(elementToEncrypt, algo, false); var edElement = new EncryptedData() { Type = EncryptedXml.XmlEncElementUrl }; string encryptionMethod = null; if (algo is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else { if (algo is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } else { if (algo is Rijndael) { switch (algo.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; default: throw new CryptographicException(string.Format("Unsupported key size: {0}", algo.KeySize)); } } else { throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } } } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); edElement.KeyInfo = new KeyInfo(); edElement.KeyInfo.AddClause(new KeyInfoName(keyName)); edElement.CipherData.CipherValue = encryptedElement; EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); if (xDoc.FirstChild is XmlDeclaration) { xDoc.RemoveChild(xDoc.FirstChild); } var rDoc = xDoc; xDoc = docCopy; return(rDoc); }
/// <summary> /// Encrypts a list of elements. /// </summary> /// <param name="elementToAddEncKeysTo"></param> /// <param name="elementsToEncrypt"></param> /// <param name="certificates"></param> /// <param name="cipherKey"></param> public void Encrypt(XmlElement elementToAddEncKeysTo, IList <XmlElement> elementsToEncrypt, X509Certificate2Collection certificates, byte[] cipherKey) { ArgumentUtils.CheckNotNull(elementToAddEncKeysTo, "elementToAddEncKeysTo"); ArgumentUtils.CheckNotNullNorEmpty(elementsToEncrypt, "elementsToEncrypt"); CertificateUtils.CheckNotNullOrEmpty(certificates, "certificates"); // Check all the elements to encrypt are not the same as the element // to add the keys to and check they belong to the same document. foreach (XmlElement elementToEncrypt in elementsToEncrypt) { if (elementToEncrypt == elementToAddEncKeysTo) { throw new XspException( "Cannot add keys to an element that is being encrypted"); } if (elementToAddEncKeysTo.OwnerDocument != elementToEncrypt.OwnerDocument) { throw new XspException( "Elements to encrypt must belong to the same document as the " + "keys element"); } if (XmlUtils.IsDescendant(elementToEncrypt, elementToAddEncKeysTo)) { throw new XspException( "Element the keys are added to cannot be a child element of an " + "element to encrypt"); } } // Get the container document XmlDocument containerDoc = elementToAddEncKeysTo.OwnerDocument; // Create a random session key RijndaelManaged sessionKey = new RijndaelManaged(); sessionKey.KeySize = 256; if (cipherKey != null) { sessionKey.Key = cipherKey; } IList <string> referenceIdList = new List <string>(); foreach (XmlElement elementToEncrypt in elementsToEncrypt) { // Generate a unique reference identifier string referenceId = "_" + Guid.NewGuid().ToString(); // Add it to the reference list referenceIdList.Add(referenceId); // Create the encrypted data EncryptedData encryptedData = XmlSecurityUtils.Encrypt( sessionKey, elementToEncrypt, referenceId); // Replace the original element with the encrypted data EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); } foreach (X509Certificate2 certificate in certificates) { // Create the encrypted key EncryptedKey encryptedKey = XmlSecurityUtils.CreateEncryptedKey( sessionKey, certificate, referenceIdList); // Import the encrypted key element into the container document XmlNode encryptedKeyElem = containerDoc.ImportNode(encryptedKey.GetXml(), true); elementToAddEncKeysTo.AppendChild(encryptedKeyElem); } }
/// <summary> /// Encrypts the XML node passed to it. /// </summary> /// <param name="node">The XmlNode to encrypt.</param> /// <returns></returns> public override XmlNode Encrypt(XmlNode node) { // Get the RSA public key to encrypt the node. This key will encrypt // a symmetric key, which will then be encryped in the XML document. RSACryptoServiceProvider cryptoServiceProvider = this.GetCryptoServiceProvider(true); // Create an XML document and load the node to be encrypted in it. XmlDocument document = new XmlDocument { PreserveWhitespace = true }; document.LoadXml("<Data>" + node.OuterXml + "</Data>"); // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // a new random symmetric key. EncryptedXml xml = new EncryptedXml(document); XmlElement documentElement = document.DocumentElement; SymmetricAlgorithm symmetricAlgorithm = new RijndaelManaged(); // Create a 192 bit random key. symmetricAlgorithm.Key = this.GetRandomKey(); symmetricAlgorithm.GenerateIV(); symmetricAlgorithm.Padding = PaddingMode.PKCS7; byte[] buffer = xml.EncryptData(documentElement ?? throw new InvalidOperationException(), symmetricAlgorithm, true); // Construct an EncryptedData object and populate // it with the encryption information. EncryptedData encryptedData = new EncryptedData(); encryptedData.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. encryptedData.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES192Url); encryptedData.KeyInfo = new KeyInfo(); // Encrypt the session key and add it to an EncryptedKey element. EncryptedKey encryptedKey = new EncryptedKey { EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url), KeyInfo = new KeyInfo(), CipherData = new CipherData { CipherValue = EncryptedXml.EncryptKey(symmetricAlgorithm.Key, cryptoServiceProvider, false) } }; KeyInfoName clause = new KeyInfoName { Value = "rsaKey" }; // Add the encrypted key to the EncryptedData object. encryptedKey.KeyInfo.AddClause(clause); KeyInfoEncryptedKey key2 = new KeyInfoEncryptedKey(encryptedKey); encryptedData.KeyInfo.AddClause(key2); encryptedData.CipherData = new CipherData(); encryptedData.CipherData.CipherValue = buffer; // Replace the element from the original XmlDocument // object with the EncryptedData element. EncryptedXml.ReplaceElement(documentElement, encryptedData, true); foreach (XmlNode node2 in document.ChildNodes) { if (node2.NodeType == XmlNodeType.Element) { foreach (XmlNode node3 in node2.ChildNodes) { if (node3.NodeType == XmlNodeType.Element) { return(node3); } } } } return(null); }
public static void Encrypt(XmlDocument Doc, String ElementName, SymmetricAlgorithm Key) { //Check the arguments provided if (Doc == null) { throw new ArgumentNullException("Doc"); } else if (ElementName == null) { throw new ArgumentNullException("ElementToEncrypt"); } else if (Key == null) { throw new ArgumentNullException("Algorithm"); } //Find the specified xmlElement object, encrypt it then create a new xmlElement object XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement; //Throw an XmlException if the element isn't found if (elementToEncrypt == null) { throw new XmlException("The specified element could not be found"); } EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false); //Create an EncryptedData object and populate it with the desired encrypted information EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; //The EncryptionMethod so that the receiver knows which algorithm to use for decryption string encryptionMethod = null; if (Key is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (Key is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (Key is Rijndael) { switch (Key.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { //Throw an exception if the transform is not in the previous categories throw new CryptographicException("The specified algorithm is not supported for XML"); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); //Add the encrypted element data to the original XMlDocument object with the EncryptedData element edElement.CipherData.CipherValue = encryptedElement; //Replace the element from the original XmlDocument object with the Encrypted Data element EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }
internal static void Encrypt(this XmlElement elementToEncrypt, EncryptingCredentials encryptingCredentials) { if (elementToEncrypt == null) { throw new ArgumentNullException(nameof(elementToEncrypt)); } if (encryptingCredentials == null) { throw new ArgumentNullException(nameof(encryptingCredentials)); } string enc; int keySize; switch (encryptingCredentials.Enc) { case SecurityAlgorithms.Aes128CbcHmacSha256: enc = EncryptedXml.XmlEncAES128Url; keySize = 128; break; case SecurityAlgorithms.Aes192CbcHmacSha384: enc = EncryptedXml.XmlEncAES192Url; keySize = 192; break; case SecurityAlgorithms.Aes256CbcHmacSha512: enc = EncryptedXml.XmlEncAES256Url; keySize = 256; break; default: throw new CryptographicException( $"Unsupported cryptographic algorithm {encryptingCredentials.Enc}"); } var encryptedData = new EncryptedData { Type = EncryptedXml.XmlEncElementUrl, EncryptionMethod = new EncryptionMethod(enc) }; string alg; switch (encryptingCredentials.Alg) { case SecurityAlgorithms.RsaOAEP: alg = EncryptedXml.XmlEncRSAOAEPUrl; break; case SecurityAlgorithms.RsaPKCS1: alg = EncryptedXml.XmlEncRSA15Url; break; default: throw new CryptographicException( $"Unsupported cryptographic algorithm {encryptingCredentials.Alg}"); } var encryptedKey = new EncryptedKey { EncryptionMethod = new EncryptionMethod(alg), }; var encryptedXml = new EncryptedXml(); byte[] encryptedElement; using (var symmetricAlgorithm = new RijndaelManaged()) { X509SecurityKey x509SecurityKey = encryptingCredentials.Key as X509SecurityKey; if (x509SecurityKey == null) { throw new CryptographicException( "The encrypting credentials have an unknown key of type {encryptingCredentials.Key.GetType()}"); } symmetricAlgorithm.KeySize = keySize; encryptedKey.CipherData = new CipherData(EncryptedXml.EncryptKey(symmetricAlgorithm.Key, (RSA)x509SecurityKey.PublicKey, alg == EncryptedXml.XmlEncRSAOAEPUrl)); encryptedElement = encryptedXml.EncryptData(elementToEncrypt, symmetricAlgorithm, false); } encryptedData.CipherData.CipherValue = encryptedElement; encryptedData.KeyInfo = new KeyInfo(); encryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedKey)); EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); }
/// <summary> /// Encrypts the NameID attribute of the AttributeQuery request. /// </summary> /// <param name="certValue"> /// Encoded X509 certificate retrieved from the identity provider's metadata /// and used to encrypt generated symmetric key. /// </param> /// <param name="xmlDoc"> /// XML document to be encrypted. /// </param> /// <param name="symmetricAlgorithmUri"> /// Symmetric algorithm uri used for encryption. /// </param> public static void EncryptAttributeQueryNameID(string certValue, string symmetricAlgorithmUri, XmlDocument xmlDoc) { if (string.IsNullOrWhiteSpace(certValue)) { throw new Saml2Exception(Resources.EncryptedXmlCertNotFound); } if (string.IsNullOrWhiteSpace(symmetricAlgorithmUri)) { throw new Saml2Exception(Resources.EncryptedXmlInvalidEncrAlgorithm); } if (xmlDoc == null) { throw new Saml2Exception(Resources.SignedXmlInvalidXml); } byte[] byteArray = Encoding.UTF8.GetBytes(certValue); X509Certificate2 cert = new X509Certificate2(byteArray); if (cert == null) { throw new Saml2Exception(Resources.EncryptedXmlCertNotFound); } XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable); nsMgr.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); nsMgr.AddNamespace("saml", Saml2Constants.NamespaceSamlAssertion); nsMgr.AddNamespace("samlp", Saml2Constants.NamespaceSamlProtocol); string xpath = "/samlp:AttributeQuery/saml:Subject/saml:NameID"; XmlNode root = xmlDoc.DocumentElement; XmlNode node = root.SelectSingleNode(xpath, nsMgr); XmlNode encryptedID = xmlDoc.CreateNode(XmlNodeType.Element, "EncryptedID", Saml2Constants.NamespaceSamlAssertion); node.ParentNode.PrependChild(encryptedID); XmlElement elementToEncrypt = (XmlElement)encryptedID.AppendChild(node.Clone()); if (elementToEncrypt == null) { throw new Saml2Exception(Resources.EncryptedXmlInvalidXml); } encryptedID.ParentNode.RemoveChild(node); SymmetricAlgorithm alg = Saml2Utils.GetAlgorithm(symmetricAlgorithmUri); if (alg == null) { throw new Saml2Exception(Resources.EncryptedXmlInvalidEncrAlgorithm); } alg.GenerateKey(); string encryptionElementID = Saml2Utils.GenerateId(); string encryptionKeyElementID = Saml2Utils.GenerateId(); EncryptedData encryptedData = new EncryptedData(); encryptedData.Type = EncryptedXml.XmlEncElementUrl; encryptedData.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES128Url); encryptedData.Id = encryptionElementID; EncryptedXml encryptedXml = new EncryptedXml(); byte[] encryptedElement = encryptedXml.EncryptData(elementToEncrypt, alg, false); encryptedData.CipherData.CipherValue = encryptedElement; encryptedData.KeyInfo = new KeyInfo(); EncryptedKey encryptedKey = new EncryptedKey(); encryptedKey.Id = encryptionKeyElementID; RSA publicKeyRSA = cert.PublicKey.Key as RSA; encryptedKey.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); encryptedKey.CipherData = new CipherData(EncryptedXml.EncryptKey(alg.Key, publicKeyRSA, false)); encryptedData.KeyInfo.AddClause(new KeyInfoRetrievalMethod("#" + encryptionKeyElementID, "http://www.w3.org/2001/04/xmlenc#EncryptedKey")); KeyInfoName kin = new KeyInfoName(); kin.Value = cert.SubjectName.Name; encryptedKey.KeyInfo.AddClause(kin); EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false); XmlNode importKeyNode = xmlDoc.ImportNode(encryptedKey.GetXml(), true); encryptedID.AppendChild(importKeyNode); }
public static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key) { // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementName == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (Key == null) { throw new ArgumentNullException("Alg"); } //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElement object. //////////////////////////////////////////////// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // symmetric key. ////////////////////////////////////////////////// EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. // Determine what kind of algorithm is being used and // supply the appropriate URL to the EncryptionMethod element. string encryptionMethod = null; if (Key is Aes) { encryptionMethod = EncryptedXml.XmlEncAES256Url; } else { // Throw an exception if the transform is not AES throw new CryptographicException("The specified algorithm is not supported or not recommended for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }
/// <summary> /// Encrypt document /// </summary> /// <param name="Doc">XmlDocument to encrypt</param> /// <param name="ElementName">Encrypt all elements of this type</param> /// <param name="Key">Encryption key to use</param> private static void Encrypt(XmlDocument Doc, string ElementName, SymmetricAlgorithm Key) { // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementName == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (Key == null) { throw new ArgumentNullException("Alg"); } //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElemnt object. //////////////////////////////////////////////// //XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementName)[0] as XmlElement; XmlNodeList lst = Doc.GetElementsByTagName(ElementName); for (int i = lst.Count - 1; i >= 0; i--) { XmlElement elementToEncrypt = (XmlElement)lst[i]; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // symmetric key. ////////////////////////////////////////////////// EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Key, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. // Determine what kind of algorithm is being used and // supply the appropriate URL to the EncryptionMethod element. string encryptionMethod = null; if (Key is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (Key is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (Key is Rijndael) { switch (Key.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { // Throw an exception if the transform is not in the previous categories throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); } }
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, SymmetricAlgorithm Alg, string KeyName) { // Check the arguments. if (Doc == null) { throw new ArgumentNullException("Doc"); } if (ElementToEncrypt == null) { throw new ArgumentNullException("ElementToEncrypt"); } if (Alg == null) { throw new ArgumentNullException("Alg"); } //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElemnt object. //////////////////////////////////////////////// XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // symmetric key. ////////////////////////////////////////////////// EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, Alg, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the // receiver knows which algorithm to use for decryption. // Determine what kind of algorithm is being used and // supply the appropriate URL to the EncryptionMethod element. string encryptionMethod = null; if (Alg is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (Alg is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } else if (Alg is Aes) { switch (Alg.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { // Throw an exception if the transform is not in the previous categories throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); // Set the KeyInfo element to specify the // name of a key. // Create a new KeyInfo element. edElement.KeyInfo = new KeyInfo(); // Create a new KeyInfoName element. KeyInfoName kin = new KeyInfoName(); // Specify a name for the key. kin.Value = KeyName; // Add the KeyInfoName element. edElement.KeyInfo.AddClause(kin); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }
public static String EncryptXML(String xml, SymmetricAlgorithm key = null) { if (String.IsNullOrEmpty(xml)) { throw new ArgumentNullException("xml"); } if (key == null) { key = DefaultCryptographyKey; } var xmlDoc = default(XmlDocument); var element = default(XmlElement); var eXml = default(EncryptedXml); var encryptedElement = default(Byte[]); var edElement = default(EncryptedData); var encryptionMethod = string.Empty; xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xml); element = xmlDoc.DocumentElement; eXml = new EncryptedXml(); Contract.Assert(element != null, "element != null"); encryptedElement = eXml.EncryptData(element, key, false); edElement = new EncryptedData { Type = EncryptedXml.XmlEncElementUrl }; if (key is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (key is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (key is Rijndael) { switch (key.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { // Throw an exception if the transform is not in the previous categories throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); // Add the encrypted element data to the // EncryptedData object. edElement.CipherData.CipherValue = encryptedElement; EncryptedXml.ReplaceElement(element, edElement, false); return(xmlDoc.OuterXml); }
public Message SecureMessage() { secprop = Message.Properties.Security ?? new SecurityMessageProperty(); SecurityToken encToken = secprop.InitiatorToken != null ? secprop.InitiatorToken.SecurityToken : security.EncryptionToken; // FIXME: it might be still incorrect. SecurityToken signToken = Parameters == CounterParameters ? null : security.SigningToken; MessageProtectionOrder protectionOrder = security.MessageProtectionOrder; SecurityTokenSerializer serializer = security.TokenSerializer; SecurityBindingElement element = security.Element; SecurityAlgorithmSuite suite = element.DefaultAlgorithmSuite; // FIXME: remove this hack if (!ShouldOutputEncryptedKey) { encToken = new BinarySecretSecurityToken(secprop.EncryptionKey); } string messageId = "uuid-" + Guid.NewGuid(); int identForMessageId = 1; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; UniqueId relatesTo = RelatesTo; if (relatesTo != null) { msg.Headers.RelatesTo = relatesTo; } else // FIXME: probably it is always added when it is stateful ? { msg.Headers.MessageId = new UniqueId("urn:" + messageId); } // FIXME: get correct ReplyTo value if (Direction == MessageDirection.Input) { msg.Headers.Add(MessageHeader.CreateHeader("ReplyTo", msg.Version.Addressing.Namespace, EndpointAddress10.FromEndpointAddress(new EndpointAddress(Constants.WsaAnonymousUri)))); } if (MessageTo != null) { msg.Headers.Add(MessageHeader.CreateHeader("To", msg.Version.Addressing.Namespace, MessageTo.Uri.AbsoluteUri, true)); } // wss:Security WSSecurityMessageHeader header = new WSSecurityMessageHeader(serializer); msg.Headers.Add(header); // 1. [Timestamp] if (element.IncludeTimestamp) { WsuTimestamp timestamp = new WsuTimestamp(); timestamp.Id = messageId + "-" + identForMessageId++; timestamp.Created = DateTime.Now; // FIXME: on service side, use element.LocalServiceSettings.TimestampValidityDuration timestamp.Expires = timestamp.Created.Add(element.LocalClientSettings.TimestampValidityDuration); header.AddContent(timestamp); } XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); nsmgr.AddNamespace("s", msg.Version.Envelope.Namespace); nsmgr.AddNamespace("o", Constants.WssNamespace); nsmgr.AddNamespace("u", Constants.WsuNamespace); nsmgr.AddNamespace("o11", Constants.Wss11Namespace); /*WrappedKey*/ SecurityToken primaryToken = null; DerivedKeySecurityToken dkeyToken = null; SecurityToken actualToken = null; SecurityKeyIdentifierClause actualClause = null; Signature sig = null; List <DerivedKeySecurityToken> derivedKeys = new List <DerivedKeySecurityToken> (); SymmetricAlgorithm masterKey = new RijndaelManaged(); masterKey.KeySize = suite.DefaultSymmetricKeyLength; masterKey.Mode = CipherMode.CBC; masterKey.Padding = PaddingMode.ISO10126; SymmetricAlgorithm actualKey = masterKey; // 2. [Encryption Token] // SecurityTokenInclusionMode // - Initiator or Recipient // - done or notyet. FIXME: not implemented yet // It also affects on key reference output bool includeEncToken = // /* FIXME: remove this hack */Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken( Security.RecipientParameters.InclusionMode, false); bool includeSigToken = // /* FIXME: remove this hack */ Parameters is SslSecurityTokenParameters ? false : ShouldIncludeToken( Security.InitiatorParameters.InclusionMode, false); SecurityKeyIdentifierClause encClause = ShouldOutputEncryptedKey ? CounterParameters.CallCreateKeyIdentifierClause(encToken, !ShouldOutputEncryptedKey ? SecurityTokenReferenceStyle.Internal : includeEncToken ? Parameters.ReferenceStyle : SecurityTokenReferenceStyle.External) : null; MessagePartSpecification sigSpec = SignaturePart; MessagePartSpecification encSpec = EncryptionPart; // encryption key (possibly also used for signing) // FIXME: get correct SymmetricAlgorithm according to the algorithm suite if (secprop.EncryptionKey != null) { actualKey.Key = secprop.EncryptionKey; } // FIXME: remove thid hack if (!ShouldOutputEncryptedKey) { primaryToken = RequestContext.RequestMessage.Properties.Security.ProtectionToken.SecurityToken as WrappedKeySecurityToken; } else { primaryToken = // FIXME: remove this hack? encToken is SecurityContextSecurityToken ? encToken : new WrappedKeySecurityToken(messageId + "-" + identForMessageId++, actualKey.Key, // security.DefaultKeyWrapAlgorithm, Parameters.InternalHasAsymmetricKey ? suite.DefaultAsymmetricKeyWrapAlgorithm : suite.DefaultSymmetricKeyWrapAlgorithm, encToken, encClause != null ? new SecurityKeyIdentifier(encClause) : null); } // If it reuses request's encryption key, do not output. if (ShouldOutputEncryptedKey) { header.AddContent(primaryToken); } actualToken = primaryToken; // FIXME: I doubt it is correct... WrappedKeySecurityToken requestEncKey = ShouldOutputEncryptedKey ? null : primaryToken as WrappedKeySecurityToken; actualClause = requestEncKey == null ? (SecurityKeyIdentifierClause) new LocalIdKeyIdentifierClause(actualToken.Id, typeof(WrappedKeySecurityToken)) : new InternalEncryptedKeyIdentifierClause(SHA1.Create().ComputeHash(requestEncKey.GetWrappedKey())); // generate derived key if needed if (CounterParameters.RequireDerivedKeys) { RijndaelManaged deriv = new RijndaelManaged(); deriv.KeySize = suite.DefaultEncryptionKeyDerivationLength; deriv.Mode = CipherMode.CBC; deriv.Padding = PaddingMode.ISO10126; deriv.GenerateKey(); dkeyToken = new DerivedKeySecurityToken( GenerateId(doc), null, // algorithm actualClause, new InMemorySymmetricSecurityKey(actualKey.Key), null, // name null, // generation null, // offset deriv.Key.Length, null, // label deriv.Key); derivedKeys.Add(dkeyToken); actualToken = dkeyToken; actualKey.Key = ((SymmetricSecurityKey)dkeyToken.SecurityKeys [0]).GetSymmetricKey(); actualClause = new LocalIdKeyIdentifierClause(dkeyToken.Id); header.AddContent(dkeyToken); } ReferenceList refList = new ReferenceList(); // When encrypted with DerivedKeyToken, put references // immediately after the derived token (not inside the // primary token). // Similarly, when we do not output EncryptedKey, // output ReferenceList in the same way. if (CounterParameters.RequireDerivedKeys || !ShouldOutputEncryptedKey) { header.AddContent(refList); } else { ((WrappedKeySecurityToken)primaryToken).ReferenceList = refList; } // [Signature Confirmation] if (security.RequireSignatureConfirmation && secprop.ConfirmedSignatures.Count > 0) { foreach (string value in secprop.ConfirmedSignatures) { header.AddContent(new Wss11SignatureConfirmation(GenerateId(doc), value)); } } SupportingTokenInfoCollection tokenInfos = Direction == MessageDirection.Input ? security.CollectSupportingTokens(GetAction()) : new SupportingTokenInfoCollection(); // empty foreach (SupportingTokenInfo tinfo in tokenInfos) { header.AddContent(tinfo.Token); } // populate DOM to sign. XPathNavigator nav = doc.CreateNavigator(); using (XmlWriter w = nav.AppendChild()) { msg.WriteMessage(w); } XmlElement body = doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement; string bodyId = null; XmlElement secElem = null; Collection <WSSignedXml> endorsedSignatures = new Collection <WSSignedXml> (); bool signatureProtection = (protectionOrder == MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature); // Below are o:Security contents that are not signed... if (includeSigToken && signToken != null) { header.AddContent(signToken); } switch (protectionOrder) { case MessageProtectionOrder.EncryptBeforeSign: // FIXME: implement throw new NotImplementedException(); case MessageProtectionOrder.SignBeforeEncrypt: case MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature: // sign // see clause 8 of WS-SecurityPolicy C.2.2 WSSignedXml sxml = new WSSignedXml(doc); SecurityTokenReferenceKeyInfo sigKeyInfo; sig = sxml.Signature; sig.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/u:Timestamp", nsmgr)) { CreateReference(sig, elem, elem.GetAttribute("Id", Constants.WsuNamespace)); } foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) { CreateReference(sig, elem, elem.GetAttribute("Id", Constants.WsuNamespace)); } foreach (SupportingTokenInfo tinfo in tokenInfos) { if (tinfo.Mode != SecurityTokenAttachmentMode.Endorsing) { XmlElement el = sxml.GetIdElement(doc, tinfo.Token.Id); CreateReference(sig, el, el.GetAttribute("Id", Constants.WsuNamespace)); } } XmlNodeList nodes = doc.SelectNodes("/s:Envelope/s:Header/*", nsmgr); for (int i = 0; i < msg.Headers.Count; i++) { MessageHeaderInfo h = msg.Headers [i]; if (h.Name == "Security" && h.Namespace == Constants.WssNamespace) { secElem = nodes [i] as XmlElement; } else if (sigSpec.HeaderTypes.Count == 0 || sigSpec.HeaderTypes.Contains(new XmlQualifiedName(h.Name, h.Namespace))) { string id = GenerateId(doc); h.Id = id; CreateReference(sig, nodes [i] as XmlElement, id); } } if (sigSpec.IsBodyIncluded) { bodyId = GenerateId(doc); CreateReference(sig, body.ParentNode as XmlElement, bodyId); } if (security.DefaultSignatureAlgorithm == SignedXml.XmlDsigHMACSHA1Url) { // FIXME: use appropriate hash algorithm sxml.ComputeSignature(new HMACSHA1(actualKey.Key)); sigKeyInfo = new SecurityTokenReferenceKeyInfo(actualClause, serializer, doc); } else { SecurityKeyIdentifierClause signClause = CounterParameters.CallCreateKeyIdentifierClause(signToken, includeSigToken ? CounterParameters.ReferenceStyle : SecurityTokenReferenceStyle.External); AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)signToken.ResolveKeyIdentifierClause(signClause); sxml.SigningKey = signKey.GetAsymmetricAlgorithm(security.DefaultSignatureAlgorithm, true); sxml.ComputeSignature(); sigKeyInfo = new SecurityTokenReferenceKeyInfo(signClause, serializer, doc); } sxml.KeyInfo = new KeyInfo(); sxml.KeyInfo.AddClause(sigKeyInfo); if (!signatureProtection) { header.AddContent(sig); } // endorse the signature with (signed)endorsing // supporting tokens. foreach (SupportingTokenInfo tinfo in tokenInfos) { switch (tinfo.Mode) { case SecurityTokenAttachmentMode.Endorsing: case SecurityTokenAttachmentMode.SignedEndorsing: if (sxml.Signature.Id == null) { sig.Id = GenerateId(doc); secElem.AppendChild(sxml.GetXml()); } WSSignedXml ssxml = new WSSignedXml(doc); ssxml.Signature.SignedInfo.CanonicalizationMethod = suite.DefaultCanonicalizationAlgorithm; CreateReference(ssxml.Signature, doc, sig.Id); SecurityToken sst = tinfo.Token; SecurityKey ssk = sst.SecurityKeys [0]; // FIXME: could be different? SecurityKeyIdentifierClause tclause = new LocalIdKeyIdentifierClause(sst.Id); // FIXME: could be different? if (ssk is SymmetricSecurityKey) { SymmetricSecurityKey signKey = (SymmetricSecurityKey)ssk; ssxml.ComputeSignature(signKey.GetKeyedHashAlgorithm(suite.DefaultSymmetricSignatureAlgorithm)); } else { AsymmetricSecurityKey signKey = (AsymmetricSecurityKey)ssk; ssxml.SigningKey = signKey.GetAsymmetricAlgorithm(suite.DefaultAsymmetricSignatureAlgorithm, true); ssxml.ComputeSignature(); } ssxml.KeyInfo.AddClause(new SecurityTokenReferenceKeyInfo(tclause, serializer, doc)); if (!signatureProtection) { header.AddContent(ssxml.Signature); } endorsedSignatures.Add(ssxml); break; } } // encrypt WSEncryptedXml exml = new WSEncryptedXml(doc); EncryptedData edata = Encrypt(body, actualKey, actualToken.Id, refList, actualClause, exml, doc); EncryptedXml.ReplaceElement(body, edata, false); // encrypt signature if (signatureProtection) { XmlElement sigxml = sig.GetXml(); edata = Encrypt(sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc); header.AddContent(edata); foreach (WSSignedXml ssxml in endorsedSignatures) { sigxml = ssxml.GetXml(); edata = Encrypt(sigxml, actualKey, actualToken.Id, refList, actualClause, exml, doc); header.AddContent(edata); } if (security.RequireSignatureConfirmation) { Collection <Wss11SignatureConfirmation> confs = header.FindAll <Wss11SignatureConfirmation> (); int count = 0; foreach (XmlElement elem in doc.SelectNodes("/s:Envelope/s:Header/o:Security/o11:SignatureConfirmation", nsmgr)) { edata = Encrypt(elem, actualKey, confs [count].Id, refList, actualClause, exml, doc); EncryptedXml.ReplaceElement(elem, edata, false); header.Contents.Insert(header.Contents.IndexOf(confs [count]), edata); header.Contents.Remove(confs [count++]); } } } // encrypt Encrypted supporting tokens foreach (SupportingTokenInfo tinfo in tokenInfos) { if (tinfo.Mode == SecurityTokenAttachmentMode.SignedEncrypted) { XmlElement el = exml.GetIdElement(doc, tinfo.Token.Id); tinfo.Encrypted = Encrypt(el, actualKey, actualToken.Id, refList, actualClause, exml, doc); EncryptedXml.ReplaceElement(el, tinfo.Encrypted, false); header.Contents.Insert(header.Contents.IndexOf(tinfo.Token), tinfo.Encrypted); header.Contents.Remove(tinfo.Token); } } break; } Message ret = Message.CreateMessage(msg.Version, msg.Headers.Action, new XmlNodeReader(doc.SelectSingleNode("/s:Envelope/s:Body/*", nsmgr) as XmlElement)); ret.Properties.Security = (SecurityMessageProperty)secprop.CreateCopy(); ret.Properties.Security.EncryptionKey = masterKey.Key; ret.BodyId = bodyId; // FIXME: can we support TransportToken here? if (element is AsymmetricSecurityBindingElement) { ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification(encToken, null); // FIXME: second argument ret.Properties.Security.InitiatorToken = new SecurityTokenSpecification(signToken, null); // FIXME: second argument } else { ret.Properties.Security.ProtectionToken = new SecurityTokenSpecification(primaryToken, null); } ret.Headers.Clear(); ret.Headers.CopyHeadersFrom(msg); // Header contents are: // - Timestamp // - SignatureConfirmation if required // - EncryptionToken if included // - derived key token for EncryptionToken // - ReferenceList for encrypted items // - signed supporting tokens // - signed endorsing supporting tokens // (i.e. Signed/SignedEncrypted/SignedEndorsing) // - Signature Token if different from enc token. // - derived key token for sig token if different // - Signature for: // - Timestamp // - supporting tokens (regardless of // its inclusion) // - message parts in SignedParts // - SignatureToken if TokenProtection // (regardless of its inclusion) // - Signatures for the main signature (above), // for every endorsing token and signed // endorsing token. // //MessageBuffer zzz = ret.CreateBufferedCopy (100000); //ret = zzz.CreateMessage (); //Console.WriteLine (zzz.CreateMessage ()); return(ret); }
/// <summary> /// XML数据加密 /// </summary> /// <param name="xmlDocument">XML 文档的实例</param> /// <param name="nodeName">需要加密的 XML 节点名字</param> /// <param name="key">密钥</param> public void Encrypt(XmlDocument xmlDocument, string nodeName) { // 检查参数 if (xmlDocument == null) { throw new ArgumentNullException("xmlDocument"); } if (nodeName == null || nodeName.Length == 0) { throw new ArgumentNullException("nodeName"); } if (mKey == null) { throw new ArgumentNullException("mKey"); } //////////////////////////////////////////////// // 在XmlDocument找到指定的元素对象,并创建一个新的XmlElemnt对象。 //////////////////////////////////////////////// XmlElement elementToEncrypt = xmlDocument.GetElementsByTagName(nodeName)[0] as XmlElement; // 如果元素不能被发现,抛出一个XmlException。 if (elementToEncrypt == null) { throw new XmlException("指定的元素不能被发现"); } ////////////////////////////////////////////////// // 创建一个新的实例的EncryptedXml类和使用它来加密XmlElement和对称密钥 ////////////////////////////////////////////////// EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, mKey, false); //////////////////////////////////////////////// // 构造一个EncryptedData对象并填充所需的加密信息。 //////////////////////////////////////////////// EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; // 创建一个EncryptionMethod元素,以便接收方知道这算法用于解密。 // 确定什么样的算法被使用和供应适当的URL到EncryptionMethod元素。 string encryptionMethod = null; if (mKey is Rijndael) { switch (mKey.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; default: throw new CryptographicException("此算法只支持16位, 24位, 32位的密钥"); } } else { // 如果变换不是在前面的类别,抛出一个异常 throw new CryptographicException("指定的算法不支持XML加密"); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); // 添加加密元素数据到EncryptedData对象。 edElement.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // 从原始XmlDocument对象与EncryptedData元素替换元素。 //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }
public void RoundtripSample1() { using (StringWriter sw = new StringWriter()) { // Encryption { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml("<root> <child>sample</child> </root>"); XmlElement body = doc.DocumentElement; using (Aes aes = Aes.Create()) { aes.Mode = CipherMode.CBC; aes.KeySize = 256; aes.IV = Convert.FromBase64String("pBUM5P03rZ6AE4ZK5EyBrw=="); aes.Key = Convert.FromBase64String("o/ilseZu+keLBBWGGPlUHweqxIPc4gzZEFWr2nBt640="); aes.Padding = PaddingMode.Zeros; EncryptedXml exml = new EncryptedXml(); byte[] encrypted = exml.EncryptData(body, aes, false); EncryptedData edata = new EncryptedData(); edata.Type = EncryptedXml.XmlEncElementUrl; edata.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url); EncryptedKey ekey = new EncryptedKey(); // omit key encryption, here for testing byte[] encKeyBytes = aes.Key; ekey.CipherData = new CipherData(encKeyBytes); ekey.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url); DataReference dr = new DataReference(); dr.Uri = "_0"; ekey.AddReference(dr); edata.KeyInfo.AddClause(new KeyInfoEncryptedKey(ekey)); ekey.KeyInfo.AddClause(new RSAKeyValue(RSA.Create())); edata.CipherData.CipherValue = encrypted; EncryptedXml.ReplaceElement(doc.DocumentElement, edata, false); doc.Save(new XmlTextWriter(sw)); } } // Decryption { using (Aes aes = Aes.Create()) { aes.Mode = CipherMode.CBC; aes.KeySize = 256; aes.Key = Convert.FromBase64String( "o/ilseZu+keLBBWGGPlUHweqxIPc4gzZEFWr2nBt640="); aes.Padding = PaddingMode.Zeros; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(sw.ToString()); EncryptedXml encxml = new EncryptedXml(doc); EncryptedData edata = new EncryptedData(); edata.LoadXml(doc.DocumentElement); encxml.ReplaceData(doc.DocumentElement, encxml.DecryptData(edata, aes)); } } } }
/// <summary> /// Retrieves a certificate from the Personal Certificate Store in Windows. /// </summary> /// <param name="sujetoCertificado"></param> /// <returns></returns> static void Encriptar(ref XmlDocument document, string elementoParaEncriptar, X509Certificate2 certificadopublico, ref XmlElement securityNode) { RSACryptoServiceProvider rsaAlgorithm = (RSACryptoServiceProvider)certificadopublico.PublicKey.Key; //llave publica usada para encriptar. //Ahora creamos un BinarySecurityToken que será el certificado x509 de la clave pública //se usa para que el receptor sepa qué certificado se usó para encriptar. XmlElement binarySecurityTokenNode = document.CreateElement("wsse", "BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); //El atributo EncodingType dice cómo el Token está codificado, en este caso, Base64Binary. binarySecurityTokenNode.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"); //El atributo ValueType indica qué es el BinarySecurityToken, en este caso un Certificado X509v3. binarySecurityTokenNode.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"); binarySecurityTokenNode.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", XmlElementsIds.PublicKeyBinarySecurityTokenUri); XmlAttribute attribute = binarySecurityTokenNode.GetAttributeNode("Id"); attribute.Prefix = "wsu"; binarySecurityTokenNode.InnerText = Convert.ToBase64String(certificadopublico.GetRawCertData()); //Creamos una llave simétrica la cuál servirá para codificar la información. //AES-128-CBC AesManaged algoritmosimetrico = new AesManaged() { Padding = PaddingMode.ISO10126, KeySize = 128, Mode = CipherMode.CBC, }; System.Security.Cryptography.Xml.EncryptedKey encryptedKey = new System.Security.Cryptography.Xml.EncryptedKey(); encryptedKey.EncryptionMethod = new System.Security.Cryptography.Xml.EncryptionMethod(EncryptedXml.XmlEncRSAOAEPUrl); encryptedKey.AddReference(new DataReference("#ED-31")); SecurityTokenReference securityTokenReference = new SecurityTokenReference(); securityTokenReference.Reference = XmlElementsIds.PublicKeyBinarySecurityTokenUri; securityTokenReference.ValueType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"; KeyInfo ekkeyInfo = new KeyInfo(); ekkeyInfo.AddClause(new KeyInfoNode(securityTokenReference.GetXml())); encryptedKey.KeyInfo = ekkeyInfo; encryptedKey.CipherData = new CipherData(EncryptedXml.EncryptKey(algoritmosimetrico.Key, rsaAlgorithm, true)); securityNode.PrependChild(document.ImportNode(encryptedKey.GetXml(), true)); securityNode.PrependChild(binarySecurityTokenNode); //Crear un XmlElement a través del nombre del Tag que se encuentra en el documento Xml especificado. XmlElement elementoParaEncriptarXML = document.GetElementsByTagName(elementoParaEncriptar)[0] as XmlElement; //Creamos una instancia de la clase EncryptedXml y usarla para encriptar //el XmlElement: elementoParaEncriptarXML; usando la llave simétrica que acabamos de //crear. EncryptedXml xmlEncriptado = new EncryptedXml(); //Encriptamos el Body (elementoParaEncriptarXML) usando el algoritmo simétrico AES-128-CBC y lo dejamos ahí. byte[] elementoEncriptado = xmlEncriptado.EncryptData(elementoParaEncriptarXML, algoritmosimetrico, false); //Ahora creamos una instancia de la clase EncryptedData que representa //un elemento <EncryptedData> en el documento XML. System.Security.Cryptography.Xml.EncryptedData encryptedData = new System.Security.Cryptography.Xml.EncryptedData() { Type = EncryptedXml.XmlEncElementContentUrl, Id = "ED-31", //Le asignamos otra propiedad a este elemento <EncryptedData> que es un EncryptionMethod //para que el receptor sepa que algoritmo usar para descifrar EncryptionMethod = new System.Security.Cryptography.Xml.EncryptionMethod(EncryptedXml.XmlEncAES128Url) //Aes-128-cbc o Rjindael. }; encryptedData.CipherData = new CipherData(elementoEncriptado); /* Para descencriptar: Funciona, es para testear si puedo desencriptar los datos. * var lmao= xmlEncriptado.DecryptData(encryptedData, algoritmosimetrico); * var decrypted = Encoding.UTF8.GetString(lmao); */ //Reemplazamos el elemento quotationCarGenericRq sin encriptar del documento XML con el elemento <EncryptedData> (que contiene el Body y sus contenidos encriptados) básicamente. //totalmente lleno. EncryptedXml.ReplaceElement(elementoParaEncriptarXML, encryptedData, false); }
public void EncrypyXmlElement(XmlDocument doc, string elementName) { // Check the arguments. if (doc == null) { throw new ArgumentNullException("Doc"); } if (elementName == null) { throw new ArgumentNullException("ElementToEncrypt"); } SymmetricAlgorithm algorithm = _rijndaelManaged; algorithm.Padding = PaddingMode.Zeros; //////////////////////////////////////////////// // Find the specified element in the XmlDocument // object and create a new XmlElemnt object. //////////////////////////////////////////////// var elementToEncrypt = doc.GetElementsByTagName(elementName)[0] as XmlElement; // Throw an XmlException if the element was not found. if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } ////////////////////////////////////////////////// // Create a new instance of the EncryptedXml class // and use it to encrypt the XmlElement with the // symmetric key. ////////////////////////////////////////////////// var encryptedXml = new EncryptedXml(); encryptedXml.Padding = PaddingMode.Zeros; var encryptedElement = encryptedXml.EncryptData(elementToEncrypt, algorithm, false); //////////////////////////////////////////////// // Construct an EncryptedData object and populate // it with the desired encryption information. //////////////////////////////////////////////// var element = new EncryptedData(); element.Type = EncryptedXml.XmlEncElementUrl; // Create an EncryptionMethod element so that the receiver knows which algorithm to use // for decryption. Determine what kind of algorithm is being used and supply the // appropriate URL to the EncryptionMethod element. string encryptionMethod = null; if (algorithm is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (algorithm is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (algorithm is Rijndael) { switch (algorithm.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; } } else { // Throw an exception if the transform is not in the previous categories throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } element.EncryptionMethod = new EncryptionMethod(encryptionMethod); // Add the encrypted element data to the EncryptedData object. element.CipherData.CipherValue = encryptedElement; //////////////////////////////////////////////////// // Replace the element from the original XmlDocument // object with the EncryptedData element. //////////////////////////////////////////////////// EncryptedXml.ReplaceElement(elementToEncrypt, element, false); }
public static void Encrypt(XmlDocument doc) { SymmetricAlgorithm symAlgo = new RijndaelManaged(); byte[] salt = Encoding.ASCII.GetBytes("This is my salt"); Rfc2898DeriveBytes theKey = new Rfc2898DeriveBytes("myclass", salt); symAlgo.Key = theKey.GetBytes(symAlgo.KeySize / 8); symAlgo.IV = theKey.GetBytes(symAlgo.BlockSize / 8); if (doc == null) { throw new ArgumentNullException("Doc"); } if (symAlgo == null) { throw new ArgumentNullException("Alg"); } XmlElement elementToEncrypt = doc.DocumentElement; if (elementToEncrypt == null) { throw new XmlException("The specified element was not found"); } EncryptedXml eXml = new EncryptedXml(); byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, symAlgo, false); EncryptedData edElement = new EncryptedData(); edElement.Type = EncryptedXml.XmlEncElementUrl; string encryptionMethod = null; if (symAlgo is TripleDES) { encryptionMethod = EncryptedXml.XmlEncTripleDESUrl; } else if (symAlgo is DES) { encryptionMethod = EncryptedXml.XmlEncDESUrl; } if (symAlgo is Rijndael) { switch (symAlgo.KeySize) { case 128: encryptionMethod = EncryptedXml.XmlEncAES128Url; break; case 192: encryptionMethod = EncryptedXml.XmlEncAES192Url; break; case 256: encryptionMethod = EncryptedXml.XmlEncAES256Url; break; default: // do the defalut action break; } } else { throw new CryptographicException("The specified algorithm is not supported for XML Encryption."); } edElement.EncryptionMethod = new EncryptionMethod(encryptionMethod); edElement.CipherData.CipherValue = encryptedElement; EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false); }