Estoy intentando firmar un xml con COPICOM de Microsoft
Descargar de aquí https://wwws.prodemge.gov.br/component/phocadownload/category/26-capicom
Instalar, luego ejecutar CMD como administrador y ejecutar el siguiente comando para registrar COPICOM.DLL
C:\Windows\system32>regsvr32 “C:\Program Files\Microsoft CAPICOM 2.1.0.2 SDK\Lib\X86\capicom.dll”
Con éste código
- Code: Select all Expand view
#include "FiveWin.ch"
Function Main()
LOCAL ctx,cPrivateKey:= cSignXml:= encrypted:="",cTexto, cSignatureValue, cDigestValue, cPublicKey
#pragma __cstream|cPrivateKey:=%s
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEArguSG5QZ8OeX3NynUh15jxT9SHf0F854Qml+GzzDkAWV3bu1
rzpU9HBG34RYiWVRaM7032WAzpXwpjLSWOvpCooSU7UKKaeXJ85ZSVtcbXLx1nRi
PvCdXwpZesCyu9fLTASECEpLUv2f14te5pV+4w7JUlfv7Cg8hr8R0kMCsGwir6TP
XOaXLFe7bGIz/wXGfw4Wh3MuD399JwkijPnZo3aLvnSBOrBYgdpYFQDAvpEKO0fk
DeWSoxg2kvt9H//04zTSTlD0frSnvhjy4KoCor7zAybjlr7mOis0SckAId3q8pF/
wxV0xHDEzes1MuHj+ANj2p5kRYh+TFQJYGQB7QIDAQABAoIBABd0ILbNsOc5Vkoh
g/y5Uxm4ct9SptaUcLlGXQOPnyzny8fLFVMtMaiU/r/9Ji8xs5RDm1UFaSOtqfXD
kHwCIm/Upl6YXWu6lVB8aqTLhnuLS1KicWDY7OQTUXaMxCkzDcbLLv2tAVSIMAOM
WPgKukQfyHprtj2lOG7SDbU/aXvbhbTGD5bKBrcau2e7pcXNrMwXuujxrs3e6Iyl
H/F8o7p4RHI7lPc/uv/65ehFeFZIBUZNbk+lMo+b7GLDbu56DcowKe54bkuH5tf4
SX8Ud4kUkyCbVLT+5Eub0JNlYqVnTkpypj3Il1WjVXvkuOGRlmKCgT2qe+z1VImo
13Obf5ECgYEA1wN2EERlJefpDwpZUJfabGr1/+HZS5zlkXSLk3rrT0XI5achHaHl
AlbPmWba6Hq4hq+nMBV54tBTwgEpvSTRcfM74NVY1Y1y7C4uvtJLxBHfcVTMkDeC
MWqeeeBI3k9f78TLHTt5qAL0tccgaVaQIMHaobdyFeUExRdl/2+NMZkCgYEAzzjg
5BZxt3/Xzzn8yTbr9/MBJSKp2WqnEZT2RfYyn41n4RDCY7txVrou97FtS4K5FxSk
37W029/4tG/3s/RBEeyJ7vnKxvtlhVwj2GNcCbxHM7q3kXevV48fYiAqBkpiZO5a
ULgUeEuLpnaap7v0xetGLExBfjyIuU76cS4Tb3UCgYEApSYRbxk5n83rYxQN2itp
J9FYNjyhDMTsR7b+5j6Jsw/k6RBgDUSmhA9t0WQBTIPGbB1LC1HTlvVxABiomJFJ
Fn8/RMhaPV0yIlquqP8aFvWrbH83yKX6KD6+jtpI3giVpbLAWCmwne33TBAwwvgs
KBz98yzWQh7wdPot6+8gwjECgYAt6gNiZlqx9uChaM7K4qFsIeq6CLErnEcCTUg3
/jH/SjyfELCRmoGlXsFzXlvCJGfQZmGVs9Qr97dKe5idxdv5FbkGO1CjwCYhY2YJ
1xIYkiAQpSlxUNyIAQ1KF6hYFnkwteNLCU53zP1XV+YyjiHRDK1SuV61ksIUlRxG
oZfq1QKBgQCMqD/JOmfE+Kb1o5HwsRpbjhboux0UltUqx3WU0iOb36sfEo+W3AsV
ZbMOu2HGJFqLe7edORx7a/ztmuhNkEUBJXh8wc2zUvhhw80eOv32tWIAwkQQ0+Rs
1f9JmziEDr+szcAWjPCb5SWpGG46XsE0z1IwGXrHUC68eAIb0wA/Qw==
-----END RSA PRIVATE KEY-----
#pragma __endtext
*
#pragma __cstream|cSignXml:=%s
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
<DigestValue>V7cTT+m5Xdb5ViNzHVzEe4LtJFF1WO/tWrlzUZiyRlI=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
#pragma __endtext
cDigestValue := CapicomClass():HashData( cSignXml )
cSignatureValue := CapicomClass():Sign( cDigestValue, , , @cPrivateKey )
? cDigestValue
? cSignatureValue
? cDigestValue == CapicomClass():VerifySignature( cSignatureValue )
? IsValidSignatureCapicom( cDigestValue, cSignatureValue )
? cPublicKey
Return Nil
*
FUNCTION IsValidSignatureCapicom( cDigestValue, cSignatureValue )
IF cDigestValue = NIL .OR. cSignatureValue = NIL
RETURN .F.
ENDIF
RETURN CapicomClass():VerifySignature( cSignatureValue ) == cDigestValue
CREATE CLASS CapicomClass
METHOD SelectCertificate()
METHOD VerifySignature( cSignedData )
METHOD HashData( cData, nAlgorithm )
METHOD PublicKey( oCAPICOMCert )
METHOD Sign( cDigestValue, oCAPICOMcert, nEncode, cPublicKey )
ENDCLASS
METHOD SelectCertificate() CLASS CapicomClass
LOCAL oCapicom, oCertificate
oCapicom:= win_OleCreateObject( "CAPICOM.Store" )
oCapicom:Open( CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY )
BEGIN SEQUENCE WITH { || __BreakBlock() }
oCertificate := oCapicom:Certificates:Select( "Selecione um certificado digital", "Algoritmo de Assinatura SHA256RSA" )
ENDSEQUENCE
IF oCapicom:Certificates:Count() == 0
RETURN NIL
ENDIF
RETURN oCertificate:Item( 1 )
METHOD VerifySignature( cSignedData ) CLASS CapicomClass
LOCAL oCapicom
IF cSignedData == NIL
RETURN NIL
ENDIF
oCapicom := win_OleCreateObject( "CAPICOM.SignedData.1" )
oCapicom:Verify( cSignedData, .F., CAPICOM_VERIFY_SIGNATURE_ONLY )
RETURN oCapicom:Content
METHOD HashData( cData, nAlgorithm ) CLASS CapicomClass
LOCAL oCapicom, oUtil
IF cData = NIL
cData := Dtos( Date() ) + Time()
ENDIF
IF nAlgorithm = NIL
nAlgorithm := CAPICOM_HASH_ALGORITHM_SHA256
ENDIF
oUtil := win_OleCreateObject( "CAPICOM.Utilities" )
oCapicom := win_OleCreateObject( "CAPICOM.HashedData.1" )
oCapicom:Algorithm := nAlgorithm
oCapicom:Hash( cData )
RETURN oUtil:Base64Encode( outil:HexToBinary( oCapicom:Value ) )
METHOD PublicKey( oCapicomCert ) CLASS CapicomClass
LOCAL cPublicKey
cPublicKey := StrTran( /* oCapicom:Certificate:*/ oCapicomCert:Export( CAPICOM_ENCODE_BASE64 ), Chr(13) + Chr(10), "" )
RETURN cPublicKey
METHOD Sign( cDigestValue, oCAPICOMCert, nEncode, cPublicKey ) CLASS CapicomClass
LOCAL oCAPICOMSignedData, oCAPICOMSigner, oCAPICOMTimeStamp, cSignature
IF cDigestValue = NIL
RETURN NIL
ENDIF
IF nEncode = NIL
nEncode := CAPICOM_ENCODE_BASE64
ENDIF
oCAPICOMSigner := win_OleCreateObject( "CAPICOM.Signer.2" ) // versao 2
IF oCAPICOMCert = NIL
oCAPICOMCert := ::SelectCertificate()
IF oCAPICOMCert = NIL
RETURN NIL
ENDIF
oCAPICOMSigner:Certificate := oCAPICOMcert
ELSE
oCAPICOMSigner:Certificate := oCAPICOMcert:DefaultInterface
ENDIF
IF ! ( oCAPICOMSigner:Certificate:HasPrivateKey ;
.AND. Dtos( oCAPICOMSigner:Certificate:ValidFromDate ) <= Dtos( Date() ) ;
.AND. Dtos( oCAPICOMSigner:Certificate:ValidToDate ) >= Dtos( Date() ) )
RETURN NIL
ENDIF
oCAPICOMSigner:Options := CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT
cPublicKey := StrTran( oCAPICOMSigner:Certificate:Export( CAPICOM_ENCODE_BASE64 ), Chr(13) + Chr(10), "" )
oCAPICOMTimeStamp := win_OleCreateObject( "CAPICOM.Attribute" )
oCAPICOMTimeStamp:Name := CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
oCAPICOMTimeStamp:Value := hb_DateTime()
oCAPICOMSigner:AuthenticatedAttributes:Add( oCAPICOMTimeStamp )
oCAPICOMSignedData := win_OleCreateObject( "CAPICOM.SignedData.1" )
oCAPICOMSignedData:Content := cDigestValue
cSignature := oCAPICOMSignedData:Sign( oCAPICOMSigner, .F., nEncode )
RETURN cSignature
Compila perfecto,
Al ejecutar da éste error
- Code: Select all Expand view
Error description: Error BASE/1003 Variable does not exist: CAPICOM_HASH_ALGORITHM_SHA256
Stack Calls
===========
Called from: D:\Sistemas\IRRIGACION\ALMACEN\FirmaXml\PRG\FirmaXml.prg => CAPICOMCLASS:HASHDATA( 0 )
Called from: D:\Sistemas\IRRIGACION\ALMACEN\FirmaXml\PRG\FirmaXml.prg => MAIN( 0 )
Gracias por la ayuda