예제 #1
0
 public override XmlElement GetXml()
 {
     if (_encryptedKey == null)
     {
         throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "KeyInfoEncryptedKey");
     }
     return(_encryptedKey.GetXml());
 }
예제 #2
0
 public override XmlElement GetXml()
 {
     if (m_encryptedKey == null)
     {
         throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "KeyInfoEncryptedKey");
     }
     return(m_encryptedKey.GetXml());
 }
예제 #3
0
 internal XmlElement GetXml(XmlDocument document)
 {
     if (encryptedKey != null)
     {
         return(encryptedKey.GetXml(document));
     }
     return(null);
 }
예제 #4
0
        /// <summary>
        /// Encrypts the NameID attribute of the AttributeQuery request.
        /// </summary>
        /// <param name="certFriendlyName">
        /// Friendly Name of the X509Certificate to be retrieved
        /// from the LocalMachine keystore and used to encrypt generated symmetric key.
        /// Be sure to have appropriate permissions set on the keystore.
        /// </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 certFriendlyName, string symmetricAlgorithmUri, XmlDocument xmlDoc)
        {
            if (string.IsNullOrWhiteSpace(certFriendlyName))
            {
                throw new Saml2Exception(Resources.EncryptedXmlInvalidCertFriendlyName);
            }

            if (string.IsNullOrWhiteSpace(symmetricAlgorithmUri))
            {
                throw new Saml2Exception(Resources.EncryptedXmlInvalidEncrAlgorithm);
            }

            if (xmlDoc == null)
            {
                throw new Saml2Exception(Resources.SignedXmlInvalidXml);
            }

            X509Certificate2 cert = FedletCertificateFactory.GetCertificateByFriendlyName(certFriendlyName);
            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);
        }
예제 #5
0
        /// <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);
        }