<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <id>http://www.devarch.net/</id>
  <title>.Net Developer and Architect</title>
  <updated>2011-11-14T14:59:57+00:00</updated>
  <link href="http://www.devarch.net/" />
  
  <subtitle>Desarrollo y arquitectura .Net, BizTalk, y otros artículos tecnológicos.</subtitle>
  <author>
    <name>writer@anonymous.com</name>
  </author>
  <generator uri="http://dotnetblogengine.net/" version="1.0.0.0">BlogEngine.Net Syndication Generator</generator>
  <blogChannel:blogRoll>http://www.devarch.net/opml.axd</blogChannel:blogRoll>
  <blogChannel:blink>http://www.devarch.net/syndication.axd</blogChannel:blink>
  <dc:creator>writer@anonymous.com</dc:creator>
  <dc:description>Desarrollo y arquitectura .Net, BizTalk, y otros artículos tecnológicos.</dc:description>
  <dc:language>es-ES</dc:language>
  <dc:title>.Net Developer and Architect</dc:title>
  <geo:lat>0.000000</geo:lat>
  <geo:long>0.000000</geo:long>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/devarchnet" /><feedburner:info uri="devarchnet" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <id>http://www.devarch.net/post/2011/11/14/Realizar-firmas-XAdES-desde-Net-5.aspx</id>
    <title>Realizar firmas XAdES desde .Net (5)</title>
    <updated>2011-11-14T14:56:00+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=d4b93aed-7cac-472e-8478-463b18e83c6d" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/FUyRC8v0cv0/Realizar-firmas-XAdES-desde-Net-5.aspx" />
    <author>
      <name>Admin</name>
    </author>
    <summary type="html">&lt;p&gt;Lamento los problemas que hab&amp;eacute;is podido tener los lectores del blog con el ejemplo del &amp;uacute;ltimo art&amp;iacute;culo de XAdES. He arreglado el enlace para que pod&amp;aacute;is acceder al ejemplo. Pod&amp;eacute;is acceder al adjunto en el mismo art&amp;iacute;culo, en&amp;nbsp;&lt;a href="http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-4.aspx"&gt;http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-4.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/FUyRC8v0cv0" height="1" width="1"/&gt;</summary>
    <published>2011-11-14T14:56:00+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2011/11/14/Realizar-firmas-XAdES-desde-Net-5.aspx#comment" />
    <dc:publisher>Admin</dc:publisher>
    <dc:description>He arreglado el enlace para que podáis acceder al ejemplo.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=d4b93aed-7cac-472e-8478-463b18e83c6d</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=d4b93aed-7cac-472e-8478-463b18e83c6d</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2011/11/14/Realizar-firmas-XAdES-desde-Net-5.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=d4b93aed-7cac-472e-8478-463b18e83c6d</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2011/11/14/Realizar-firmas-XAdES-desde-Net-5.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-4.aspx</id>
    <title>Realizar firmas XAdES desde .Net (4)</title>
    <updated>2011-03-31T14:01:00+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=ee6a6ec3-1364-4a11-beda-abb0794ca442" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/rUu36gqV3_A/realizar-firmas-xades-desde-net-4.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;En el art&amp;iacute;culo anterior hemos codificado un m&amp;eacute;todo que permite realizar la firma XAdES. Sin embargo, al tratar de ejecutar su prueba unitaria, observamos que el m&amp;eacute;todo de firma nos devuelve una &lt;em&gt;CryptographicException: Malformed reference element. &lt;/em&gt;Esta excepci&amp;oacute;n es levantada por el objeto SignedXml al no conseguir encontrar el nodo con atributo Id y el valor especificado en las diferentes referencias. Vamos a ver c&amp;oacute;mo solucionar este problema y por fin, conseguir realizar la firma completa.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;En concreto, las referencias que nos est&amp;aacute;n dando problemas son las referencias al nodo con Id &amp;ldquo;KeyInfo&amp;rdquo; (la clave p&amp;uacute;blica de firma) y la referencia al nodo &amp;ldquo;XADES-Properties&amp;rdquo; (el objeto XAdES). Para poder adaptar el objeto SignedXml y lograr realizar estas referencias, deberemos crearnos un objeto que herede de SignedXml. En nuestro ejemplo lo llamaremos XAdESSignedXml. En este objeto, sobrescribiremos el m&amp;eacute;todo &lt;em&gt;GetIdElement&lt;/em&gt;, que se encarga de buscar los nodos a los que se realizan las referencias, encarg&amp;aacute;ndonos en este objeto de buscar manualmente en el Xml los nodos que nos hacen falta:&lt;/p&gt;
&lt;pre class="brush: c-sharp"&gt;sealed class XAdESSignedXml: SignedXml
{
    private readonly List&amp;lt;DataObject&amp;gt; _dataObjects = new List&amp;lt;DataObject&amp;gt;();

    public const string XadesSignaturePropertiesNamespace = "http://uri.etsi.org/01903/v1.2.2#SignedProperties";

    public XAdESSignedXml(XmlDocument document) : base(document) { }

    public override XmlElement GetIdElement(XmlDocument doc, string id)
    {
        if (String.IsNullOrEmpty(id)) return null;

        XmlElement xmlElement = base.GetIdElement(doc, id);
        if (xmlElement != null) return xmlElement;

        //Search XAdES node
        foreach (DataObject dataObject in _dataObjects)
        {
            XmlElement nodeWithSameId = findNodeWithAttributeValueIn(dataObject.Data, "Id", id);
            if (nodeWithSameId != null) 
                return nodeWithSameId;
        }

        //Search the KeyInfo node
        if (KeyInfo != null)
        {
            XmlElement nodeWithSameId = findNodeWithAttributeValueIn(KeyInfo.GetXml().SelectNodes("."), "Id", id);
            if (nodeWithSameId != null) 
                return nodeWithSameId;
        }
        return null;
    }
    [... m&amp;eacute;todos auxiliares...}
}&lt;/pre&gt;
&lt;p&gt;Sobrescribiendo este m&amp;eacute;todo, logramos poder buscar las referencias no solamente en el Xml que se va a firmar, sino tambi&amp;eacute;n en los objetos que van a formar parte del Xml de firma (dentro del nodo Signature). De esta manera, primero se busca el nodo referenciado mediante la clase SignedXml, y si no se encuentra se pasa a nuestro c&amp;oacute;digo propio. Primero se busca, en la colecci&amp;oacute;n de objetos _dataObjects el objeto correspondiente al objeto XAdES. Si se encuentra, se devuelve, y si no, se busca el objeto KeyInfo.&lt;/p&gt;
&lt;p&gt;De esta manera, SignedXml es capaz de calcular del DigestValue para cada referencia, para posteriormente calcular la firma.&lt;/p&gt;
&lt;p&gt;Pero para poder usarlo, tendremos que modificar el m&amp;eacute;todo de firma, para emplear nuestro objeto en lugar del SignedXml. Para ello, en el m&amp;eacute;todo de firma, sustituiremos:&lt;/p&gt;
&lt;pre class="brush: c-sharp; toolbar: false"&gt;SignedXml signer = new SignedXml(toSign);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Por lo siguiente:&lt;/p&gt;
&lt;pre class="brush: c-sharp; toolbar: false"&gt;XAdESSignedXml signer = new XAdESSignedXml(toSign);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ejecutaremos nuestra prueba unitaria. Si hemos hecho todo bien, obtendremos una prueba correcta, obteniendo el siguiente resultado:&lt;/p&gt;
&lt;pre class="brush: xhtml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;documento id="documento"&amp;gt;
	&amp;lt;titulo id="titulo"&amp;gt;Documento de pruebas&amp;lt;/titulo&amp;gt;
	&amp;lt;descripcion id="descripcion"&amp;gt;Documento destinado a realizar pruebas de firma&amp;lt;/descripcion&amp;gt;
	&amp;lt;Signature Id="SignatureUsuario" xmlns="http://www.w3.org/2000/09/xmldsig#"&amp;gt;
		&amp;lt;SignedInfo&amp;gt;
			&amp;lt;CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&amp;gt;
			&amp;lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&amp;gt;
			&amp;lt;Reference URI=""&amp;gt;
				&amp;lt;Transforms&amp;gt;
					&amp;lt;Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"&amp;gt;
						&amp;lt;XPath xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&amp;gt;not(ancestor-or-self::ds:Signature)&amp;lt;/XPath&amp;gt;
					&amp;lt;/Transform&amp;gt;
					&amp;lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&amp;gt;
				&amp;lt;/Transforms&amp;gt;
				&amp;lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&amp;gt;
				&amp;lt;DigestValue&amp;gt;EhaeWtAs6PEFAMHhHlJDT509kNE=&amp;lt;/DigestValue&amp;gt;
			&amp;lt;/Reference&amp;gt;
			&amp;lt;Reference Id="SignatureUsuario-XADES-Properties-Ref" URI="#XADES-Properties" Type="http://uri.etsi.org/01903/v1.2.2#SignedProperties"&amp;gt;
				&amp;lt;Transforms&amp;gt;
					&amp;lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&amp;gt;
				&amp;lt;/Transforms&amp;gt;
				&amp;lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&amp;gt;
				&amp;lt;DigestValue&amp;gt;lBINUyb1H5+S/ufalq/oBHd3Z0E=&amp;lt;/DigestValue&amp;gt;
			&amp;lt;/Reference&amp;gt;
			&amp;lt;Reference Id="SignatureUsuario-KeyInfo-Ref" URI="#KeyInfo"&amp;gt;
				&amp;lt;Transforms&amp;gt;
					&amp;lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&amp;gt;
				&amp;lt;/Transforms&amp;gt;
				&amp;lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&amp;gt;
				&amp;lt;DigestValue&amp;gt;VFx0acqOZinC2c+Dv07GiRx9+LE=&amp;lt;/DigestValue&amp;gt;
			&amp;lt;/Reference&amp;gt;
		&amp;lt;/SignedInfo&amp;gt;
		&amp;lt;SignatureValue&amp;gt;EukSphW1wBeWo4X0TwVNj8sPFUafQDQT6aGlKeuRYFSRH83NJU+v4Rk6EKa8VlOmx8UwIBEY/I2B+6T/IF6UYCWvNhuX+W6r7GdlNldBE50Vjo8XLX36L1HiyTXuh1hNc2qOpvlFuR6h4xlfHD8XqQ6XXpu6ScCLdMqJjAVb/Co=&amp;lt;/SignatureValue&amp;gt;
		&amp;lt;KeyInfo Id="KeyInfo"&amp;gt;
			&amp;lt;X509Data&amp;gt;
				&amp;lt;X509SubjectName&amp;gt;CN=TestCertificate, OU=Testing, OU=local&amp;lt;/X509SubjectName&amp;gt;
				&amp;lt;X509Certificate&amp;gt;MIIB2TCCAYegAwIBAgIQZfvBf6QChY9MxURe7gvy3jAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTExMDMyOTA5MTQyNFoXDTM5MTIzMTIzNTk1OVowPDEOMAwGA1UECxMFbG9jYWwxEDAOBgNVBAsTB1Rlc3RpbmcxGDAWBgNVBAMTD1Rlc3RDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyCpLpQjTmY1rymBnrBMj48gVWwseQdqLj47baOX5/dSRNMi8DdTBWV9eHryi4l1ivoG65AD8GHWcMoqiEQ2ZyjhHD/yR2CX5sd6Dm26e+caZIZ7mqm+wD4brR6NpNcJtIPBR2HYiHLPctCHffFmr16hOI6DlYJ5UoBm5TElw7HkCAwEAAaNLMEkwRwYDVR0BBEAwPoAQEuQJLQYdHU8AjWEh3BZkY6EYMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5ghAGN2wAqgBkihHPuNSqXDX0MAkGBSsOAwIdBQADQQBTpAn4LfxKfCosDnDQDu6A4GhG8QWKjo9faHkS2xqajiYAiWf76oCIqj1hudcS94xfCp3gaRtajaUaB/ceVa5s&amp;lt;/X509Certificate&amp;gt;
			&amp;lt;/X509Data&amp;gt;
		&amp;lt;/KeyInfo&amp;gt;
		&amp;lt;Object Id="XADES"&amp;gt;
			&amp;lt;etsi:QualifyingProperties Target="SignatureUsuario" xmlns:etsi="http://uri.etsi.org/01903/v1.3.2#"&amp;gt;
				&amp;lt;etsi:SignedProperties Id="XADES-Properties"&amp;gt;
					&amp;lt;etsi:SignedSignatureProperties&amp;gt;
						&amp;lt;etsi:SigningTime&amp;gt;2011-03-31T10:56:13Z&amp;lt;/etsi:SigningTime&amp;gt;
						&amp;lt;etsi:SigningCertificate&amp;gt;
							&amp;lt;etsi:Cert&amp;gt;
								&amp;lt;etsi:CertDigest&amp;gt;
									&amp;lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" /&amp;gt;
									&amp;lt;ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&amp;gt;kRV4rHiKIE3iM5ZKx5DBNsDbrd8=&amp;lt;/ds:DigestValue&amp;gt;
								&amp;lt;/etsi:CertDigest&amp;gt;
								&amp;lt;etsi:IssuerSerial&amp;gt;
									&amp;lt;ds:X509IssuerName xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&amp;gt;CN=Root Agency&amp;lt;/ds:X509IssuerName&amp;gt;
									&amp;lt;ds:X509SerialNumber xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&amp;gt;65FBC17FA402858F4CC5445EEE0BF2DE&amp;lt;/ds:X509SerialNumber&amp;gt;
								&amp;lt;/etsi:IssuerSerial&amp;gt;
							&amp;lt;/etsi:Cert&amp;gt;
						&amp;lt;/etsi:SigningCertificate&amp;gt;
					&amp;lt;/etsi:SignedSignatureProperties&amp;gt;
				&amp;lt;/etsi:SignedProperties&amp;gt;
			&amp;lt;/etsi:QualifyingProperties&amp;gt;
		&amp;lt;/Object&amp;gt;
	&amp;lt;/Signature&amp;gt;
&amp;lt;/documento&amp;gt;&lt;/pre&gt;
&lt;div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:ae02550c-b4f4-4f78-90fa-aa81004d7301" class="wlWriterEditableSmartContent" style="display: inline; float: none; margin: 0px; padding: 0px;"&gt;
&lt;p&gt;Descarga el proyecto de &lt;a href="http://www.devarch.net/file.axd?file=TestProject1_5.zip"&gt;ejemplo de firma&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;En esta serie de cuatro art&amp;iacute;culos hemos podido ver, de una manera eminentemente pr&amp;aacute;ctica, de que manera realizar una firma mediante el est&amp;aacute;ndar XAdES-BES. Hemos podido ver que la soluci&amp;oacute;n al problema es relativamente sencilla, con alg&amp;uacute;n que otro problema que tiene f&amp;aacute;cil soluci&amp;oacute;n. Espero que sea de ayuda para la comunidad.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/rUu36gqV3_A" height="1" width="1"/&gt;</summary>
    <published>2011-03-31T14:01:00+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-4.aspx#comment" />
    <category term="Seguridad" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>En el artículo anterior hemos codificado un método que permite realizar la firma XAdES. Sin embargo, al tratar de ejecutar su prueba unitaria, observamos que el método de firma nos devuelve una CryptographicException: Malformed reference element. Esta excepción es levantada por el objeto SignedXml al no conseguir encontrar el nodo con atributo Id y el valor especificado en las diferentes referencias. Vamos a ver cómo solucionar este problema y por fin, conseguir realizar la firma completa.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=ee6a6ec3-1364-4a11-beda-abb0794ca442</pingback:target>
    <slash:comments>1</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=ee6a6ec3-1364-4a11-beda-abb0794ca442</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-4.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=ee6a6ec3-1364-4a11-beda-abb0794ca442</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-4.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-3.aspx</id>
    <title>Realizar firmas XAdES desde .Net (3)</title>
    <updated>2011-03-31T09:56:04+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=f6fa996e-7682-45b7-90c7-130698c09648" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/YRRF2-opNmE/realizar-firmas-xades-desde-net-3.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;En los anteriores artículos de esta serie pudimos ver la &lt;a href="http://devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx" target="_blank"&gt;estructura de un XML fimado mediante XAdES&lt;/a&gt;, y el modo de &lt;a href="http://devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx" target="_blank"&gt;validar una firma y generar un certificado de pruebas&lt;/a&gt;. Por fin, en este tercer artículo de la serie, vamos a firmar documentos. Primero realizaremos una firma XmlDSig y posteriormente ampliaremos esta firma para obtener una firma XAdES correcta.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Para realizar una firma compatible con XmlDSig no tenemos más que emplear la clase SignedXml de .Net, y proporcionarle el Xml que queremos firmar, la clave privada con la que firmaremos y una referencia al nodo que queremos firmar. Haremos una prueba unitaria que nos valide esta operativa:&lt;/p&gt;  &lt;pre class="brush: c-sharp"&gt;[TestMethod]
public void TestXmlDSigSignature()
{
    Signature sig = new Signature();
    X509Certificate2 cert = sig.GetCertificateFromStore(StoreLocation.CurrentUser, StoreName.My,
        &amp;quot;91 15 78 ac 78 8a 20 4d e2 33 96 4a c7 90 c1 36 c0 db ad df&amp;quot;);

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot; encoding=\&amp;quot;UTF-8\&amp;quot;?&amp;gt;&amp;lt;documento id=\&amp;quot;documento\&amp;quot;&amp;gt;&amp;lt;titulo id=\&amp;quot;titulo\&amp;quot;&amp;gt;Documento de pruebas&amp;lt;/titulo&amp;gt;&amp;lt;descripcion id=\&amp;quot;descripcion\&amp;quot;&amp;gt;Documento destinado a realizar pruebas de firma&amp;lt;/descripcion&amp;gt;&amp;lt;/documento&amp;gt;&amp;quot;);

    XmlDocument signed = sig.SignDocument(cert, doc);
    sig.Validate(signed);            
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Vamos a realizar una firma &lt;em&gt;Enveloped. &lt;/em&gt;Para ello implementamos el siguiente método:&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;public XmlDocument SignDocument(X509Certificate2 cert, XmlDocument doc)
{
    SignedXml signer = new SignedXml(doc);

    //Set the key to sign
    signer.SigningKey = cert.PrivateKey;
    signer.KeyInfo = getKeyInfo(signer, cert);

    //Set nodes idetifiers
    signer.Signature.Id = &amp;quot;SignatureUsuario&amp;quot;;
    signer.KeyInfo.Id = &amp;quot;KeyInfo&amp;quot;;

    //Set canonicalization method for signature
    signer.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

    //Set the reference to sign
    signer.AddReference(setCertificationReference(signer));

    //Compute signature
    signer.ComputeSignature();

    //Construct the Signed Xml and return it
    doc.DocumentElement.AppendChild(doc.ImportNode(signer.GetXml(), true));
    return doc;
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;El método es bastante sencillo de seguir con los comentarios, con lo que no me extenderé en describir cada paso realizado. Tenemos que tener en cuenta que queremos incluir en la firma todo el XML excluyendo el nodo Signature de la firma, de modo que creamos una referencia al contenido del XML mediante una sentencia Xpath. Para ello, vamos a crear el método que nos realizará esta referencia:&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;private Reference setCertificationReference(SignedXml signer)
{
    Reference reference = new Reference(String.Empty);

    // create the XML that represents the transform
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(&amp;quot;&amp;lt;XPath xmlns:ds=\&amp;quot;http://www.w3.org/2000/09/xmldsig#\&amp;quot;&amp;gt;not(ancestor-or-self::ds:Signature)&amp;lt;/XPath&amp;gt;&amp;quot;);

    XmlDsigXPathTransform xform = new XmlDsigXPathTransform();
    xform.LoadInnerXml(doc.DocumentElement.SelectNodes(&amp;quot;.&amp;quot;));

    reference.TransformChain = new TransformChain();
    reference.TransformChain.Add(xform);
    reference.TransformChain.Add(new XmlDsigExcC14NTransform());

    return reference;
}

private KeyInfo getKeyInfo(SignedXml signer, X509Certificate2 cert)
{
    KeyInfo keyInfo = new KeyInfo();
    KeyInfoX509Data keyInfoClause = new KeyInfoX509Data(cert);
    keyInfoClause.AddSubjectName(cert.SubjectName.Name);
    keyInfo.AddClause(keyInfoClause);
    return keyInfo;
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Ejecutamos la prueba unitaria y comprobaremos que la firma ser ealiza y se valida correctamente. Este es el XML resultante (tras formatearlo con un editor de texto):&lt;/p&gt;

&lt;pre class="brush: xhtml"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;documento id=&amp;quot;documento&amp;quot;&amp;gt;
	&amp;lt;titulo id=&amp;quot;titulo&amp;quot;&amp;gt;Documento de pruebas&amp;lt;/titulo&amp;gt;
	&amp;lt;descripcion id=&amp;quot;descripcion&amp;quot;&amp;gt;Documento destinado a realizar pruebas de firma&amp;lt;/descripcion&amp;gt;
	&amp;lt;Signature Id=&amp;quot;SignatureUsuario&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;
		&amp;lt;SignedInfo&amp;gt;
			&amp;lt;CanonicalizationMethod Algorithm=&amp;quot;http://www.w3.org/2001/10/xml-exc-c14n#&amp;quot; /&amp;gt;
			&amp;lt;SignatureMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#rsa-sha1&amp;quot; /&amp;gt;
			&amp;lt;Reference URI=&amp;quot;&amp;quot;&amp;gt;
				&amp;lt;Transforms&amp;gt;
					&amp;lt;Transform Algorithm=&amp;quot;http://www.w3.org/TR/1999/REC-xpath-19991116&amp;quot;&amp;gt;
						&amp;lt;XPath xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;not(ancestor-or-self::ds:Signature)&amp;lt;/XPath&amp;gt;
					&amp;lt;/Transform&amp;gt;
					&amp;lt;Transform Algorithm=&amp;quot;http://www.w3.org/2001/10/xml-exc-c14n#&amp;quot; /&amp;gt;
				&amp;lt;/Transforms&amp;gt;
				&amp;lt;DigestMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#sha1&amp;quot; /&amp;gt;
				&amp;lt;DigestValue&amp;gt;EhaeWtAs6PEFAMHhHlJDT509kNE=&amp;lt;/DigestValue&amp;gt;
			&amp;lt;/Reference&amp;gt;
		&amp;lt;/SignedInfo&amp;gt;
		&amp;lt;SignatureValue&amp;gt;vN+qTDrnITHaRy94qCJhur1/fZHNJPXh5eT6bkEFh6EQRigI3ZFywO0fllnegX3CBoRhLFiaGbwB2upbpRLMEovzKTjZ4xB/DXmym5KZSPcyO7Fh25iq4L3VIETkGf4zV4cef7ZtDTN2lvKdoKnPkNFNQXXYcxS7WxIIvLKSg2c=&amp;lt;/SignatureValue&amp;gt;
		&amp;lt;KeyInfo Id=&amp;quot;KeyInfo&amp;quot;&amp;gt;
			&amp;lt;X509Data&amp;gt;
				&amp;lt;X509SubjectName&amp;gt;CN=TestCertificate, OU=Testing, OU=local&amp;lt;/X509SubjectName&amp;gt;
				&amp;lt;X509Certificate&amp;gt;MIIB2TCCAYegAwIBAgIQZfvBf6QChY9MxURe7gvy3jAJBgUrDgMCHQUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTExMDMyOTA5MTQyNFoXDTM5MTIzMTIzNTk1OVowPDEOMAwGA1UECxMFbG9jYWwxEDAOBgNVBAsTB1Rlc3RpbmcxGDAWBgNVBAMTD1Rlc3RDZXJ0aWZpY2F0ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyCpLpQjTmY1rymBnrBMj48gVWwseQdqLj47baOX5/dSRNMi8DdTBWV9eHryi4l1ivoG65AD8GHWcMoqiEQ2ZyjhHD/yR2CX5sd6Dm26e+caZIZ7mqm+wD4brR6NpNcJtIPBR2HYiHLPctCHffFmr16hOI6DlYJ5UoBm5TElw7HkCAwEAAaNLMEkwRwYDVR0BBEAwPoAQEuQJLQYdHU8AjWEh3BZkY6EYMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5ghAGN2wAqgBkihHPuNSqXDX0MAkGBSsOAwIdBQADQQBTpAn4LfxKfCosDnDQDu6A4GhG8QWKjo9faHkS2xqajiYAiWf76oCIqj1hudcS94xfCp3gaRtajaUaB/ceVa5s&amp;lt;/X509Certificate&amp;gt;
			&amp;lt;/X509Data&amp;gt;
		&amp;lt;/KeyInfo&amp;gt;
	&amp;lt;/Signature&amp;gt;
&amp;lt;/documento&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Podemos comprobar entonces la sencillez de .Net para realizar una firma en .Net, ya que el objeto SignedXml nos construye para nosotros todo el XML de firma, teniendo solamente que incrustar manualmente el nodo Signature dentro del Xml.&lt;/p&gt;

&lt;p&gt;Como vimos en el primer artículo de la serie, XAdES es un protocolo que se basa en XmlDsig, por lo que simplemente tendremos que añadir las partes que necesitamos para cumplimentar el estándar. En concreto, necesitamos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Añadir un objeto en el cual se describa el certificado y su emisor. &lt;/li&gt;

  &lt;li&gt;Añadir referencias a este objeto recién creado, así como al nodo KeyInfo. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Empezamos como antes, realizando una prueba unitaria que nos permita validar nuestro desarrollo:&lt;/p&gt;

&lt;pre class="brush: c-sharp"&gt;[TestMethod]
public void TestXAdESSignature()
{
    Signature sig = new Signature();
    X509Certificate2 cert = sig.GetCertificateFromStore(StoreLocation.CurrentUser, StoreName.My,
        &amp;quot;91 15 78 ac 78 8a 20 4d e2 33 96 4a c7 90 c1 36 c0 db ad df&amp;quot;);

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(&amp;quot;&amp;lt;?xml version=\&amp;quot;1.0\&amp;quot; encoding=\&amp;quot;UTF-8\&amp;quot;?&amp;gt;&amp;lt;documento id=\&amp;quot;documento\&amp;quot;&amp;gt;&amp;lt;titulo id=\&amp;quot;titulo\&amp;quot;&amp;gt;Documento de pruebas&amp;lt;/titulo&amp;gt;&amp;lt;descripcion id=\&amp;quot;descripcion\&amp;quot;&amp;gt;Documento destinado a realizar pruebas de firma&amp;lt;/descripcion&amp;gt;&amp;lt;/documento&amp;gt;&amp;quot;);

    XmlDocument signed = sig.SignDocumentXAdES(cert, doc);
    sig.Validate(signed);
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Y desarrollamos el método de firma XAdES, que como se puede observar, es muy similar al que ya desarrollamos antes:&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;private static XmlDocument SignDocument(X509Certificate2 cert, XmlDocument toSign)
{
    SignedXml signer = new SignedXml(toSign);

    //Set the key to sign
    signer.SigningKey = cert.PrivateKey;
    signer.KeyInfo = getKeyInfo(signer, cert);

    //Set nodes idetifiers
    signer.Signature.Id = &amp;quot;SignatureUsuario&amp;quot;;
    signer.KeyInfo.Id = &amp;quot;KeyInfo&amp;quot;;

    //Set canonicalization method for signature
    signer.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

    //Add XAdES node
    addXAdESNodes(signer, toSign, cert);

    //Set the references to sign
    signer.AddReference(setCertificationReference(signer));
    signer.AddReference(setXAdESReference(signer));
    signer.AddReference(setKeyInfoReference(signer));

    //Compute signature
    signer.ComputeSignature();

    //Construct the Signed Xml and return it 
    toSign.DocumentElement.AppendChild(toSign.ImportNode(signer.GetXml(), true));
    return toSign;
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;La principal peculiaridad es que hay que construir el objeto XAdES a mano, esto es, construir el nodo XML mediante DOM. De esto se encarga el método &lt;em&gt;addXAdESNode&lt;/em&gt; (cuyas “tripas”, por su extensión, no reflejaré aquí por brevedad, sólo la parte importante del mismo):&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;DataObject dataObject = new DataObject();
XmlElement result = document.CreateElement(&amp;quot;etsi&amp;quot;, &amp;quot;QualifyingProperties&amp;quot;, &amp;quot;http://uri.etsi.org/01903/v1.3.2#&amp;quot;);

//You must add all the nodes into &lt;em&gt;result&lt;/em&gt; XmlElement with DOM 
//Set the attributes and add to SignedXml class 
result.SetAttribute(&amp;quot;Target&amp;quot;, signedXml.Signature.Id); 
dataObject.Data = result.SelectNodes(&amp;quot;.&amp;quot;); 
dataObject.Id = &amp;quot;XADES&amp;quot;; signedXml.AddObject(dataObject); &lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;En este trozo de código estamos creando un objeto dentro del cual introduciremos el nodo XAdES construido a mano. El XML resultante (generado con los métodos auxiliares omitidos) queda como sigue:&lt;/p&gt;

&lt;pre class="brush: xhtml"&gt;&amp;lt;Object Id=&amp;quot;XADES&amp;quot;&amp;gt;
	&amp;lt;etsi:QualifyingProperties Target=&amp;quot;SignatureUsuario&amp;quot; xmlns:etsi=&amp;quot;http://uri.etsi.org/01903/v1.3.2#&amp;quot;&amp;gt;
		&amp;lt;etsi:SignedProperties Id=&amp;quot;XADES-Properties&amp;quot;&amp;gt;
			&amp;lt;etsi:SignedSignatureProperties&amp;gt;
				&amp;lt;etsi:SigningTime&amp;gt;2011-03-31T10:56:13Z&amp;lt;/etsi:SigningTime&amp;gt;
				&amp;lt;etsi:SigningCertificate&amp;gt;
					&amp;lt;etsi:Cert&amp;gt;
						&amp;lt;etsi:CertDigest&amp;gt;
							&amp;lt;ds:DigestMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#sha1&amp;quot; xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot; /&amp;gt;
							&amp;lt;ds:DigestValue xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;kRV4rHiKIE3iM5ZKx5DBNsDbrd8=&amp;lt;/ds:DigestValue&amp;gt;
						&amp;lt;/etsi:CertDigest&amp;gt;
						&amp;lt;etsi:IssuerSerial&amp;gt;
							&amp;lt;ds:X509IssuerName xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;CN=Root Agency&amp;lt;/ds:X509IssuerName&amp;gt;
							&amp;lt;ds:X509SerialNumber xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;65FBC17FA402858F4CC5445EEE0BF2DE&amp;lt;/ds:X509SerialNumber&amp;gt;
						&amp;lt;/etsi:IssuerSerial&amp;gt;
					&amp;lt;/etsi:Cert&amp;gt;
				&amp;lt;/etsi:SigningCertificate&amp;gt;
			&amp;lt;/etsi:SignedSignatureProperties&amp;gt;
		&amp;lt;/etsi:SignedProperties&amp;gt;
	&amp;lt;/etsi:QualifyingProperties&amp;gt;
&amp;lt;/Object&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;No te preocupes, los métodos auxiliares podrás verlos en el adjunto del último artículo de la serie. Simplemente están omitidos por mejorar la legibilidad del mismo. Lo importante es entender que este XML hay que montarlo manualmente.&lt;/p&gt;

&lt;p&gt;Posteriormente, necesitaremos implementar los dos métodos que crean las referencias a la clave de firma y al objeto XADES:&lt;/p&gt;

&lt;pre class="brush: c-sharp; toolbar: false"&gt;private static Reference setXAdESReference(SignedXml signer)
{
    Reference reference = new Reference(&amp;quot;#XADES-Properties&amp;quot;);
    reference.Id = &amp;quot;SignatureUsuario-XADES-Properties-Ref&amp;quot;;
    reference.Type = &amp;quot;http://uri.etsi.org/01903/v1.2.2#SignedProperties&amp;quot;;
    reference.AddTransform(new XmlDsigExcC14NTransform());
    return reference;
}

private static Reference setKeyInfoReference(SignedXml signedXml)
{
    Reference reference = new Reference(&amp;quot;#&amp;quot; + signedXml.KeyInfo.Id);
    reference.AddTransform(new XmlDsigExcC14NTransform());
    reference.Id = &amp;quot;SignatureUsuario-KeyInfo-Ref&amp;quot;;
    return reference;
}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Una vez que terminamos de implementar estos dos métodos, podremos ejecutar la prueba unitaria, puesto que prácticamente tenemos acabado el método de firma. Sin embargo, podemos comprobar que la prueba unitaria no funciona, debido a que obtenemos una excepcion &lt;em&gt;CryptographicException: Malformed reference element&lt;/em&gt;. Esta excepción indica que los nodos que estamos referenciando en los métodos &lt;em&gt;setXAdESReference&lt;/em&gt; y &lt;em&gt;setKeyinforeference&lt;/em&gt; no se encuentran por el objeto SignedXml.&lt;/p&gt;

&lt;p&gt;En el próximo artículo veremos como solucionar este problema. Sin embargo, ya hemos avanzado en la solución de la realización de la firma en gran medida.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/YRRF2-opNmE" height="1" width="1"/&gt;</summary>
    <published>2011-03-31T09:56:04+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-3.aspx#comment" />
    <category term="Seguridad" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>En los anteriores artículos de esta serie pudimos ver la estructura de un XML fimado mediante XAdES, y el modo de validar una firma y generar un certificado de pruebas. Por fin, en este tercer artículo de la serie, vamos a firmar documentos. Primero realizaremos una firma XmlDSig y posteriormente ampliaremos esta firma para obtener una firma XAdES correcta.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=f6fa996e-7682-45b7-90c7-130698c09648</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=f6fa996e-7682-45b7-90c7-130698c09648</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-3.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=f6fa996e-7682-45b7-90c7-130698c09648</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2011/03/31/realizar-firmas-xades-desde-net-3.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2011/03/28/realizar-firmas-xades-desde-net-2.aspx</id>
    <title>Realizar firmas XAdES desde .Net (2)</title>
    <updated>2011-03-28T15:53:00+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=e00eb190-02f3-4303-a2b5-238806da188e" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/5b9cmCMuXpQ/realizar-firmas-xades-desde-net-2.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;En el &lt;a href="http://devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx" target="_blank"&gt;anterior art&amp;iacute;culo&lt;/a&gt; he introducido el concepto de la firma digital mediante los est&amp;aacute;ndares XAdES y XML-DSig. En este art&amp;iacute;culo vamos a ver c&amp;oacute;mo validar una firma mediante XML-DSig, empleando las clases nativas facilitadas en .Net, en modo &lt;em&gt;Enveloped, &lt;/em&gt;as&amp;iacute; como vamos a generar un certificado X509 para poder realizar la firma y ver c&amp;oacute;mo accedemos al mismo.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Para realizar esta firma vamos a utilizar un certificado de usuario. Un certificado de usuario v&amp;aacute;lido puede ser cualquiera de los expedidos por entidades certificadoras como por ejemplo la F&amp;aacute;brica Nacional de Moneda y Timbre. Para hacer este peque&amp;ntilde;o ejemplo, emplearemos un certificado de pruebas generado en .Net, tomando como referencia las instrucciones que indico en &lt;a href="http://devarch.net/post/2010/01/29/Obtener-un-certificado-del-almacen-de-certificados.aspx" target="_blank"&gt;este art&amp;iacute;culo&lt;/a&gt;. Del mismo art&amp;iacute;culo podemos tomar el m&amp;eacute;todo para recuperar un objeto X509Certificate2 con el contenido del certificado digital.&lt;/p&gt;
&lt;p&gt;Primero vamos a escribir un m&amp;eacute;todo que nos permita realizar una validaci&amp;oacute;n de una firma empleando el objeto SignedXml. Este m&amp;eacute;todo podr&amp;aacute; validar cualquier XML con firma &lt;em&gt;Enveloped&lt;/em&gt;, ya que la clave p&amp;uacute;blica con la que est&amp;aacute; firmado el XML deber&amp;iacute;a estar presente en el nodo &lt;em&gt;Signature&lt;/em&gt; del XML.&lt;/p&gt;
&lt;pre class="brush: c-sharp; toolbar: false"&gt;public void Validate(XmlDocument document)
{
     XmlNamespaceManager nsMgr = new XmlNamespaceManager(document.NameTable);
     nsMgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");

     //Cargamos el XML en el objeto SignedXML
     SignedXml verifier = new SignedXml(document);      

     //Obtenemos el nodo de la firma y se lo porporcionamos al objeto SignedXml para poder realizar la validaci&amp;oacute;n
     XmlElement signatureElement = document.DocumentElement.SelectSingleNode("//ds:Signature", nsMgr) as XmlElement;
     verifier.LoadXml(signatureElement);
     
     //Realizamos la comprobaci&amp;oacute;n
     if (!verifier.CheckSignature())
         throw new InvalidSignatureException();
}&lt;/pre&gt;
&lt;p&gt;Generaremos el certificado de pruebas con la siguiente sentencia, para crearnos un certificado en la carpeta &lt;em&gt;Personal&lt;/em&gt; del almac&amp;eacute;n de certificados del usuario que ha iniciado la sesi&amp;oacute;n:&lt;/p&gt;
&lt;pre class="brush: c-sharp; toolbar: false"&gt;makecert -sr CurrentUser -ss My -a sha1 -n CN=TestCertificate,OU=Testing,OU=local -sky exchange &amp;ndash;pe&lt;/pre&gt;
&lt;p&gt;Lo podremos ver si accedemos a Internet Explorer, abrimos las &lt;em&gt;Opciones de Internet&lt;/em&gt;, vamos a la pesta&amp;ntilde;a &lt;em&gt;Contenido&lt;/em&gt; y pulsamos el bot&amp;oacute;n &lt;em&gt;Certificados&lt;/em&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devarch.net/image.axd?picture=Certificados1.png" target="_blank"&gt;&lt;img style="display: inline; border-width: 0px;" title="Certificado" src="http://devarch.net/image.axd?picture=Certificados1_thumb.png" border="0" alt="Certificado" width="244" height="223" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tengamos en cuenta que este certificado s&amp;oacute;lo nos va a valer para hacer pruebas en la m&amp;aacute;quina local, si necesitamos hacer pruebas en varias m&amp;aacute;quinas tendremos que o bien instalar este mismo certificado en ellas, o bien instalar un certificado v&amp;aacute;lido.&lt;/p&gt;
&lt;p&gt;Para poder emplear este certificado, modificamos el m&amp;eacute;todo para obtener el certificado para que realice la carga del mismo desde el almac&amp;eacute;n de certificados del usuario:&lt;/p&gt;
&lt;pre class="brush: c-sharp; toolbar: false"&gt;public X509Certificate2 GetCertificateFromStore(StoreLocation storeLocation, 
    StoreName storeName, string thumbprint)
{
    X509Store store = new X509Store(storeName, storeLocation);
    store.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certs =
        store.Certificates.Find(X509FindType.FindByThumbprint,
        thumbprint, false);
    store.Close();
    return certs[0];
}&lt;/pre&gt;
&lt;p&gt;Si hici&amp;eacute;ramos una prueba unitaria de este m&amp;eacute;todo podr&amp;iacute;amos comprobar como efectivamente recuperamos el certificado de usuario:&lt;/p&gt;
&lt;pre class="brush: c-sharp; toolbar: false"&gt;[TestMethod]
public void TestGetCertificate()
{
    Signature sig = new Signature();
    X509Certificate2 cert = sig.GetCertificateFromStore(StoreLocation.CurrentUser, StoreName.My,
        "91 15 78 ac 78 8a 20 4d e2 33 96 4a c7 90 c1 36 c0 db ad df");
    Assert.IsNotNull(cert);
}&lt;/pre&gt;
&lt;p&gt;Para acceder al certificado empleamos la propiedad &lt;em&gt;Thumbprint&lt;/em&gt; (Huella dactilar) del mismo, que podemos ver en las propiedades del certificado:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devarch.net/image.axd?picture=Certificados2.png"&gt;&lt;img style="display: inline; border: 0px;" title="Propiedades del certificado" src="http://devarch.net/image.axd?picture=Certificados2_thumb.png" border="0" alt="Propiedades del certificado" width="210" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En el pr&amp;oacute;ximo art&amp;iacute;culo realizaremos una firma con SignedXml y el certificado recuperado.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/5b9cmCMuXpQ" height="1" width="1"/&gt;</summary>
    <published>2011-03-28T15:53:00+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2011/03/28/realizar-firmas-xades-desde-net-2.aspx#comment" />
    <category term="Seguridad" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>En el anterior artículo he introducido el concepto de la firma digital mediante los estándares XAdES y XML-DSig. En este artículo vamos a ver cómo validar una firma mediante XML-DSig, empleando las clases nativas facilitadas en .Net, en modo Enveloped, así como vamos a generar un certificado X509 para poder realizar la firma y ver cómo accedemos al mismo.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=e00eb190-02f3-4303-a2b5-238806da188e</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=e00eb190-02f3-4303-a2b5-238806da188e</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2011/03/28/realizar-firmas-xades-desde-net-2.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=e00eb190-02f3-4303-a2b5-238806da188e</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2011/03/28/realizar-firmas-xades-desde-net-2.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx</id>
    <title>Realizar firmas XAdES desde .Net (1)</title>
    <updated>2011-03-25T16:35:33+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=667d367f-dd54-405d-9650-3546b6a181f2" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/iIdy16yWN9c/realizar-firmas-xades-desde-Net-1.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;Es raro que hasta hace poco, trabajando tanto tiempo con BizTalk y con XML, no haya tenido que trabajar con protocolos de firma de XML. En esta serie de artículos voy a hablar acerca de cómo realizar una firma mediante &lt;a href="http://es.wikipedia.org/wiki/Xades" target="_blank"&gt;XAdES (XML Advanced Electronic Signatures)&lt;/a&gt;&lt;em&gt;.&lt;/em&gt; XAdES consiste en una capa superior al estándar de firma XML &lt;a href="http://www.w3.org/TR/xmldsig-core/" target="_blank"&gt;Xml-DSig (o XML Signature)&lt;/a&gt;. Pero más raro aún, buscando en internet, es no haber logrado encontrar ningún artículo que hable de conseguir realizar firmas mediante este estándar con .Net, e incluso algunos afirmando que este tipo de firma sólo puede realizarse en Java. Pero nada más lejos de la realidad.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Al finalizar este artículo seremos capaces de realizar firmas compatibles con el estándar &lt;em&gt;XAdES-BES&lt;/em&gt; (es el nivel básico de seguridad ofrecido por el estándar, como se puede leer en el artículo de la wikipedia que he enlazado más arriba). Fundamentalmente, un XML con firma XAdES-BES consiste en un documento XML con una firma &lt;em&gt;Enveloped&lt;/em&gt;. Este tipo de firma consiste en un XML con nuestros datos, en el cual al final del mismo existe un nodo &lt;em&gt;Signature&lt;/em&gt; (establecido en el estándar Xml-DSig) dentro del cual se encuentra la firma del mismo.&lt;/p&gt;  &lt;p&gt;Vamos a trabajar con los siguientes objetos en .Net, con lo cual, estaría bien tener ciertas nociones en el uso de los mismos para poder seguir el artículo:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;X509Certificate2: Realizaremos la firma mediante un certificado instalado en el almacén de certificados Windows de la máquina. Este objeto representa toda la información del mismo: Clave pública y privada (si existe), emisor del certificado, caducidad, etc etc… &lt;/li&gt;    &lt;li&gt;SignedXml: Este objeto es la implementación de Microsoft en .Net del estándar de firma XML Signature. Es clave para poder realizar las firmas correctamente. &lt;/li&gt;    &lt;li&gt;XmlDocument (y en general todo el DOM XML de Microsoft): Estos objetos hacen accesible el XML a firmar (y el firmado) mediante el modelo de objetos DOM. &lt;/li&gt;    &lt;li&gt;Reference, DataObject: Objetos auxiliares, que nos permitirán generar la estructura de la firma correctamente. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Adicionalmente, también estaría bien conocer las bases de la criptografía, al menos las bases de la firma mediante claves asíncronas. Y conocer el uso de certificados de usuario X509.&lt;/p&gt;  &lt;p&gt;Comenzaremos esta introducción, analizando un XML firmado mediante el estándar &lt;em&gt;XAdES-BES&lt;/em&gt;. Por ejemplo, si tenemos este XML que necesitamos firmar:&lt;/p&gt;  &lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;documento id=&amp;quot;documento&amp;quot;&amp;gt;
  &amp;lt;titulo id=&amp;quot;titulo&amp;quot;&amp;gt;Documento de pruebas&amp;lt;/titulo&amp;gt;
  &amp;lt;descripcion id=&amp;quot;descripcion&amp;quot;&amp;gt;Documento destinado a realizar pruebas de firma&amp;lt;/descripcion&amp;gt;
&amp;lt;/documento&amp;gt;&lt;/pre&gt;

&lt;p&gt;Este sería el XML firmado (el ejemplo está acortado para aportar claridad al artículo):&lt;/p&gt;

&lt;pre class="brush: xhtml; toolbar: false"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;documento id=&amp;quot;documento&amp;quot;&amp;gt;
  &amp;lt;titulo id=&amp;quot;titulo&amp;quot;&amp;gt;Documento de pruebas&amp;lt;/titulo&amp;gt;
  &amp;lt;descripcion id=&amp;quot;descripcion&amp;quot;&amp;gt;Documento destinado a realizar pruebas de firma&amp;lt;/descripcion&amp;gt;
  &amp;lt;Signature Id=&amp;quot;SignatureUsuario&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;
    &amp;lt;SignedInfo&amp;gt;
      &amp;lt;CanonicalizationMethod Algorithm=&amp;quot;http://www.w3.org/2001/10/xml-exc-c14n#&amp;quot; /&amp;gt;
      &amp;lt;SignatureMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#rsa-sha1&amp;quot; /&amp;gt;
      &amp;lt;Reference URI=&amp;quot;&amp;quot;&amp;gt;
        &amp;lt;Transforms&amp;gt;
          &amp;lt;Transform Algorithm=&amp;quot;http://www.w3.org/TR/1999/REC-xpath-19991116&amp;quot;&amp;gt;
            &amp;lt;XPath xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;not(ancestor-or-self::ds:Signature)&amp;lt;/XPath&amp;gt;
          &amp;lt;/Transform&amp;gt;
          &amp;lt;Transform Algorithm=&amp;quot;http://www.w3.org/2001/10/xml-exc-c14n#&amp;quot; /&amp;gt;
        &amp;lt;/Transforms&amp;gt;
        &amp;lt;DigestMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#sha1&amp;quot; /&amp;gt;
        &amp;lt;DigestValue&amp;gt;&amp;lt;!-- Digest del XML completo en Base64 --&amp;gt;&amp;lt;/DigestValue&amp;gt;
      &amp;lt;/Reference&amp;gt;
      &amp;lt;Reference Id=&amp;quot;SignatureUsuario-XADES-Properties-Ref&amp;quot; URI=&amp;quot;#XADES-Properties&amp;quot; Type=&amp;quot;http://uri.etsi.org/01903/v1.2.2#SignedProperties&amp;quot;&amp;gt;
        &amp;lt;Transforms&amp;gt;
          &amp;lt;Transform Algorithm=&amp;quot;http://www.w3.org/2001/10/xml-exc-c14n#&amp;quot; /&amp;gt;
        &amp;lt;/Transforms&amp;gt;
        &amp;lt;DigestMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#sha1&amp;quot; /&amp;gt;
        &amp;lt;DigestValue&amp;gt;&amp;lt;!-- Digest del objeto XAdES en Base64 --&amp;gt;&amp;lt;/DigestValue&amp;gt;
      &amp;lt;/Reference&amp;gt;
      &amp;lt;Reference Id=&amp;quot;SignatureUsuario-KeyInfo-Ref&amp;quot; URI=&amp;quot;#KeyInfo&amp;quot;&amp;gt;
        &amp;lt;Transforms&amp;gt;
          &amp;lt;Transform Algorithm=&amp;quot;http://www.w3.org/2001/10/xml-exc-c14n#&amp;quot; /&amp;gt;
        &amp;lt;/Transforms&amp;gt;
        &amp;lt;DigestMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#sha1&amp;quot; /&amp;gt;
        &amp;lt;DigestValue&amp;gt;&amp;lt;!-- Digest del objeto KeyInfo en Base64 --&amp;gt;&amp;lt;/DigestValue&amp;gt;
      &amp;lt;/Reference&amp;gt;
    &amp;lt;/SignedInfo&amp;gt;
    &amp;lt;SignatureValue&amp;gt;&amp;lt;!-- Valor de la firma en Base64 --&amp;gt;&amp;lt;/SignatureValue&amp;gt;
    &amp;lt;KeyInfo Id=&amp;quot;KeyInfo&amp;quot;&amp;gt;
      &amp;lt;X509Data&amp;gt;
        &amp;lt;X509SubjectName&amp;gt;&amp;lt;!-- Subject del certificado que realiza la firma --&amp;gt;&amp;lt;/X509SubjectName&amp;gt;
        &amp;lt;X509Certificate&amp;gt;&amp;lt;!-- Clave pública del certificado en Base64 --&amp;gt;&amp;lt;/X509Certificate&amp;gt;
      &amp;lt;/X509Data&amp;gt;
    &amp;lt;/KeyInfo&amp;gt;
    &amp;lt;Object Id=&amp;quot;XADES&amp;quot;&amp;gt;
      &amp;lt;etsi:QualifyingProperties Target=&amp;quot;SignatureUsuario&amp;quot; xmlns:etsi=&amp;quot;http://uri.etsi.org/01903/v1.3.2#&amp;quot;&amp;gt;
        &amp;lt;etsi:SignedProperties Id=&amp;quot;XADES-Properties&amp;quot;&amp;gt;
          &amp;lt;etsi:SignedSignatureProperties&amp;gt;
            &amp;lt;etsi:SigningTime&amp;gt;2011-03-28T09:56:09Z&amp;lt;/etsi:SigningTime&amp;gt;
            &amp;lt;etsi:SigningCertificate&amp;gt;
              &amp;lt;etsi:Cert&amp;gt;
                &amp;lt;etsi:CertDigest&amp;gt;
                  &amp;lt;ds:DigestMethod Algorithm=&amp;quot;http://www.w3.org/2000/09/xmldsig#sha1&amp;quot; xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot; /&amp;gt;
                  &amp;lt;ds:DigestValue xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&amp;lt;!-- Digest del certificado en Base64 --&amp;gt;&amp;lt;/ds:DigestValue&amp;gt;
                &amp;lt;/etsi:CertDigest&amp;gt;
                &amp;lt;etsi:IssuerSerial&amp;gt;
                  &amp;lt;ds:X509IssuerName xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&amp;lt;!-- Asunto del emisor del certificado --&amp;gt;&amp;lt;/ds:X509IssuerName&amp;gt;
                  &amp;lt;ds:X509SerialNumber xmlns:ds=&amp;quot;http://www.w3.org/2000/09/xmldsig#&amp;quot;&amp;gt;&amp;lt;!-- Número de serie del certificado emisor --&amp;gt;&amp;lt;/ds:X509SerialNumber&amp;gt;
                &amp;lt;/etsi:IssuerSerial&amp;gt;
              &amp;lt;/etsi:Cert&amp;gt;
            &amp;lt;/etsi:SigningCertificate&amp;gt;
          &amp;lt;/etsi:SignedSignatureProperties&amp;gt;
        &amp;lt;/etsi:SignedProperties&amp;gt;
      &amp;lt;/etsi:QualifyingProperties&amp;gt;
    &amp;lt;/Object&amp;gt;
  &amp;lt;/Signature&amp;gt;
&amp;lt;/documento&amp;gt;&lt;/pre&gt;

&lt;p&gt;En este XML podemos observar cómo se introduce un nodo Signature como último elemento que cuelga del nodo raíz. Esta firma es por tanto, una firma &lt;em&gt;Enveloped&lt;/em&gt;. Dentro de este nodo firma podemos diferenciar dos partes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Parte de la firma XmlDSig: Consiste en la parte del nodo Signature comprendida entre las líneas 6 y 40 del ejemplo. Estos nodos son generados de manera nativa por el objeto SignedXml de .Net al realizar el cálculo de la misma. &lt;/li&gt;

  &lt;li&gt;Extensión XAdES: Consiste en el resto del nodo Signature, esto es, los nodos comprendidos entre las líneas 41 y 61. En estas líneas se describen ciertas propiedades del certificado de usuario que está realizando la firma. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recordemos que el estándar XML-DSig admite tres tipos de firmas diferentes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Enveloped: &lt;/em&gt;El XML que contiene la firma se incrusta en el interior del XML a firmar, como en el ejemplo anterior.&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;Enveloping: &lt;/em&gt;El documento firmado se incrusta dentro del XML de la firma.&lt;/li&gt;

  &lt;li&gt;&lt;em&gt;Detached:&lt;/em&gt; El XML que contiene la firma es independiente del documento firmado. Por tanto, para validar la firma, es necesario transmitir separadamente el XML de la firma y el XML firmado.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/iIdy16yWN9c" height="1" width="1"/&gt;</summary>
    <published>2011-03-25T16:35:33+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx#comment" />
    <category term="Seguridad" />
    <dc:publisher>zorry</dc:publisher>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=667d367f-dd54-405d-9650-3546b6a181f2</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=667d367f-dd54-405d-9650-3546b6a181f2</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=667d367f-dd54-405d-9650-3546b6a181f2</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2011/03/25/realizar-firmas-xades-desde-Net-1.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-4.aspx</id>
    <title>Uso de tablas de cross references como almacenamiento (4)</title>
    <updated>2010-08-03T12:45:02+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=11f4f7d4-fee3-4bf1-91b4-307f7e84ef6f" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/zdSYpI4EpEs/uso-de-tablas-de-cross-references-como-almacenamiento-4.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;Una vez que hemos visto cómo obtener datos de las tablas de referencia cruzada provistas por BizTalk Server, en este artículo vamos a ver un ejemplo práctico de uso de esta funcionalidad. En este ejemplo veremos como realizar un formateo de mensaje parametrizado.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Primero deberemos establecer el texto del mensaje y sus parámetros. Para ello modificaremos los archivos XML correspondientes:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;List_Of_Message_Definition.xml&lt;/strong&gt;&lt;/p&gt;  &lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfMessageDef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;messageDef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;code&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;APP1_EMAIL_BODY&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;code&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Email to send in case of error in process.&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;argumentName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Argument1 Id&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;argumentName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;argumentName&lt;/span&gt; &lt;span style="color: #ff0000"&gt;idXRefName&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;APP1_APPCODE&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;App Code&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;argumentName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;messageDef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfMessageDef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;En este XML definimos un mensaje, de nombre APP1_EMAIL_BODY. Este mensaje tendrá dos parámetros:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;El primero (Argument1 Id) será un parámetro de reemplazamiento (el valor que facilitemos en el primer parámetro será sustituido directamente en la cadena del mensaje). &lt;/li&gt;

  &lt;li&gt;El segundo parámetro (App Code) será un parámetro enlazado con una cross reference. Es decir, que se tomará el valor de la cross reference indicado por el valor suministrado al segundo parámetro, y se introducirá en el mensaje.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;List_Of_Message_Text.xml&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfMessageText&lt;/span&gt; &lt;span style="color: #ff0000"&gt;lang&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;es-ES&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
   &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;messageText&lt;/span&gt; &lt;span style="color: #ff0000"&gt;code&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;APP1_EMAIL&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;This is a mail message with id '%1', 
      please contact %2.&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;messageText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfMessageText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;En este XML definimos el texto del mensaje, en el que se puede ver que podemos, para un mismo nombre de mensaje, podríamos definir más de un literal de nombre (para su localización). En el literal, se define la posición de los dos argumentos con el literal %n, siendo n la posición del argumento.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;List_Of_IdXRef.xml&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfIDXRef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;idXRef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;APP1_APPCODE&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;description&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;idXRef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfIDXRef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;En este XML definimos el nombre de la cross reference que empleamos como argumento en el mensaje.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;List_Of_IdXRef_Value.xml&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfIDXRefData&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;idXRef&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;APP1_APPCODE&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;appInstance&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;APP1_INSTANCE&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
			&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;appID&lt;/span&gt; &lt;span style="color: #ff0000"&gt;commonID&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;12&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Pedro García&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;appID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
		&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;appInstance&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;idXRef&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;	
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;listOfIDXRefData&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;En este XML definimos el valor de la cross reference Para un CommonID 12.&lt;/p&gt;

&lt;p&gt;Para el ejemplo supondremos que hemos definido una instancia de aplicación APP1_INSTANCE, dependiente de un tipo de aplicación APP1_TYPE, en sus correspondientes archivos XML de importación.&lt;/p&gt;

&lt;p&gt;Una vez definidos e importados los datos mediante BTSXRefImport.exe, simplemente tendremos que llamar al método FormatMessage:&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #008000"&gt;//Reads message body from configuration&lt;/span&gt;
varAuxString = Microsoft.BizTalk.CrossReferencing.CrossReferencing.
    FormatMessage(&amp;quot;&lt;span style="color: #8b0000"&gt;APP1_EMAIL&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;es-ES&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;APP1_INSTANCE&lt;/span&gt;&amp;quot;, 
    &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &amp;quot;&lt;span style="color: #8b0000"&gt;Identification&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;12&lt;/span&gt;&amp;quot;);&lt;/pre&gt;

&lt;p&gt;O bien mediante el functoid equivalente, si necesitamos obtener el mensaje desde un mapa:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.devarch.net/image.axd?picture=image_2.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="224" alt="image" src="http://www.devarch.net/image.axd?picture=image_thumb_2.png" width="320" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Con este ejemplo, finalizamos esta serie de artículos que hablan acerca de esta funcionalidad poco documentada de BizTalk Server 2006.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/zdSYpI4EpEs" height="1" width="1"/&gt;</summary>
    <published>2010-08-03T12:45:02+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-4.aspx#comment" />
    <category term="BizTalk" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>Una vez que hemos visto cómo obtener datos de las tablas de referencia cruzada provistas por BizTalk Server, en este artículo vamos a ver un ejemplo práctico de uso de esta funcionalidad. En este ejemplo veremos como realizar un formateo de mensaje parametrizado.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=11f4f7d4-fee3-4bf1-91b4-307f7e84ef6f</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=11f4f7d4-fee3-4bf1-91b4-307f7e84ef6f</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-4.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=11f4f7d4-fee3-4bf1-91b4-307f7e84ef6f</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-4.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-3.aspx</id>
    <title>Uso de tablas de cross references como almacenamiento (3)</title>
    <updated>2010-08-03T10:27:08+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=982dba31-8f1b-4b66-8040-cb7086298879" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/0cJ5uthl1ts/uso-de-tablas-de-cross-references-como-almacenamiento-3.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;Una vez que hemos descrito las bases de la funcionalidad de cross references ofrecida por BizTalk, cómo estructura internamente BizTalk estos datos &lt;a href="http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx"&gt;en el primer artículo de la serie&lt;/a&gt;, y de que manera introducir los parámetros de configuración en las tablas xref &lt;a href="http://www.devarch.net/post/2010/07/15/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx"&gt;en el segundo&lt;/a&gt;, en este artículo vamos a ver la parte más importante, de qué manera obtener estos datos para manejarlos en nuestra aplicación.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;En primer lugar, tenemos que ver en que lugar debemos acceder a las tablas xref, teniendo dos posibilidades para acceder a las mismas: En mapas y en orquestaciones.&lt;/p&gt;  &lt;p&gt;Al acceder a las tablas xref desde mapas, emplearemos una serie de functoids facilitados por BizTalk de manera nativa:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.devarch.net/image.axd?picture=image.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="246" alt="image" src="http://www.devarch.net/image.axd?picture=image_thumb.png" width="230" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Así, podemos arrastrar los fucntoid necesarios para obtener los datos de configuración. En el ejemplo que nos ocupaba en la primera tabla del artículo 2, para obtener el CommonID de valor 123456789, deberíamos hacer la siguiente llamada al functoid &lt;em&gt;Get Common ID&lt;/em&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.devarch.net/image.axd?picture=image_1.png"&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="362" alt="image" src="http://www.devarch.net/image.axd?picture=image_thumb_1.png" width="389" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Igual podemos hacer para obtener un valor por aplicación, llamando al functoid &lt;em&gt;Get Application ID&lt;/em&gt;, o formatear un mensaje con el functoid &lt;em&gt;Format Message&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;También tenemos la posibilidad de obtener datos de configuración en las orquestaciones. Para ello, tenemos que referenciar el assembly &lt;em&gt;Microsoft.BizTalk.CrossReferencing&lt;/em&gt; (localizado en la ruta de instalación de BizTalk) en el proyecto en que tengamos nuestra orquestación.&lt;/p&gt;  &lt;p&gt;Una vez determinado el lugar donde queremos acceder a las tablas xref, emplearemos un shape &lt;em&gt;Message Assignment&lt;/em&gt;&amp;#160; o un shape &lt;em&gt;Expression&lt;/em&gt;, en el que introduciremos este código:&lt;/p&gt;  &lt;pre&gt;&lt;span style="color: #008000"&gt;//Reads order CommonID from configuration&lt;/span&gt;
varAuxString = Microsoft.BizTalk.CrossReferencing.CrossReferencing.
    GetCommonID(&amp;quot;&lt;span style="color: #8b0000"&gt;ORDER&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Siebel&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;111&lt;/span&gt;&amp;quot;);&lt;/pre&gt;

&lt;p&gt;De igual manera, podemos hacer una consulta por valores de aplicación llamando al método &lt;em&gt;GetApplicationID&lt;/em&gt;, o formatear un mensaje con el método &lt;em&gt;FormatMessage&lt;/em&gt; dentro de este namespace &lt;em&gt;Microsoft.BizTalk.CrossReferencing.CrossReferencing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;En este artículo hemos podido ver cómo consumir los datos almacenados en las tablas xref de BizTalk, como manera de acceder a parámetros de configuración tanto de aplicación como de referencias cruzadas entre diferentes aplicaciones.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/0cJ5uthl1ts" height="1" width="1"/&gt;</summary>
    <published>2010-08-03T10:27:08+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-3.aspx#comment" />
    <category term="BizTalk" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>Una vez que hemos descrito las bases de la funcionalidad de cross references ofrecida por BizTalk, cómo estructura internamente BizTalk estos datos en el primer artículo de la serie, y de que manera introducir los parámetros de configuración en las tablas xref en el segundo, en este artículo vamos a ver la parte más importante, de qué manera obtener estos datos para manejarlos en nuestra aplicación.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=982dba31-8f1b-4b66-8040-cb7086298879</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=982dba31-8f1b-4b66-8040-cb7086298879</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-3.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=982dba31-8f1b-4b66-8040-cb7086298879</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2010/08/03/uso-de-tablas-de-cross-references-como-almacenamiento-3.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2010/07/15/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx</id>
    <title>Uso de tablas de cross references como almacenamiento (2)</title>
    <updated>2010-07-15T10:38:58+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=f1f96530-ae94-4950-8822-df3d4ae2d979" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/U_hl4KAuQgQ/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;En el &lt;a href="http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx"&gt;artículo anterior&lt;/a&gt; vimos los pros y contras de emplear las tablas xref de BizTalk para almacenar datos de configuración. En este, vamos a describir de una manera práctica cómo introducir datos de configuración o de referencias cruzadas en BizTalk de una manera sencilla.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Para importar datos en las tablas xref de BizTalk, necesitaremos definir una serie de archivos XML. En este archivo zip tenemos un ejemplo de paquete de despliegue, el cual podemos usar como plantilla para adaptarlo a los valores que necesite nuestra aplicación:&lt;/p&gt;  &lt;div class="wlWriterEditableSmartContent" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:e87a8dda-2556-4bc5-a44d-81fc26308257" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;p&gt; &lt;a href="http://www.devarch.net/file.axd?file=xrefseed_2.zip" target="_blank"&gt;XrefSeed.zip&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;  &lt;p&gt;Una vez modificados los XML, tenemos que llamar a una herramienta de línea de comandos con la siguiente sentencia:&lt;/p&gt;  &lt;pre&gt;BTSXRefImport.exe -file=SetupFile.xml&lt;/pre&gt;

&lt;p&gt;Este archivo SetupFile.xml contendrá una lista de archivos XML, los cuales almacenarán todos los datos que se importarán en las diferentes tablas en base de datos. Su contenido será parecido a esto:&lt;/p&gt;

&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;&lt;span style="color: #0000ff"&gt;?&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setup-Files&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;:&lt;span style="color: #ff0000"&gt;xsi&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #008000"&gt;&amp;lt;!-- btsxrefimport -file=setupfiles.xml--&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;App_Type_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_App_Type.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;App_Type_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;App_Instance_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_App_Instance.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;App_Instance_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;IDXRef_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_IDXRef.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;IDXRef_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;IDXRef_Data_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_IDXRef_Data.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;IDXRef_Data_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
         &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ValueXRef_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_ValueXRef.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ValueXRef_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ValueXRef_Data_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_ValueXRef_Data.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ValueXRef_Data_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Msg_Def_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_Message_Definition.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Msg_Def_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
	&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Msg_Text_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;List_Of_Message_Text.xml&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Msg_Text_file&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Setup-Files&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;A partir de aquí tendremos que ir modificando cada archivo XML, teniendo en cuenta que tenemos cuatro grupos de archivos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Archivos de definición de aplicaciones:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;List_Of_App_Type.xml: En este archivo se definen los tipos de aplicación que queremos declarar. &lt;/li&gt;

  &lt;li&gt;List_Of_App_Instance.xml: En este archivo se definen las diferentes instancias de aplicaciones que necesitemos declarar. Por ejemplo, para un tipo de aplicación APP1, podemos tener varias instancias como por ejemplo APP1.Config, APP1.Constants o APP1.Codes…&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;Archivos de definición de ID de referencias cruzadas, relacionadas con una instancia de aplicación.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;List_Of_IDXRef.xml: En este archivo se definirán los nombres de las claves de configuración para las que queramos dar valores.&lt;/li&gt;

  &lt;li&gt;List_Of_IDXRef_Data.xml: En este archivo se guardan los valores de las claves de configuración, relacionando estas con las instancias de aplicación.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En la siguiente tabla podemos ver los diferentes datos que pueden almacenar estos archivos:&lt;/p&gt;

&lt;table cellspacing="0" cellpadding="2" width="400" border="1"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="100"&gt;AppInst&amp;#160;&amp;#160;&amp;#160; &lt;/td&gt;

      &lt;td valign="top" width="100"&gt;IDXRef&amp;#160;&amp;#160;&amp;#160; &lt;/td&gt;

      &lt;td valign="top" width="100"&gt;CommonID&amp;#160;&amp;#160;&amp;#160; &lt;/td&gt;

      &lt;td valign="top" width="100"&gt;AppID&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="100"&gt;Siebel&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;ORDER&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;123456789&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;111&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="100"&gt;Oracle&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;ORDER&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;123456789&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;333&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;
  &lt;br /&gt;De esta manera, para un IDXRef ORDER y un CommonID 123456789, tenemos que para la instancia Siebel, el valor de configuración es 111, mientras que para la instancia Oracle, el valor de configuración es 333.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Archivos de definición de valores de configuración, relacionados con uno o varios tipos de aplicación.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;List_Of_ValueXRef.xml: En este archivo se definirán los nombres de las claves de configuración para las que queramos dar valores.&lt;/li&gt;

  &lt;li&gt;List_Of_ValueXRef_Data.xml: En este archivo se guardan los valores de las claves de configuración.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;En la siguiente tabla podemos ver los diferentes datos que pueden almacenar estos archivos:&lt;/p&gt;

&lt;table cellspacing="0" cellpadding="2" width="400" border="1"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="100"&gt;AppType&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;ValXRef&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;CommonValue&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;AppValue&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="100"&gt;Siebel&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;OrderStatus&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;Open&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;Open&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="100"&gt;Oracle&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;OrderStatus&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;Open&lt;/td&gt;

      &lt;td valign="top" width="100"&gt;ENTERED&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;De esta manera podemos definir un diferente valor para AppValue, dependiendo de la aplicación, para un mismo ValXRef y CommonValue.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Archivos de definición de mensajes y sus literales, pudiendo especificar mensajes en diferentes idiomas.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;List_Of_Message_Definition.xml: En este archivo declararemos los ID de los mensajes que necesite nuestra aplicación, así como los posibles parámetros de sustitución que pudieran tener estos.&lt;/li&gt;

  &lt;li&gt;List_Of_Message_Text.xml: En este archivo se almacenan los literales de los mensajes, especificando el idioma de estos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Al ejecutar la herramienta BTSXRefImport.exe, se importarán los datos contenidos en estos ocho archivos en nueve tablas de la base de datos BizTalkMgmtDb:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;xref_AppInstance&lt;/li&gt;

  &lt;li&gt;xref_AppType&lt;/li&gt;

  &lt;li&gt;xref_IDXRef&lt;/li&gt;

  &lt;li&gt;xref_IDXRefData&lt;/li&gt;

  &lt;li&gt;xref_MessageArgument&lt;/li&gt;

  &lt;li&gt;xref_MessageDef&lt;/li&gt;

  &lt;li&gt;xref_MessageText&lt;/li&gt;

  &lt;li&gt;xref_ValueXRef&lt;/li&gt;

  &lt;li&gt;xref_ValueXRefData&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una vez hemos visto la estructura de los archivos XML de xref y para qué sirve cada uno de ellos, en el &lt;a href="http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento-y3.aspx"&gt;siguiente artículo&lt;/a&gt; veremos cómo obtener estos datos, o bien llamando al API de BizTalk si vamos a leerlos desde código u orquestaciones, o bien empleando functoids si los leemos en mapas.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/U_hl4KAuQgQ" height="1" width="1"/&gt;</summary>
    <published>2010-07-15T10:38:58+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2010/07/15/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx#comment" />
    <category term="BizTalk" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>En el artículo anterior vimos los pros y contras de emplear las tablas xref de BizTalk para almacenar datos de configuración. En este, vamos a describir de una manera práctica cómo introducir datos de configuración o de referencias cruzadas en BizTalk de una manera sencilla.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=f1f96530-ae94-4950-8822-df3d4ae2d979</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=f1f96530-ae94-4950-8822-df3d4ae2d979</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2010/07/15/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=f1f96530-ae94-4950-8822-df3d4ae2d979</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2010/07/15/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx</id>
    <title>Uso de tablas de cross references como almacenamiento (1)</title>
    <updated>2010-07-13T11:27:00+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=9bdce9c7-c669-463b-b283-1e72b7e7e8c9" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/dKMf5XN03ww/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;Dentro de las posibilidades que tenemos de parametrizar nuestra aplicaci&amp;oacute;n BizTalk, vamos a ver c&amp;oacute;mo podemos usar las tablas Cross References (xref) para almacenar valores de configuraci&amp;oacute;n que posteriormente podemos consumir en nuestra aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Sin analizar mucho, podemos recurrir a otras alternativas para almacenar par&amp;aacute;metros de nuestra aplicaci&amp;oacute;n, pero estas alternativas tienen sus inconvenientes. Por ejemplo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uso de archivos XML de configuraci&amp;oacute;n. Si tenemos una infraestructura con m&amp;aacute;s de una m&amp;aacute;quina BizTalk, tendremos que tener cuidado al desplegar la aplicaci&amp;oacute;n y configuraci&amp;oacute;n (o al modificar un valor de la misma), al tener que realizar la misma modificaci&amp;oacute;n en todas las m&amp;aacute;quinas, es decir, que la configuraci&amp;oacute;n es susceptible a errores. &lt;/li&gt;
&lt;li&gt;Uso de una base de datos propietaria. Esta soluci&amp;oacute;n, aun evitando los problemas de la soluci&amp;oacute;n anterior, requiere de un esfuerzo de desarrollo de la base de datos y del c&amp;oacute;digo que accede a los par&amp;aacute;metros y sus valores. &lt;/li&gt;
&lt;li&gt;Uso de la base de datos de Single Sign On. Aunque se puede usar esta base de datos para almacenar datos de configuraci&amp;oacute;n, realmente no est&amp;aacute; dise&amp;ntilde;ada para esta funci&amp;oacute;n. &lt;/li&gt;
&lt;li&gt;Uso de Business Rules. Tambi&amp;eacute;n se pueden usar para almacenar datos de configuraci&amp;oacute;n, pero no es el prop&amp;oacute;sito de esta herramienta, que est&amp;aacute; dise&amp;ntilde;ada para almacenar decisiones de negocio basadas en par&amp;aacute;metros. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin embargo, esta soluci&amp;oacute;n nos permitir&amp;aacute; salvar estos inconvenientes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No depende de archivos de configuraci&amp;oacute;n, con lo que un cambio en la configuraci&amp;oacute;n afectar&amp;aacute; en todo momento a todas las m&amp;aacute;quinas que est&amp;eacute;n en un grupo de BizTalk. &lt;/li&gt;
&lt;li&gt;No hay que implementar tablas o procedimientos almacenados de base de datos, ni desplegar nuevas bases de datos en el servidor de bases de datos, puesto que se emplean las tablas xref que se encuentran en la base de datos BiztalkMgmtDb. &lt;/li&gt;
&lt;li&gt;No hay que realizar ning&amp;uacute;n desarrollo espec&amp;iacute;fico para acceder a estas tablas, puesto que BizTalk posee un API que ya facilita el acceso a estas. Incluso, en el caso de los mapas, ya de manera nativa tenemos functoids que nos devolver&amp;aacute;n los valores que tengamos parametrizados. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;De modo que una vez analizadas las ventajas, vamos a ver c&amp;oacute;mo almacenar par&amp;aacute;metros y valores en estas tablas:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.devarch.net/image.axd?picture=Relaciones_1.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" title="Relaciones" src="http://www.devarch.net/image.axd?picture=Relaciones_thumb_1.gif" border="0" alt="Relaciones" width="560" height="380" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Esta es la estructura de las tablas. Para importar valores dentro de este esquema de base de datos, BizTalk nos facilita una herramienta dentro de la ruta de instalaci&amp;oacute;n de BizTalk Server, a la cual tendremos que proporcionarle una serie de archivos Xml con los datos que queremos almacenar. Esta herramienta se denomina BtsXrefImport.exe, es una herramienta de l&amp;iacute;nea de comandos a la cual tendremos que suministrarle un archivo xml de configuraci&amp;oacute;n&lt;/p&gt;
&lt;p&gt;En el &lt;a href="http://www.devarch.net/post/2010/07/15/uso-de-tablas-de-cross-references-como-almacenamiento-2.aspx"&gt;siguiente art&amp;iacute;culo&lt;/a&gt; analizaremos c&amp;oacute;mo introducir los datos dentro de las tablas de xref, as&amp;iacute; como obtener la informaci&amp;oacute;n de ellos desde orquestaciones y mapas.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/dKMf5XN03ww" height="1" width="1"/&gt;</summary>
    <published>2010-07-13T11:27:00+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx#comment" />
    <category term="BizTalk" />
    <dc:publisher>zorry</dc:publisher>
    <dc:description>Dentro de las posibilidades que tenemos de parametrizar nuestra aplicación BizTalk, vamos a ver cómo podemos usar las tablas Cross References (xref) para almacenar valores de configuración que posteriormente podemos consumir en nuestra aplicación.</dc:description>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=9bdce9c7-c669-463b-b283-1e72b7e7e8c9</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=9bdce9c7-c669-463b-b283-1e72b7e7e8c9</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=9bdce9c7-c669-463b-b283-1e72b7e7e8c9</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2010/07/13/Uso-de-tablas-de-cross-references-como-almacenamiento.aspx</feedburner:origLink></entry>
  <entry>
    <id>http://www.devarch.net/post/2010/02/26/Certificados-y-permisos.aspx</id>
    <title>Certificados y permisos</title>
    <updated>2010-02-26T07:46:49+00:00</updated>
    <link rel="self" href="http://www.devarch.net/post.aspx?id=9f2a1c25-ca4f-4c01-a052-01ffb76c7867" />
    <link href="http://feedproxy.google.com/~r/devarchnet/~3/aJKApzDTojY/Certificados-y-permisos.aspx" />
    <author>
      <name>zorry</name>
    </author>
    <summary type="html">&lt;p&gt;En los servicios WCF se puede establecer seguridad a nivel de mensaje. Para poderlo hacer, hay que instalar un certificado, que será el que se emplee para cifrar el contenido que se requiera.&lt;/p&gt;  &lt;p&gt;Ahora bien, un certificado generalmente es instalado por un administrador, pero un servicio generalmente corre con credenciales de usuario restringido. Con lo que normalmente no tendrá privilegios para poder acceder al fichero de la clave privada de los certificados. Vamos a ver cómo manejar esta situación.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;El error que nos dará en este caso es:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The certificate 'CN=xxxxxxxx' must have a private key that is capable of key exchange. &lt;/strong&gt;&lt;strong&gt;The process must have access rights for the private key&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Lo que nos hará falta es ubicar el archivo que contiene la clave privada del certificado en primer lugar. Y después conceder los permisos. Para lo 2º existe una herramienta en el sistema operativo: cacls.exe. Pero para lo 1º no existe ninguna herramienta.&lt;/p&gt;  &lt;p&gt;En la página &lt;a href="https://mail.ilitia.com/exchweb/bin/redir.asp?URL=http://msdn.microsoft.com/en-us/library/aa717039.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa717039.aspx&lt;/a&gt; existen aplicaciones de muestra para WCF, WF y CardSpace. Entre estas muestras hay una aplicación que se lama FindPrivateKey que sirve exactamente para esto.&lt;/p&gt;  &lt;p&gt;Se le dice cual es el contenedor del certificado y el nombre del mismo. Por ejemplo, para si queremos obtener el certificado instalado en el almacén personal de la máquina para el nombre NOMBRE-CERTIFICADO pondremos : &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;FindPrivateKey My LocalMachine -n &amp;quot;CN=NOMBRE-CERTIFICADO&amp;quot; -a&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;La salida será la ruta del archivo con la clave privada del certificado. Por ejemplo:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\8aeda5eb81555f14f8f9960745b5a40d_38f7de48-5ee9-452d-8a5a-92789d7110b1&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Y entonces tendremos que ir a ese archivo y dar permisos de lectura al usuario del pool del servicio. Por ejemplo, si el usuario es NETWORK SERVICE, pondremos:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;cacls.exe &amp;quot;C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys\8aeda5eb81555f14f8f9960745b5a40d_38f7de48-5ee9-452d-8a5a-92789d7110b1&amp;quot; /E /G &amp;quot;NETWORK SERVICE&amp;quot;:R&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;He de dar las gracias a Luis de Santiago que me ha proporcionado esta entrada. Gran truco, Luiso!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/devarchnet/~4/aJKApzDTojY" height="1" width="1"/&gt;</summary>
    <published>2010-02-26T07:46:49+00:00</published>
    <link rel="related" href="http://www.devarch.net/post/2010/02/26/Certificados-y-permisos.aspx#comment" />
    <category term="Seguridad" />
    <category term="Desarrollo .Net" />
    <dc:publisher>zorry</dc:publisher>
    <pingback:server>http://www.devarch.net/pingback.axd</pingback:server>
    <pingback:target>http://www.devarch.net/post.aspx?id=9f2a1c25-ca4f-4c01-a052-01ffb76c7867</pingback:target>
    <slash:comments>0</slash:comments>
    <trackback:ping>http://www.devarch.net/trackback.axd?id=9f2a1c25-ca4f-4c01-a052-01ffb76c7867</trackback:ping>
    <wfw:comment>http://www.devarch.net/post/2010/02/26/Certificados-y-permisos.aspx#comment</wfw:comment>
    <wfw:commentRss>http://www.devarch.net/syndication.axd?post=9f2a1c25-ca4f-4c01-a052-01ffb76c7867</wfw:commentRss>
  <feedburner:origLink>http://www.devarch.net/post/2010/02/26/Certificados-y-permisos.aspx</feedburner:origLink></entry>
</feed>

