Iniciar Sesión

Ver la Versión Completa : [Sintaxis] Firma digital sobre XML


Kuk
23 de febrero de 2017, 12:47
System.Security.Cryptography.Xml namespace allows you to digitally sign an XML document or part of it. The following example was converted into OO Cobol using a MSDN C# sample. The original C# code has been commented out so you can compare how far from C# logic OO Cobol is...see for yourself!


program-id. main as "ConsoleApplication5.Main".

environment division.
configuration section.
repository.
class ClassCspParameters as "System.Security.Cryptography.CspParameters"
class ClassXmlDocument as "System.Xml.XmlDocument"
class ClassXmlNode as "System.Xml.XmlNode"
class ClassRSACryptoServiceProvider as "System.Security.Cryptography.RSACryptoServiceProvi der"
class ClassSignedXml as "System.Security.Cryptography.Xml.SignedXml"
class ClassXmlReference as "System.Security.Cryptography.Xml.Reference"
class ClassXmlDsigEnvSignatureTrans
as "System.Security.Cryptography.Xml.XmlDsigEnvelopedS ignatureTransform"
class ClassXmlElement as "System.Xml.XmlElement"
class SystemString as "System.String"
property StringEmpty as "Empty"
property KeyContainer as "KeyContainerName"
property PreserveWhitespace as "PreserveWhitespace"
property SigningKey as "SigningKey"
property Uri as "Uri"
property DocumentElement as "DocumentElement".

data division.
working-storage section.
01 cspParams usage object reference ClassCspParameters.
01 xmlDoc usage object reference ClassXmlDocument.
01 xmlDocChild usage object reference ClassXmlNode.
01 xmlNode usage object reference ClassXmlNode.
01 rsaKey usage object reference ClassRSACryptoServiceProvider.
01 signedXml usage object reference ClassSignedXml.
01 xmlReference usage object reference ClassXmlReference.
01 emptyString usage object reference SystemString.
01 env usage object reference ClassXmlDsigEnvSignatureTrans.
01 xmlDigitalSignature usage object reference ClassXmlElement.
01 xmlElement usage object reference ClassXmlElement.

procedure division.

*> Cobol does not support empty strings, so this a trick
set emptyString to StringEmpty of SystemString

*> C# CspParameters cspParams = new CspParameters();
invoke ClassCspParameters "NEW" returning cspParams

*> C# cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
set KeyContainer OF cspParams to "XML_DSIG_RSA_KEY"

*> C# RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

invoke ClassRSACryptoServiceProvider "NEW" using cspParams returning rsaKey

*> C# XmlDocument xmlDoc = new XmlDocument();

invoke ClassXmlDocument "NEW" returning xmlDoc

*> C# xmlDoc.PreserveWhitespace = true;
set PreserveWhitespace of xmlDoc to b"1"

*> C# xmlDoc.Load("test.xml");
invoke xmlDoc "Load" using "c:\test.xml"

*> C# SignedXml signedXml = new SignedXml(Doc);
invoke ClassSignedXml "NEW" using xmlDoc returning signedXml

*> C# signedXml.SigningKey = Key; - it should be rsaKey instead of just "Key"
set SigningKey of signedXml to rsaKey

*> C# Reference reference = new Reference();
invoke ClassXmlReference "NEW" returning xmlReference

*> reference.Uri = ""; // !! means all document
set uri of xmlReference to emptyString

*> C$ XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
invoke ClassXmlDsigEnvSignatureTrans "NEW" returning env

*> C# reference.AddTransform(env);
invoke xmlReference "AddTransform" using env

*> C# signedXml.AddReference(reference);
invoke signedXml "AddReference" using xmlReference

*> signedXml.ComputeSignature()
invoke signedXml "ComputeSignature"

*> C# XmlElement xmlDigitalSignature = signedXml.GetXml();
invoke signedXml "GetXml" returning xmlDigitalSignature

*> C# Doc.DocumentElement.AppendChild(Doc.ImportNode(xml DigitalSignature, true));
invoke xmlDoc "ImportNode" using xmlDigitalSignature, b"1" returning xmlDocChild

set xmlElement to DocumentElement of xmlDoc

invoke xmlElement "AppendChild" using xmlDocChild

*> C# xmlDoc.Save("SignedTest.xml");
invoke xmlDoc "Save" using "c:\SignedTest.xml"

stop run.


Testing our app:


<?xml version="1.0" encoding="UTF-8" ?>
<Cliente version="1.0">
<Nome>Elis</Nome>
<Contatos>
<Telefone>99-9999-9999</Telefone>
<eMail>[email protected]</eMail>
</Contatos>
</Cliente>


After run our app:


<?xml version="1.0" encoding="UTF-8" ?>
<Cliente version="1.0">
<Nome>Elis</Nome>
<Contatos>
<Telefone>99-9999-9999</Telefone>
<eMail>[email protected]</eMail>
</Contatos>
<Signature xmlns=http://www.w3.org/2000/09/xmldsig#><SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /><Reference URI="">
<Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>y4V1upGm/awXUcAKWFAG/PSRDAU=</DigestValue></Reference></SignedInfo>
<SignatureValue>CNVyQxiYBVN C0o3szSkz 65mHFZ JV7rGgTkV62NH/i8fDN1yUJyd7Zo88TH4qdc
U Vc qPLSIwaHO411TgI5N vmitbodhYI4O7n8HwbDa1nTEsTeGnpsXlGXTJsTvQVUe1FpD HTsITfFmE
zs9HiuN5sY3glag4EZUCEyDIk=</SignatureValue>
</Signature></Cliente>

Recato53
26 de febrero de 2017, 20:48
Estoy intentando probar le código para firma un archivo XML y no consigo compilar el proyecto, se producen muchos errores, creo que falta algo.

Estoy muy interesado en este programa, me puedes enviar el proyecto en PowerCobol.

Muchas gracias.
Un saludo.

Kuk
26 de febrero de 2017, 23:38
Recato53, este código es de NetCOBOL .NET, si te fijas está usando clases externas que corresponden con Namespaces de .NET:


repository.
class ClassCspParameters as "System.Security.Cryptography.CspParameters"
class ClassXmlDocument as "System.Xml.XmlDocument"
class ClassXmlNode as "System.Xml.XmlNode"
class ClassRSACryptoServiceProvider as "System.Security.Cryptography.RSACryptoServiceProvi der"
class ClassSignedXml as "System.Security.Cryptography.Xml.SignedXml"
class ClassXmlReference as "System.Security.Cryptography.Xml.Reference"
...


Eslopes, corrígeme si me estoy equivocando.

Eslopes
21 de diciembre de 2017, 14:26
Sim, está correto. Todavia é possível usar este código com o Power. Neste caso é necessário criar uma DLL e expor a mesma para o Power, o qual poderá chamar uma DLL .Net desde que a mesma seja devidamente registrada no Windows Registry. Google é seu melhor amigo!!!