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); }
/// <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); }
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))); }
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); }
/// <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); }
/// <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); }
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); }