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
#include "FiveWin.ch"
Function Main()
LOCAL ctx,cPrivateKey:= cSignXml:= encrypted:="",cTexto, cSignatureValue, cDigestValue, cPublicKey
#pragma __cstream|cPrivateKey:=%s
[REDACTED:PRIVATE_KEY_BLOCK]
#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 cSignatureAl ejecutar da éste error
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 )Adhemar C.