public XElement Serialize(bool ignoreDsNamespace)
        {
            var result = new XElement(Constants.XMLNamespaces.DS + "KeyInfo");

            if (!ignoreDsNamespace)
            {
                result.Add(new XAttribute(XNamespace.Xmlns + "ds", Constants.XMLNamespaces.DS));
            }

            if (!string.IsNullOrWhiteSpace(Id))
            {
                result.Add(new XAttribute("Id", Id));
            }

            if (SecurityTokenReference != null)
            {
                result.Add(SecurityTokenReference.Serialize());
            }

            if (X509Data != null)
            {
                result.Add(X509Data.Serialize());
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public KeyInfoNode addSecurityTokenReference()
        {
            XmlElement securityTokenRef = SecurityTokenReference.xmlKeyInfoSecurityTokenReference(_doc, uuid);
            var        keyInfoData      = new KeyInfoNode(securityTokenRef);

            return(keyInfoData);
        }
        protected void CreateToken(SoapEnvelope soap, X509Certificate2 certificateSignature, XmlElement nodeKeyInfo)
        {
            SecurityTokenReference tokenRef          = new SecurityTokenReference();
            XmlElement             tokenXmlReference = tokenRef.GetXml(soap);

            var nodeX509Data = CreateNode(tokenXmlReference, Constants.DATA);

            var nodeX509IssuerSerial = CreateNode(nodeX509Data, Constants.ISSUER_SERIAL);

            nodeX509Data.AppendChild(nodeX509IssuerSerial);

            var nodeX509IssuerName = CreateNode(nodeX509IssuerSerial, Constants.ISSUER_NAME);

            nodeX509IssuerName.InnerText = certificateSignature.Issuer;

            var nodeX509SerialNumber = CreateNode(nodeX509IssuerSerial, Constants.SERIAL_NUMBER);

            nodeX509SerialNumber.InnerText = Convert.ToString(Convert.ToInt64(certificateSignature.SerialNumber, 16));

            nodeX509IssuerSerial.AppendChild(nodeX509IssuerName);
            nodeX509IssuerSerial.AppendChild(nodeX509SerialNumber);

            tokenXmlReference.AppendChild(nodeX509Data);

            nodeKeyInfo.AppendChild(tokenXmlReference);
        }
        private GenericXmlSecurityKeyIdentifierClause CreateKeyIdentifierClause(SecurityTokenReference reference, bool attached)
        {
            var document = XmlHelper.CreateElement(writer => WriteSecurityTokenReference(writer, reference, attached));

            if (document == null)
            {
                return(null);
            }
            return(new GenericXmlSecurityKeyIdentifierClause(reference.KeyIdentifier.Id ?? reference.KeyIdentifier.Value, document.FirstChild as XmlElement));
        }
        public override SecurityTokenReference CreateReference()
        {
            var keyIdentifier = new KeyIdentifier(_token.Id)
            {
                ValueType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID",
            };
            var reference = new SecurityTokenReference(keyIdentifier)
            {
                TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"
            };

            return(reference);
        }
Exemple #6
0
        private AS4EncryptedKey(EncryptedKey encryptedKey, SecurityTokenReference securityTokenReference, string digestAlgorithm, string mgfAlgorithm)
        {
            _encryptedKey    = encryptedKey;
            _digestAlgorithm = digestAlgorithm;
            _mgfAlgorithm    = mgfAlgorithm;

            SecurityTokenReference = securityTokenReference;

            if (SecurityTokenReference != null)
            {
                encryptedKey.KeyInfo.AddClause(SecurityTokenReference);
            }
        }
        private void WriteSecurityTokenReference(XmlDictionaryWriter writer, SecurityTokenReference reference, bool attached)
        {
            var context = new WsSerializationContext(_version);

            if (attached)
            {
                WsTrustSerializer.WriteRequestedAttachedReference(writer, context, reference);
            }
            else
            {
                WsTrustSerializer.WriteRequestedUnattachedReference(writer, context, reference);
            }
        }
		public DerivedKeyToken(byte [] origKey)
		{
			length = XmlSigHandler.NumKeyBytes;

			secTokRef = new SecurityTokenReference();
			secTokRef.Reference = new Reference();
			secTokRef.Reference.ValueType = "http://schemas.xmlsoap.org/ws/2004/04/security/sc/sct";

			byte [] baNonce = OpenNETCF.Security.Cryptography.NativeMethods.Rand.GetRandomBytes(20);
			nonce = Convert.ToBase64String(baNonce, 0, baNonce.Length);

			derKey = P_SHA1.DeriveKey(origKey, this.label, baNonce, length);

			System.Guid g = GuidEx.NewGuid();
			this.id = "SecurityToken-" + g.ToString("D");
		}
        private GenericXmlSecurityKeyIdentifierClause GetSecurityKeyIdentifierForTokenReference(SecurityTokenReference securityTokenReference)
        {
            if (securityTokenReference == null)
            {
                return(null);
            }

            return(new GenericXmlSecurityKeyIdentifierClause(WsSecuritySerializer.CreateXmlElement(securityTokenReference)));
        }
Exemple #10
0
        private SoapFilterResult Sign(SoapEnvelope envelope)
        {
            XmlNode securityNode = envelope.CreateNode(XmlNodeType.Element, "wsse:Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            envelope.PreserveWhitespace = false;

            /*
             * <wsu:Timestamp wsu:Id="Timestamp-10ba255c-ea41-4041-ab07-2b7a3220ef88">
             * <wsu:Created>2011-01-07T07:49:08Z</wsu:Created>
             * <wsu:Expires>2011-01-07T07:54:08Z</wsu:Expires>
             * </wsu:Timestamp>
             */
            XmlNode timestampNode = envelope.CreateNode(
                XmlNodeType.Element,
                "wsu:Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            XmlElement timestampElement = timestampNode as XmlElement;

            XmlAttribute IdAttTs = envelope.CreateAttribute("wsu", "Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            IdAttTs.Value = "Timestamp-" + Guid.NewGuid().ToString();

            XmlNode created = envelope.CreateNode(XmlNodeType.Element, "wsu:Created", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            created.InnerText = DateTime.Now.ToUniversalTime().ToString("o");

            DateTime expiration = DateTime.Now.AddMinutes(5);
            XmlNode  expires    = envelope.CreateNode(XmlNodeType.Element, "wsu:Expires", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            expires.InnerText = expiration.ToUniversalTime().ToString("o");

            timestampElement.Attributes.Append(IdAttTs);
            timestampElement.AppendChild(created);
            timestampElement.AppendChild(expires);

            XmlNode binarySecurityTokenNode = envelope.CreateNode(
                XmlNodeType.Element,
                "wsse:BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            XmlElement binarySecurityTokenElement = binarySecurityTokenNode as XmlElement;

            binarySecurityTokenElement.SetAttribute(
                "xmlns:wsu",
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            binarySecurityTokenElement.SetAttribute(
                "EncodingType",
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            binarySecurityTokenElement.SetAttribute(
                "ValueType",
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");

            XmlAttribute IdAtt = envelope.CreateAttribute("wsu", "Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            IdAtt.Value = _parentAssertion.Token.Id;
            binarySecurityTokenElement.Attributes.Append(IdAtt);

            byte[] publicCert = _parentAssertion.Token.Certificate.GetRawCertData();
            binarySecurityTokenElement.InnerXml = Convert.ToBase64String(publicCert, Base64FormattingOptions.None);

            SignatureFramework.SignedXml signature = new SignatureFramework.SignedXml(envelope);
            signature.Signature.Id = "Signature-" + Guid.NewGuid().ToString();

            KeyInfo ki = new KeyInfo();

            ki.Id = "KeyInfo-" + Guid.NewGuid().ToString();
            SecurityTokenReference sectokenReference = new SecurityTokenReference(_parentAssertion.Token, SecurityTokenReference.SerializationOptions.Reference);

            ki.AddClause(sectokenReference);

            signature.KeyInfo = ki;

            SignatureFramework.SignedInfo si = new SignatureFramework.SignedInfo();

            si.SignatureMethod = _parentAssertion.SignatureMethod;

            si.CanonicalizationMethod = SignatureFramework.XmlSignatureConstants.XmlDsigExcC14NTransformUrl;

            String bodyId = "Body-" + Guid.NewGuid().ToString();

            envelope.Body.SetAttribute("Id", bodyId);

            System.Security.Cryptography.Xml.Reference bsBody = new System.Security.Cryptography.Xml.Reference();
            bsBody.Uri = "#" + bodyId;
            bsBody.AddTransform(new System.Security.Cryptography.Xml.XmlDsigExcC14NTransform());
            si.AddReference(bsBody);

            System.Security.Cryptography.Xml.Reference refTimestamp = new System.Security.Cryptography.Xml.Reference();
            refTimestamp.Uri = "#" + IdAttTs.Value;
            refTimestamp.AddTransform(new System.Security.Cryptography.Xml.XmlDsigExcC14NTransform());
            si.AddReference(refTimestamp);

            signature.SignedInfo = si;

            bool disposeCryptoProvider = false;

            var key = (RSACryptoServiceProvider)_parentAssertion.Token.Certificate.PrivateKey;

            if (key.CspKeyContainerInfo.ProviderName == "Microsoft Strong Cryptographic Provider" ||
                key.CspKeyContainerInfo.ProviderName == "Microsoft Enhanced Cryptographic Provider v1.0" ||
                key.CspKeyContainerInfo.ProviderName == "Microsoft Base Cryptographic Provider v1.0" ||
                key.CspKeyContainerInfo.ProviderName == "Microsoft RSA SChannel Cryptographic Provider")
            {
                Type CspKeyContainerInfo_Type = typeof(CspKeyContainerInfo);

                FieldInfo     CspKeyContainerInfo_m_parameters = CspKeyContainerInfo_Type.GetField("m_parameters", BindingFlags.NonPublic | BindingFlags.Instance);
                CspParameters parameters = (CspParameters)CspKeyContainerInfo_m_parameters.GetValue(key.CspKeyContainerInfo);

                var cspparams = new CspParameters(24, "Microsoft Enhanced RSA and AES Cryptographic Provider", key.CspKeyContainerInfo.KeyContainerName);
                cspparams.KeyNumber  = parameters.KeyNumber;
                cspparams.Flags      = parameters.Flags;
                signature.SigningKey = new RSACryptoServiceProvider(cspparams);

                disposeCryptoProvider = true;
            }
            else
            {
                signature.SigningKey = _parentAssertion.Token.Certificate.PrivateKey;
            }

            securityNode.AppendChild(binarySecurityTokenNode);
            securityNode.AppendChild(timestampNode);
            envelope.ImportNode(securityNode, true);
            XmlNode node = envelope.Header;

            node.AppendChild(securityNode);

            signature.ComputeSignature();
            securityNode.AppendChild(envelope.ImportNode(signature.GetXml(), true));

            if (disposeCryptoProvider)
            {
                signature.SigningKey.Dispose();
            }

            return(SoapFilterResult.Continue);
        }
Exemple #11
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);
        }
Exemple #12
0
        /// <summary>
        /// Firmar y Encriptar el Documento XML usando un Certificado x509.
        /// </summary>
        /// <param name="xmldoc">el documento XML a firmar y encriptar.</param>
        /// <param name="certificado">el certificado para poder firmar el XML</param>
        /// <param name="certificadopublico">el certificado publico para poder encriptar</param>
        /// <returns></returns>
        private static XmlDocument FirmaryEncriptarSoapRequest(XmlDocument xmldoc, X509Certificate2 certificadoPrivado, X509Certificate2 certificadopublico)
        {
            #region Firmar
            //añadir las referencias de espacios de nombres para asegurarnos de que podamos trabajar contra
            //cualquier documento elemento XML sin importar el nombramiento de los Tags siempre y cuando sepamos sus Namespaces.
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmldoc.NameTable);
            namespaceManager.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            namespaceManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            namespaceManager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");

            //Seleccionar el Header para agregarle elementos.
            XmlElement headerNode = xmldoc.DocumentElement.SelectSingleNode("//soapenv:Header", namespaceManager) as XmlElement;
            //Creamos el nodo de seguridad <Security>
            XmlElement securityNode = xmldoc.CreateElement("wsse", "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            securityNode.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            securityNode.SetAttribute("mustUnderstand", "http://schemas.xmlsoap.org/soap/envelope/", "1");
            XmlAttribute mustUnderstandSecurityAttribute = securityNode.GetAttributeNode("mustUnderstand");
            mustUnderstandSecurityAttribute.Prefix = "soapenv";



            #region Preparar elementos a ser firmados


            //Ahora vamos a crear otro BinarySecurityToken

            //Ahora creamos un BinarySecurityToken que será el certificado x509 de la clave privada
            //Con este BinarySecurityToken se espera que el receptor pueda verificar el Digest de la firma que se
            //genera con este BinarySecurityToken.
            //este BinarySecurityToken es firmado también.

            XmlElement binarySecurityTokenNode2 = xmldoc.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.
            binarySecurityTokenNode2.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.
            binarySecurityTokenNode2.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");

            binarySecurityTokenNode2.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", XmlElementsIds.PrivateKeyBinarySecurityTokenUri);
            XmlAttribute attribute2 = binarySecurityTokenNode2.GetAttributeNode("Id");
            attribute2.Prefix = "wsu";
            binarySecurityTokenNode2.InnerText = Convert.ToBase64String(certificadoPrivado.GetRawCertData());

            //Creamos una estampa de tiempo, la cuál será firmada también:

            Timestamp timestamp = new Timestamp();
            timestamp.TtlInSeconds = 5000;

            //El body también será firmado, pero todavía no tiene los atributos requeridos para que pueda ser firmado
            //Aquí se los agrego.

            //Ahora vamos a ponerle un Id.
            XmlElement body = xmldoc.DocumentElement.SelectSingleNode("//soapenv:Body", namespaceManager) as XmlElement;
            body.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            body.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", XmlElementsIds.BodyId);
            var bodyId = body.GetAttributeNode("Id");
            bodyId.Prefix = "wsu";

            #endregion

            #region Agregar elementos a ser firmados al nodo Security



            securityNode.AppendChild(timestamp.GetXml(xmldoc));
            securityNode.AppendChild(binarySecurityTokenNode2);
            //agregar
            headerNode.AppendChild(securityNode);
            //el body ya existe, y no pertenece al nodo security.

            #endregion

            //Al momento de computar la firma, la clase SignedXml buscará las referencias previamente puestas, (las busca por los Id de cada uno
            //de los elementos a ser firmados.
            //y firmará los elementos que las referencias han referenciado
            //valga la redundancia.

            #region Crear firma XML


            //Ahora vamos a agregar un elemento Signature, que representa la firma digital.

            SignedXml signedXml = new SignedXmlWithId(xmldoc);

            signedXml.Signature.Id = "SIG-3";
            //la canonicalización indica como se deben interpretar los espacios en blanco y similares
            //porque el valor de firma puede cambiar inclusive cuando hayan espacios u otros caracteres-
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            //cual fue el algoritmo usado para firmar.
            signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

            //Cada una de las referencias apunta a un Id, que deberán tener los elementos
            //a ser firmados.


            System.Security.Cryptography.Xml.Reference reference = new System.Security.Cryptography.Xml.Reference
            {
                Uri = "#" + XmlElementsIds.PrivateKeyBinarySecurityTokenUri
            };
            reference.AddTransform(new XmlDsigExcC14NTransform(""));
            reference.DigestMethod = SignedXml.XmlDsigSHA1Url;

            System.Security.Cryptography.Xml.Reference reference2 = new System.Security.Cryptography.Xml.Reference
            {
                Uri = "#" + timestamp.Id
            };
            reference2.AddTransform(new XmlDsigExcC14NTransform("wsse lib soapenv"));
            reference2.DigestMethod = SignedXml.XmlDsigSHA1Url;

            System.Security.Cryptography.Xml.Reference reference3 = new System.Security.Cryptography.Xml.Reference
            {
                Uri = "#" + XmlElementsIds.BodyId
            };
            reference3.AddTransform(new XmlDsigExcC14NTransform("lib"));
            reference3.DigestMethod = SignedXml.XmlDsigSHA1Url;


            signedXml.SignedInfo.AddReference(reference);
            signedXml.SignedInfo.AddReference(reference2);
            signedXml.SignedInfo.AddReference(reference3);
            signedXml.SigningKey = certificadoPrivado.PrivateKey; //la clave privada para firmar.

            //La Keyinfo representa un identificador de un Token de seguridad.
            //en el caso de las firmas, identifica cómo encontrar el token que se usó para firmar.
            KeyInfo keyInfoInsideSignature = new KeyInfo();
            keyInfoInsideSignature.Id = "KI-D313N3M1G0";

            //en este caso Una referencia a un token de seguridad.
            SecurityTokenReference securityTokenReferenceInsideSignature = new SecurityTokenReference();
            securityTokenReferenceInsideSignature.Id        = "STR-SecurityTokenReference";
            securityTokenReferenceInsideSignature.ValueType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
            securityTokenReferenceInsideSignature.Reference = XmlElementsIds.PrivateKeyBinarySecurityTokenUri; //El BinarySecurityToken que contiene el Certificado x509v3 usado para la firma (usando su clave privada)
            KeyInfoClause keyInfoClauseInsideSignature = new KeyInfoNode(securityTokenReferenceInsideSignature.GetXml());
            keyInfoInsideSignature.AddClause(keyInfoClauseInsideSignature);

            signedXml.KeyInfo = keyInfoInsideSignature;


            signedXml.ComputeSignature();

            //revisar que la firma sea válida.(para propósitos de desarrollo)
            bool    firstcheck    = signedXml.CheckSignature(certificadoPrivado, true);
            XmlNode signatureNode = signedXml.GetXml(); //Finalmente ya obtenemos un elemento <signature> totalmente formado y listo para ser anexado al nodo <security>
            #endregion


            securityNode.AppendChild(signatureNode);



            #endregion

            #region Encriptar

            //Ahora vamos a obtener el certificado público, y usar su clave para encriptar el contenido del body

            Encriptar(ref xmldoc, "lib:quotationCarGenericRq", certificadopublico, ref securityNode);

            #endregion

            //Devolver un XML Firmado y Encriptado.
            #region testing, se puede dejar comentado:
            //HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://wsqa.libertycolombia.com.co:8443/soa-infra/services/GenericAuto/GenericAutoQuotation/GenericAutoQuotationMediator_ep");
            //req.Headers.Add("SOAPAction", "urn:quotationCarGeneric");
            //req.Method = "POST";
            //req.UserAgent = "Apache-HttpClient/4.1.1 (java 1.5)";
            //req.ContentType = "text/xml;charset=\"utf-8\"";
            //req.Host = "wsqa.libertycolombia.com.co:8443";

            ////XmlDocument xmldoctest = new XmlDocument();
            ////xmldoctest.Load(@"C:\Users\CarlosAlbertoFiguere\Desktop\test.xml");

            //using (Stream stream = req.GetRequestStream())
            //{
            //    using (StreamWriter streamWriter = new StreamWriter(stream))
            //    {
            //        streamWriter.Write(xmldoc.OuterXml);

            //    }

            //}
            //try
            //{
            //    WebResponse lol = req.GetResponse();
            //    string response = (new StreamReader(lol.GetResponseStream())).ReadToEnd();

            //}
            //catch (WebException wex)
            //{
            //    string response = (new StreamReader(wex.Response.GetResponseStream())).ReadToEnd();
            //}
            #endregion

            return(xmldoc);
        }
Exemple #13
0
        private GenericXmlSecurityKeyIdentifierClause GetSecurityKeyIdentifierForTokenReference(SecurityTokenReference securityTokenReference)
        {
            if (securityTokenReference == null)
            {
                return(null);
            }

            // this is tricky.
            // the SecurityTokenReference must be in the wsse namespace of the security binding that will communicate with the relying party.
            // the 'TokenType must be in wsse 1.1
            // TODO - need to create to obtain the actual security version that will be used for the relying party.
            // even though the MessageSecurityVersion is 1.1, the security header is written with 1.0
            return(new GenericXmlSecurityKeyIdentifierClause(WsSecuritySerializer.GetXmlElement(securityTokenReference, new WsSerializationContext(WsTrustVersion.TrustFeb2005))));
        }
        /// <summary>
        /// Create signed representation of the envelope
        /// </summary>
        /// <remarks>
        /// The WS-Security compliant signature must be crafted specifically
        /// for ePUAP.
        ///
        /// First and only documentation for this is the
        /// Instrukcja_dla_Integratora_DT.pdf from ePUAP website.
        ///
        /// I've tried a WCF client with custom binding with no result.
        /// </remarks>
        public virtual string GetSignedXML(X509Certificate2 signatureCertificate)
        {
            // check
            if (this.Header == null ||
                this.Header.Security == null ||
                this.Header.Security.BinarySecurityToken == null ||

                this.Body == null ||
                this.Body.Contents == null
                )
            {
                throw new ArgumentException("Can't compute signature of an incomplete Envelope");
            }
            if (signatureCertificate == null ||
                signatureCertificate.PrivateKey == null
                )
            {
                throw new ArgumentException("Can't compute signature without actual certificate");
            }

            // set ids
            var binarySecurityTokenId = string.Format("X509-{0}", Guid.NewGuid().ToString());
            var bodyId = string.Format("id-{0}", _random.Next());

            this.Body.Id = bodyId;
            this.Header.Security.BinarySecurityToken.Id = binarySecurityTokenId;
            this.Header.Security.BinarySecurityToken.SignatureCertificate = signatureCertificate;

            // sign
            var xml        = this.GetXML();
            var xmlrequest = new XmlDocument();

            xmlrequest.LoadXml(xml);

            var signedXml = new SignedXmlWithId(xmlrequest);

            signedXml.SigningKey = signatureCertificate.ToSha256PrivateKey();
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            signedXml.SignedInfo.SignatureMethod        = SignedXml.XmlDsigRSASHA256Url;

            // reference
            var reference = new Reference();

            reference.Uri = string.Format("#{0}", bodyId);

            // transform
            var c14transform = new XmlDsigExcC14NTransform();

            reference.AddTransform(c14transform);
            reference.DigestMethod = SignedXml.XmlDsigSHA256Url;

            // keyinfo
            var keyInfo = new KeyInfo();

            keyInfo.Id = string.Format("KI-{0}", _random.Next());
            var str = new SecurityTokenReference();

            str.Reference = string.Format("#{0}", binarySecurityTokenId);
            str.ValueType = Namespaces.WS_SEC_TOKENPROFILE;

            keyInfo.AddClause(str);
            signedXml.KeyInfo = keyInfo;

            // compose signature
            signedXml.AddReference(reference);
            signedXml.ComputeSignature();

            // import the signature node into the document
            var signatureXml = signedXml.GetXml();

            var headerNode = xmlrequest
                             .DocumentElement.ChildNodes
                             .Cast <XmlNode>()
                             .FirstOrDefault(n => n.LocalName == "Header");
            var headerSecurityNode = headerNode
                                     .ChildNodes
                                     .Cast <XmlNode>()
                                     .FirstOrDefault(n => n.LocalName == "Security");
            var binarySecurityTokenNode = headerSecurityNode.FirstChild;

            // insert it just after BSE
            var importedSignatureXml = xmlrequest.ImportNode(signatureXml, true);

            headerSecurityNode.InsertAfter(importedSignatureXml, binarySecurityTokenNode);

            return(xmlrequest.OuterXml);
        }