Highlighted
Absent Member.
Absent Member.
3071 views

assinar xml

Jump to solution

Boa dia a todos, por favor estou tentando fazer uma assinatura digital em um XML, e esta dando super certo com a ajuda do exemples que Chris Glazier e Altair Borges me enviaram, porem esta assinando com o algoritimo RSA-SHA1 mas eu preciso assinar com algoritimo RSA-SHA256, eu achei um exemplo que eu acredite que seja o que eu preciso conforme esta abaixo em C#, mas não estou conseguindo converter o Visual COBOL for Visual Studio, se alguém conseguir me ajudar ficarei muito agradecido.

 

atenciosamente

 

Renato Soares Vieira

 

using System; using System.Security.Cryptography; class RSASample { static void Main() { try { //Create a new instance of RSACryptoServiceProvider. using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { //The hash to sign. byte[] hash; using (SHA256 sha256 = SHA256.Create()) { byte[] data = new byte[] { 59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135 }; hash = sha256.ComputeHash(data); } //Create an RSASignatureFormatter object and pass it the //RSACryptoServiceProvider to transfer the key information. RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa); //Set the hash algorithm to SHA256. RSAFormatter.SetHashAlgorithm("SHA256"); //Create a signature for HashValue and return it. byte[] SignedHash = RSAFormatter.CreateSignature(hash); } } catch (CryptographicException e) { Console.WriteLine(e.Message); } } }

0 Likes
1 Solution

Accepted Solutions
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: assinar xml

Jump to solution

For the first question, do you wish to save the certificate for long-term storage on disk or in memory for the next invocation of the method from the same instance of the application?

If you store the certificate in the working-storage of the class then this is instance data and will be available to all methods and all invocations of this instance.

If you wish to store it on disk so that you can access it again, you might look at using the export and import methods of the X509Certificate class. The docs can be found here:

I am not an expert on certificates or how to manipulate them so I will not comment further on how to achieve this.

On your second question, the requirement to call managed code from a native application using COM has nothing to do with the product version being used. It is part of the Interop functionality of using native and managed code together in the same application. You would need to do this if NX was used to compile the client or Visual COBOL was used.

View solution in original post

24 Replies
Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution

using System;

using System.Security.Cryptography;

class RSASample

{

static void Main()

{

try

{

//Create a new instance of RSACryptoServiceProvider.

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())

{ //The hash to sign.

byte[] hash;

using (SHA256 sha256 = SHA256.Create())

{

byte[] data = new byte[] { 59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135 };

hash = sha256.ComputeHash(data);

}

//Create an RSASignatureFormatter object and pass it the             

//RSACryptoServiceProvider to transfer the key information.

RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa);

//Set the hash algorithm to SHA256.

RSAFormatter.SetHashAlgorithm("SHA256");

//Create a signature for HashValue and return it.

byte[] SignedHash = RSAFormatter.CreateSignature(hash);

}

}

catch (CryptographicException e)

{

Console.WriteLine(e.Message);

}

}

}

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: assinar xml

Jump to solution

The conversion for this program is as follows:

 

      $set ilusing"System""
      $set ilusing"System.Security.Cryptography" 
       class-id xmldigisign.RSASample.
       working-storage section.
       method-id main static.
       local-storage section.
       procedure division.
		   try 
              *> Create a new instance of RSACryptoServiceProvider.
		      perform using rsa as type RSACryptoServiceProvider = new RSACryptoServiceProvider
				 *>The hash to sign. 
				 declare hash as type Byte occurs any 
		         perform using sha256 as type SHA256 = type SHA256::Create
					declare #data as type Byte occurs 20 = table of
                      type Byte(59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135)
					set hash = sha256::ComputeHash(#data)
		         end-perform
 
              *> Create an RSASignatureFormatter object and pass it the               
			  *> RSACryptoServiceProvider to transfer the key information. 
				 declare RSAFormatter as type RSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rsa) 
			  *> Set the hash algorithm to SHA256. 

                 invoke RSAFormatter::SetHashAlgorithm("SHA256")
			  *> Create a signature for HashValue and return it. 
				 declare SignedHash as type Byte occurs any = RSAFormatter::CreateSignature(hash)
		      end-perform
		   catch e as type CryptographicException
		      display e::Message
		   end-try
		   goback.

       end method.

       end class.

Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution
Thank you Mr. Glazier, I'm going to test on my project.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution

Bom dia Mr. Glazier

Infelizmente não deu certo, acho que analisei errado ou estou fazendo alguma coisa errada no programa, no meu XML eu tenho que assinar com algoritmo RSA-SHA256, mas o programa esta assinando com algoritmo RSA-SHA1, por isso pensei que poderia ser aquele método que converteu para mim ontem, mas não deu certo, vou anexar o programa como estou fazendo , e o XML de como assinou e um de como deve assinar, se o Senhor poder me ajudar mais uma vez ficarei muito grato.

Atenciosamente

Renato Soares Vieira

      $set ilusing"System"
      *set ilusing"System.Windows.Forms"
      $set ilusing"System.Xml"
      $set ilusing"System.Security.Cryptography"
      $set ilusing"System.Security.Cryptography.Xml"
      $set ilusing"System.Security"
      $set ilusing"System.Security.Cryptography.X509Certificates"
      *class-id xmlsigning.Form1 is partial
      *          inherits type System.Windows.Forms.Form.
       class-id xmlsigning.SignXML.
      
       working-storage section.

       method-id main static.
       procedure division.
      
           declare XMLAssinado as string = "p:\renato\r1000-042018-assinado.xml"
           declare #XML as string = "p:\renato\r1000-042018.xml"
           declare #URI as string = "#ID1507391350000002018041911433600002"
           *>
           declare pCertificado as type X509Certificate2 = null
           try
              *> Verificar a possibilidade de passar certificado para assinatura, sem a necessidade
              *> de chamar a lista de certificado
              declare subject as string = type String::Empty
              if (pCertificado not = null)
                 set subject to pCertificado::Subject::ToString
              end-if
              declare x509Certificate as type X509Certificate2 = new X509Certificate2
              declare store as type X509Store = new X509Store("MY", type StoreLocation::CurrentUser)
              invoke store::Open(type OpenFlags::ReadOnly b-or type OpenFlags::OpenExistingOnly)
              declare collection as type X509Certificate2Collection = store::Certificates
                 as type X509Certificate2Collection
              declare collection1 as type X509Certificate2Collection
                 = collection::Find(type X509FindType::FindByTimeValid, type DateTime::Now, false)
                   as type X509Certificate2Collection
              declare collection2 as type X509Certificate2Collection
                 = collection::Find(type X509FindType::FindByKeyUsage,
                   type X509KeyUsageFlags::DigitalSignature, false) as type X509Certificate2Collection
              declare scollection as type X509Certificate2Collection
                 = type X509Certificate2UI::SelectFromCollection(collection2,
                   "Certificado(s) Digital(is) disponível(is)",
                   "Selecione o certificado digital para uso no aplicativo Perform",
                   type X509SelectionFlag::SingleSelection)
              if (scollection::Count <> 0)
            *>   invoke type MessageBox::Show("Nenhum certificado digital foi selecionado ou o "
            *>      & "certificado selecionado está com problemas.")
            *>else
                 set pCertificado to scollection[0]
                 declare documento as type XmlDocument = new XmlDocument
                 set documento::PreserveWhitespace to true
                 try
                    *> verificando elemento de referencia
                    invoke documento::Load(#XML)
                    try
                   perform using rsa as type RSACryptoServiceProvider = new RSACryptoServiceProvider
                   *>The hash to sign.
                   declare hash as type Byte occurs any
                         perform using sha256 as type SHA256 = type SHA256::Create
                        declare #data as type Byte occurs 20 = table of
                                                 type Byte(59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135)
                         set hash = sha256::ComputeHash(#data)
                         end-perform
                          *> Create an RSASignatureFormatter object and pass it the              
                    *> RSACryptoServiceProvider to transfer the key information.
                   declare RSAFormatter as type RSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rsa)
                    *> Set the hash algorithm to SHA256.
                          invoke RSAFormatter::SetHashAlgorithm("SHA256")
                    *> Create a signature for HashValue and return it.
                   declare SignedHash as type Byte occurs any = RSAFormatter::CreateSignature(hash)
                   end-perform
                       try
                          *> selecionando certificado digital baseado no subject
                          set x509Certificate to collection1[0]
                          declare docXML as type SignedXml = new SignedXml(documento)
                          set docXML::SigningKey to pCertificado::PrivateKey
                          *> Create a reference to be signed.
                          declare #reference as type Reference = new Reference()
                          set #reference::Uri to #URI
                          *> adicionando EnvelopedSignatureTransform a referencia
                          declare envelopedSigntature as type XmlDsigEnvelopedSignatureTransform
                             = new XmlDsigEnvelopedSignatureTransform
                          invoke #reference::AddTransform(envelopedSigntature)
                          declare c14Transform as type XmlDsigC14NTransform = new XmlDsigC14NTransform
                          invoke #reference::AddTransform(c14Transform)
                          invoke docXML::AddReference(#reference)
                          *> carrega o certificado em KeyInfoX509Data para adicionar a KeyInfo
                          declare keyInfo as type KeyInfo = new KeyInfo
                          invoke keyInfo::AddClause(new type KeyInfoX509Data(pCertificado))
                          set docXML::KeyInfo to keyInfo
                          invoke docXML::ComputeSignature
                          *> recuperando a representacao do XML assinado
                          declare xmlDigitalSignature as type XmlElement = docXML::GetXml
                          invoke documento::DocumentElement::AppendChild(documento::ImportNode(xmlDigitalSignature,
                             true))
                          set XMLAssinado to documento::OuterXml
                          invoke documento::Save("p:\renato\r1000-042018-assinado.xml")
                       catch ex as type Exception
                        *>invoke type MessageBox::Show("Erro: " & ex::Message)
                       end-try
                    catch ex as type Exception
                     *>invoke type MessageBox::Show("Erro: " & ex::Message)
                    end-try
                 catch caught as type Exception
                  *>invoke type MessageBox::Show("Erro ao assinar o documento - " & caught::Message)
                 end-try
              end-if
           catch caught as type Exception
            *>invoke type MessageBox::Show("XML mal formado - " & caught::Message)
           end-try.
           
       end method.
     
       end class.

 

r1000_2D00_042018_2D00_assinado.xml

r1000_2D00_042018_2D00_assinado.xml

0 Likes
Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution
boa tarde, como eu converto o comanda abaixo em c# para o visual cobol?

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),signatureMethod);

e

signer.SignedInfo.CanonicalizationMethod = signatureCanonicalizationMethod;
signer.SignedInfo.SignatureMethod = signatureMethod;

obrigado
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution

Acho melhor eu colocar o exemplo inteiro para entenderem

 

obrigado

exemplo.txt

0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: assinar xml

Jump to solution

This would look something like the following in COBOL:

 

      $set ilusing"System.Xml"
      $set ilusing"System.Security.Cryptography"
      $set ilusing"System.Security.Cryptography.Xml"
      $set ilusing"System.Security.Cryptography.X509Certificates"
      $set ilusing"System.Deployment.Internal.CodeSigning"
       class-id myclass.
       method-id SignDocument static.
       procedure division using doc as type XmlDocument
		                  returning retdoc as type XmlDocument.
       
            declare signatureCanonicalizationMethod as string = "www.w3.org/.../xml-exc-c14n
            declare signatureMethod as string = "www.w3.org/.../xmldsig-more
            declare digestMethod as string = "www.w3.org/.../xmlenc
	    declare signatureReferenceURI as string = "#_73e63a41-156d-4fda-a26c-8d79dcade713"
            invoke type CryptoConfig::AddAlgorithm(type of type RSAPKCS1SHA256SignatureDescription, signatureMethod)
	    declare signingCertificate = self::GetCertificate
	    declare signer as type SignedXml = new SignedXml(doc)
            set signer::SigningKey = signingCertificate::PrivateKey
            set signer::KeyInfo = new KeyInfo
            invoke signer::KeyInfo::AddClause(new KeyInfoX509Data(signingCertificate))
	    set signer::SignedInfo::CanonicalizationMethod = signatureCanonicalizationMethod
            set signer::SignedInfo::SignatureMethod = signatureMethod
	    declare envelopeTransform as type XmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform
            declare cn14Transform as type XmlDsigExcC14NTransform = new XmlDsigExcC14NTransform
            declare signatureReference as type Reference = new Reference
            set signatureReference::Uri = signatureReferenceURI
            invoke signatureReference::AddTransform(envelopeTransform)
            invoke signatureReference::AddTransform(cn14Transform)
            set signatureReference::DigestMethod = digestMethod
	    invoke signer::AddReference(signatureReference)
	    invoke signer::ComputeSignature
            declare signatureElement as type XmlElement = signer::GetXml
	    invoke doc::DocumentElement::AppendChild(signer::GetXml())
	    set retdoc to doc
        
	    goback.

       end method.
       method-id GetCertificate private static.
       procedure division returning retcertificate as type X509Certificate2.
       
           declare store as type X509Store = new X509Store(type StoreName::My, type StoreLocation::LocalMachine)
           invoke store::Open(type OpenFlags::ReadOnly)
           declare card as type X509Certificate2 = null
           perform varying cert as type X509Certificate2 thru store::Certificates
              if not cert::HasPrivateKey
                 exit perform cycle
              end-if
              if cert::Thumbprint::Equals("a_certain_thumb_print", type StringComparison::OrdinalIgnoreCase)
                 set card = cert
                 exit perform
	      end-if
	   end-perform
           invoke store::Close
	   set retcertificate to card
           goback.

       end method.
       end class.
    	   
Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution
Thank you mr Glazier
 
Is now just giving an error in the line below, I have to include some method to accept this type?
 
invoke type CryptoConfig::AddAlgorithm(type of type RSAPKCS1SHA256SignatureDescription, signatureMethod)
 
erro:
 
Erro COBCH0845 Unknown type 'type RSAPKCS1SHA256SignatureDescription'
 
thank you
 
Renato
 
0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: assinar xml

Jump to solution
Which version of the .NET Framework are you using?
I had to change mine to 4.61 and then I added in the References for System.Deployment v4.0.30319 and Microsoft.Build.Tasks.v4.0 v4.0.30319 as well.
0 Likes
Highlighted
Absent Member.
Absent Member.

RE: assinar xml

Jump to solution
do not know how to tell you, we are using the visual cobol for visual studio 3.0, and I am running it by itself visual cobol for visual studio.
How can I see this?
0 Likes
Highlighted
Micro Focus Expert
Micro Focus Expert

RE: assinar xml

Jump to solution
Open up the Project Properties page and look on the Application tab. This is where you set the .NET Framework version. The list of supported Frameworks can change depending on which Visual Studio version you are using. I am using VS2017.

The actual assemblies need to be added as References in the References folder. If you expand this folder and select one of the assemblies you will see its properties if your property window is displayed.
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.