*------ Constantes CertOpenStore para: lpszStoreProvider #DEFINE CERT_STORE_PROV_SYSTEM 10#define CERT_STORE_PROV_MSG 1#define CERT_STORE_PROV_MEMORY 2#define CERT_STORE_PROV_FILE 3#define CERT_STORE_PROV_REG 4#define CERT_STORE_PROV_PKCS7 4#define CERT_STORE_PROV_SERIALIZED 6#define CERT_STORE_PROV_FILENAME_A 7#define CERT_STORE_PROV_FILENAME_W 8#define CERT_STORE_PROV_SYSTEM_A 9#define CERT_STORE_PROV_SYSTEM_W 10#DEFINE CERT_STORE_PROV_COLLECTION 11#define CERT_STORE_PROV_SYSTEM_REGISTRY_A 12#define CERT_STORE_PROV_SYSTEM_REGISTRY_W 13#define CERT_STORE_PROV_SYSTEM_REGISTRY CERT_STORE_PROV_SYSTEM_REGISTRY_W#define CERT_STORE_PROV_PHYSICAL_W 14#define CERT_STORE_PROV_PHYSICAL CERT_STORE_PROV_PHYSICAL_W#define CERT_STORE_PROV_SMART_CARD_W 15#define CERT_STORE_PROV_SMART_CARD CERT_STORE_PROV_SMART_CARD_W#define CERT_STORE_PROV_LDAP_W 16#define CERT_STORE_PROV_LDAP CERT_STORE_PROV_LDAP_W#define CERT_STORE_PROV_PKCS12 17*------ Constantes CertOpenStore para:#DEFINE PKCS_7_ASN_ENCODING 65536#DEFINE X509_ASN_ENCODING 1*------ Constantes CertOpenStore para: dwFlags#DEFINE CERT_STORE_OPEN_EXISTING_FLAG 0x00004000#DEFINE CERT_SYSTEM_STORE_LOCATION_MASK 0x00FF0000#DEFINE CERT_SYSTEM_STORE_LOCATION_SHIFT 16#DEFINE CERT_SYSTEM_STORE_CURRENT_USER_ID 1#DEFINE CERT_SYSTEM_STORE_LOCAL_MACHINE_ID 2#DEFINE CERT_SYSTEM_STORE_CURRENT_SERVICE_ID 4#DEFINE CERT_SYSTEM_STORE_SERVICES_ID 5#DEFINE CERT_SYSTEM_STORE_USERS_ID 6#DEFINE CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY_ID 7#DEFINE CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY_ID 8#DEFINE CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE_ID 9#DEFINE CERT_SYSTEM_STORE_CURRENT_USER BITLSHIFT(1,16)#DEFINE CERT_SYSTEM_STORE_LOCAL_MACHINE BITLSHIFT(2,16)#DEFINE CERT_SYSTEM_STORE_CURRENT_SERVICE BITLSHIFT(4,16)#DEFINE CERT_SYSTEM_STORE_SERVICES BITLSHIFT(5,16)#DEFINE CERT_SYSTEM_STORE_USERS BITLSHIFT(6,16)#DEFINE CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY BITLSHIFT(7,16)#DEFINE CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY BITLSHIFT(8,16)#DEFINE CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE BITLSHIFT(9,16)*------ Constantes CryptUIDlgSelectCertificateFromStore para: dwDontUseColumn#DEFINE CRYPTUI_SELECT_ISSUEDTO_COLUMN 0x000000001#DEFINE CRYPTUI_SELECT_ISSUEDBY_COLUMN 0x000000002#DEFINE CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004#DEFINE CRYPTUI_SELECT_FRIENDLYNAME_COLUMN 0x000000008#DEFINE CRYPTUI_SELECT_LOCATION_COLUMN 0x00000010#DEFINE CRYPTUI_SELECT_EXPIRATION_COLUMN 0x000000020
=SetDeclarationsApis()hStore = GetCertOpenStore("MY")IF hStore>0 lnCertContext = GetCryptUIDlgSelectCertificateFromStore(hStore) GetDecodeCertificateX509(lnCertContext) nResp = CertFreeCertificateContext(lnCertContext) nResp = CertCloseStore(hStore, 0)ENDIF
PROCEDURE GetDecodeCertificateX509() LPARAMETERS tpCertContext AS Long cCertInfo = GetStructure_CertInfo(tpCertContext) cVersion = GetVersion(cCertInfo) cSerialNumber = STRCONV(GetSerialNumber(cCertInfo),15) cSignatureAlg = GetSignatureAlgorithm(cCertInfo) cIssuer = GetIssuer(tpCertContext) tNotBefor = GetNotBefore(tpCertContext) tNotAfter = GetNotAfter(tpCertContext) cSubject = GetSubject(tpCertContext) cPublicKeyInfo = GetSubjectPublicKeyInfo(cCertInfo) bPublicKeyValue = GetSubjectPublicKeyValue(cCertInfo) cPublicKeyValue = STRCONV(bPublicKeyValue,15) cExponent = GetExponent(bPublicKeyValue) cModulos = STRCONV(GetModulus(bPublicKeyValue, SUBSTR(cPublicKeyInfo, 1, AT(";", cPublicKeyInfo)-1)),13) cCertificateType = GetCertificateType(tpCertContext) cCertificateEncoded = STRCONV(GetCertificateEncoded(tpCertContext),13) *------ Salida a TextoTEXT TO lcFileText TEXTMERGE NOSHOW ADDITIVE Versión: <<cVersion>>Número de serie: <<cSerialNumber>>Algoritmo de Firma: <<cSignatureAlg>>Emisor : <<cIssuer>>Fecha Emision: <<tNotBefor>>Fecha Caduca: <<tNotAfter>>Sujeto : <<cSubject>>Algoritmo de Clave Publica: <<cPublicKeyInfo>>Clave Pública: <<cPublicKeyValue>>Exponente: <<cExponent>>Modulus: <<cModulos>>Tipo de Certificado: <<cCertificateType>>Certificado Codificado: <<cCertificateEncoded>>ENDTEXT *------ Grabamos en archivo de texto STRTOFILE(lcFileText, ADDBS(FULLPATH(""))+"CertX509Decode.txt") MODIFY FILE ADDBS(FULLPATH(""))+"CertX509Decode.txt"ENDPROC
PROCEDURE GetCertOpenStore() LPARAMETERS tcStoreName AS String hStoreHandle = 0 lpszStoreProvider = CERT_STORE_PROV_SYSTEM_A dwEncodingType = BITOR(PKCS_7_ASN_ENCODING, X509_ASN_ENCODING) hCryptProv = 0 dwFlags = CERT_SYSTEM_STORE_CURRENT_USER pvPara = "MY" + CHR(0) hStoreHandle = CertOpenStore(lpszStoreProvider, dwEncodingType, hCryptProv, dwFlags, pvPara) RETURN hStoreHandleENDPROC
PROCEDURE GetCryptUIDlgSelectCertificateFromStore() LPARAMETERS thStore AS Long pCertContext = 0 hCertStore = thStore hWnd = _SCREEN.HWnd pwszTitle = NULL pwszDisplayString = NULL dwDontUseColumn = 0 dwFlags = 0 pvReserved = NULL pCertContext=CryptUIDlgSelectCertificateFromStore(hCertStore, hWnd, pwszTitle, pwszDisplayString, dwDontUseColumn, dwFlags, pvReserved) RETURN pCertContextENDPROC
PROCEDURE GetStructure_CertInfo() LPARAMETERS tpCertContext AS Long lbCertInfo = SYS(2600, tpCertContext, 20) lpCertInfo = CTOBIN(SUBSTR(lbCertInfo, 13, 4), "4RS") lcCertInfo = SYS(2600, lpCertInfo, 112) RETURN lcCertInfoENDPROC
PROCEDURE GetVersion() LPARAMETERS tcCertInfo AS String lpVersion1 = CTOBIN(SUBSTR(tcCertInfo,1,4),"4RS") RETURN lpVersion1 + 1ENDPROC
PROCEDURE GetSerialNumber() LPARAMETERS tcCertInfo AS String lbSerialNumber = SUBSTR(tcCertInfo, 5, 8) lnSerialNumber = CTOBIN(SUBSTR(lbSerialNumber, 1, 4),"4RS") lpSerialNumber = CTOBIN(SUBSTR(lbSerialNumber, 5, 4),"4RS") lcSerialNumber = SYS(2600, lpSerialNumber, lnSerialNumber) lcSerialRevers = GetReverseString(lcSerialNumber) RETURN lcSerialReversENDPROC
PROCEDURE GetSignatureAlgorithm() LPARAMETERS tcCertInfo AS String lbSignAlgorithm = SUBSTR(tcCertInfo, 13, 12) lpAlgorithmOID = CTOBIN(SUBSTR(lbSignAlgorithm, 1, 4),"4RS") lnAlgorithmPara = CTOBIN(SUBSTR(lbSignAlgorithm, 5, 4),"4RS") lpAlgorithmPara = CTOBIN(SUBSTR(lbSignAlgorithm, 9, 4),"4RS") lcAlgorithmOID = SYS(2600, lpAlgorithmOID, GetStrLenA(lpAlgorithmOID)) lcAlgorithmPara = STRCONV(SYS(2600, lpAlgorithmPara, lnAlgorithmPara),15) RETURN lcAlgorithmOID +"; " + lcAlgorithmParaENDPROC
PROCEDURE GetIssuer() LPARAMETERS tpCertContext AS Long lcIssuer = "" lpCertInfo = CTOBIN(SYS(2600, tpCertContext + 12, 4), "4RS") IF lpCertInfo > 0 lcIssuer = GetCertNameToString(lpCertInfo + 24) ENDIF RETURN lcIssuerENDPROC
PROCEDURE GetNotBefore() LPARAMETERS tpCertContext AS Long ltNotBefore = CTOT("") lpCertInfo = CTOBIN(SYS(2600, tpCertContext+ 12, 4), "4RS") IF lpCertInfo > 0 lpNotBefore = lpCertInfo + 32 lpSystemTime = SPACE(16) IF FileTimeToSystemTime(lpNotBefore, @lpSystemTime)#0 ltNotBefore = GetBinatyToDateTime(lpSystemTime) ENDIF ENDIF RETURN ltNotBeforeENDPROC
PROCEDURE GetNotAfter() LPARAMETERS tpCertContext AS Long ltNotAfter = CTOT("") lpCertInfo = CTOBIN(SYS(2600, tpCertContext + 12, 4), "4RS") IF lpCertInfo > 0 lpNotAfter = lpCertInfo + 40 lpSystemTime = SPACE(16) IF FileTimeToSystemTime(lpNotAfter, @lpSystemTime)#0 ltNotAfter = GetBinatyToDateTime(lpSystemTime) ENDIF ENDIF RETURN ltNotAfter ENDPROC
PROCEDURE GetSubject() LPARAMETERS tpCertContext AS Long lcSubjectStr = "" IF tpCertContext>0 lpCertInfo = CTOBIN(SYS(2600, tpCertContext + 12, 4), "4RS") IF lpCertInfo > 0 lcSubjectStr=GetCertNameToString(lpCertInfo + 48) ENDIF ENDIF RETURN lcSubjectStrENDPROC
PROCEDURE GetSubjectPublicKeyInfo() LPARAMETERS tcCertInfo AS String lbSubjectPubKey = SUBSTR(tcCertInfo,57,12) lpAlgorithmPKey = CTOBIN(SUBSTR(lbSubjectPubKey, 1, 4),"4RS") lnAlgorithmPara = CTOBIN(SUBSTR(lbSubjectPubKey, 5, 4),"4RS") lpAlgorithmPara = CTOBIN(SUBSTR(lbSubjectPubKey, 9, 4),"4RS") lcAlgorithmPKey = SYS(2600, lpAlgorithmPKey, GetStrLenA(lpAlgorithmPKey)) lcAlgorithmPara = STRCONV(SYS(2600, lpAlgorithmPara, lnAlgorithmPara),15) RETURN lcAlgorithmPKey +"; "+ lcAlgorithmParaENDPROC
PROCEDURE GetSubjectPublicKeyValue() LPARAMETERS tcCertInfo AS String lbPublicKey = SUBSTR(tcCertInfo,69,8) lnPublicKey = CTOBIN(SUBSTR(lbPublicKey, 1, 4),"4RS") lpPublicKey = CTOBIN(SUBSTR(lbPublicKey, 5, 4),"4RS") lcPublicKey = SYS(2600, lpPublicKey, lnPublicKey) RETURN lcPublicKeyENDPROC
PROCEDURE GetExponent() LPARAMETERS tbPublicKey AS String cAsn1Exponent = RIGHT(tbPublicKey,3) cB64Exponent = STRCONV(cAsn1Exponent,13) RETURN cB64ExponentENDPROC
PROCEDURE GetModulus() PARAMETERS tbPublicKey AS String, tcIdAlgorithm AS String nLenPubK=LEN(tbPublicKey) IF VARTYPE(tcIdAlgorithm)<>"C" tcIdAlgorithm="1.2.840.113549.1.1.5" ENDIF cAsn1Modulus=tbPublicKey DO CASE CASE LEFT(tcIdAlgorithm,13)<>"1.2.840.10045" AND LEFT(tcIdAlgorithm,9)<>"1.3.132.0" *----- Algorithm RSA Cryptography (Rivest, Shamir y Adleman) nIniChr=AT(CHR(0),tbPublicKey)+1 nEndChr=AT(STRCONV("0203010001",16), tbPublicKey) IF nEndChr==0 nEndChr=AT(STRCONV("020103",16), tbPublicKey) ENDIF IF nIniChr>nEndChr bIni512=STRCONV("30470240",16) nIniChr=AT(bIni512,tbPublicKey)+LEN(bIni512) ENDIF cAsn1Modulus=SUBSTR(tbPublicKey, nIniChr, nEndChr-nIniChr) CASE LEFT(tcIdAlgorithm,13)=="1.2.840.10045" OR LEFT(tcIdAlgorithm,9)=="1.3.132.0" *----- Algorithm ECC Cryptography (Elliptic Curve Cryptography) cAsn1Modulus=tbPublicKey ENDCASE RETURN cAsn1ModulusENDPROC
PROCEDURE GetCertificateType() LPARAMETERS tpCertContext AS Long lcCertType = "" IF tpCertContext>0 lcCertContext = SYS(2600, tpCertContext, 20) lnCertType = CTOBIN(SUBSTR(lcCertContext, 1, 4), "4RS") lcCertType = IIF(lnCertType=1, "X509Certificate", "PKCS7Certificate") ENDIF RETURN lcCertTypeENDPROC
PROCEDURE GetCertificateEncoded() LPARAMETERS tpCertContext AS Long lbCertEncoded = "" IF tpCertContext>0 lcCertContext = SYS(2600, tpCertContext, 20) lpCertEncoded = CTOBIN(SUBSTR(lcCertContext, 5, 4), "4RS") lnCertEncoded = CTOBIN(SUBSTR(lcCertContext, 9, 4), "4RS") lbCertEncoded = SYS(2600, lpCertEncoded, lnCertEncoded) ENDIF RETURN lbCertEncodedENDPROC
PROCEDURE GetReverseString() LPARAMETERS tcStringToReverse AS String LOCAL lcReverse, nRev lcReverse="" FOR nRev = LEN(tcStringToReverse) TO 1 STEP -1 lcReverse = lcReverse + SUBSTR(tcStringToReverse, nRev,1) NEXT RETURN lcReverseENDPROC
PROCEDURE GetCertNameToString() LPARAMETERS pbCertNameBlob AS Long *----- Valores posibles para wDwStrType, pueden ser la suma de varios SIMPLENAMESTR = 1 OIDNAMESTR = 2 X500NAMESTR = 3 SEMICOLONFLAG = 0x40000000 CRLFFLAG = 0x08000000 NOPLUSFLAG = 0x20000000 NOQUOTINGFLAG = 0x10000000 NAMEREVERSE = 0x02000000 DISABLEIE4UTF8 = 0x00010000 ENABLEPUNYCODE = 0x00200000 *----- Asignamos valores a Parametros nCertEncodTyp = BITOR(PKCS_7_ASN_ENCODING, X509_ASN_ENCODING) cpName = pbCertNameBlob nDwStrType = BITOR(X500NAMESTR, OIDNAMESTR, NAMEREVERSE, SEMICOLONFLAG) lcNameDecoded = "" lnNameLong = 0 *----- Intento 1, obtenemos longitud de cadena lnNameLong = CertNameToStr(nCertEncodTyp, cpName, nDwStrType, @lcNameDecoded, @lnNameLong) IF lnNameLong <> 0 *----- Intento 2, conociendo longitud de cadena, Obtenemos el nombre decodificado lcNameDecoded= REPLICATE(CHR(0), lnNameLong) CertNameToStr(nCertEncodTyp, cpName, nDwStrType, @lcNameDecoded, @lnNameLong) ENDIF *----- La función devuelve una cadena terminada en nulo, quitamos el CHR(0) que represanta nulo RETURN STRTRAN(lcNameDecoded, CHR(0), "")ENDPROC
PROCEDURE GetBinatyToDateTime() LPARAMETERS tbSystemTime AS String ltDateTime = "" IF !EMPTY(tbSystemTime) wYear = CTOBIN(SUBSTR(tbSystemTime,1,2),"2RS") wMonth = CTOBIN(SUBSTR(tbSystemTime,3,2),"2RS") wDayWeek = CTOBIN(SUBSTR(tbSystemTime,5,2),"2RS") wDay = CTOBIN(SUBSTR(tbSystemTime,7,2),"2RS") wHour = CTOBIN(SUBSTR(tbSystemTime,9,2),"2RS") wMinute = CTOBIN(SUBSTR(tbSystemTime,11,2),"2RS") wSecond = CTOBIN(SUBSTR(tbSystemTime,13,2),"2RS") wMilSec = CTOBIN(SUBSTR(tbSystemTime,15,2),"2RS") ltDateTime = DATETIME(wYear, wMonth, wDay, wHour, wMinute, wSecond) ENDIF RETURN ltDateTimeENDPROC
PROCEDURE SetDeclarationsApis() DECLARE LONG CertOpenStore IN Crypt32; LONG lpszStoreProvider,; LONG dwEncodingType,; LONG hCryptProv,; LONG dwFlags,; STRING pvPara DECLARE LONG CryptUIDlgSelectCertificateFromStore IN Cryptui; LONG hCertStore,; LONG hWnd, ; STRING @pwszTitle, ; STRING @pwszDisplayString, ; LONG dwDontUseColumn, ; LONG dwFlags,; STRING pvReserved
DECLARE LONG CertNameToStr IN Crypt32; LONG dwCertEncodingType, ; LONG pName, ; LONG dwStrType, ; STRING @psz, ; LONG csz
DECLARE LONG CertFreeCertificateContext IN Crypt32; LONG pCertContext
DECLARE LONG CertCloseStore IN Crypt32; LONG hCertStore,; LONG dwFlags
*------ Kernel32 DECLARE LONG FileTimeToSystemTime IN Kernel32; LONG lpFileTime,; STRING @lpSystemTime *------ Determina la longitud de un puntero, no devuelve en caracter null de finalización DECLARE LONG lstrlenA IN Kernel32 AS GetStrLenA; LONG lpString
DECLARE LONG lstrlenW IN Kernel32 AS GetStrLenW; LONG lpString ENDPROC
Aquí una captura del código, ejecutando y devolviendo datos, en este caso decodifico un certificado X509 creado en Fox a puro código. Con Fox y CryptoApi podemos crear certificados autofirmados, y certificados de entidad final, y firmar esos certificados con nuestro certificado de raíz también creado en Fox.

Enorme aporte!!De que manera podría obtener la fecha de validez de un certificado .pfx?Saludos.César.-
Fernando, cómo puedo procesar un archivo extensión crt con esta Api?
Saludos
Esteban
*------------ Constantes Certificate Type#DEFINE X509_ASN_ENCODING 1 #DEFINE PKCS_7_ASN_ENCODING 0x00010000*------------ Constantes CryptStringToBinary, para: dwFlags #DEFINE CRYPT_STRING_BASE64HEADER 0x00000000#DEFINE CRYPT_STRING_BASE64 0x00000001#DEFINE CRYPT_STRING_BINARY 0x00000002#DEFINE CRYPT_STRING_BASE64REQUESTHEADER 0x00000003#DEFINE CRYPT_STRING_HEX 0x00000004#DEFINE CRYPT_STRING_HEXASCII 0x00000005#DEFINE CRYPT_STRING_BASE64_ANY 0x00000006#DEFINE CRYPT_STRING_ANY 0x00000007#DEFINE CRYPT_STRING_HEX_ANY 0x00000008#DEFINE CRYPT_STRING_BASE64X509CRLHEADER 0x00000009#DEFINE CRYPT_STRING_HEXADDR 0x0000000a#DEFINE CRYPT_STRING_HEXASCIIADDR 0x0000000b#DEFINE CRYPT_STRING_HEXRAW 0x0000000c#DEFINE CRYPT_STRING_STRICT 0x20000000
=SetDeclarationsAPI()cFileCer=GETFILE("CER,CRT,PEM")IF EMPTY(cFileCer) RETURNENDIFlnCertContext=GetImportCerCrtPemDer(cFileCer)? lnCertContext
PROCEDURE GetImportCerCrtPemDer() PARAMETERS tcFilePemOrCer AS String pCertContext = 0 cStringCert=FILETOSTR(tcFilePemOrCer) IF !EMPTY(cStringCert) *----- Decodificamos la cadena para ASN1 pbCertEncoded = GetCryptStringToBinary(cStringCert) IF !EMPTY(pbCertEncoded) dwCertEncodingType = BITOR(PKCS_7_ASN_ENCODING, X509_ASN_ENCODING) cbCertEncoded = LEN(pbCertEncoded) pCertContext = CertCreateCertificateContext(dwCertEncodingType, pbCertEncoded, cbCertEncoded) ELSE MESSAGEBOX("No se pudo decodicar el archivo", 16, _SCREEN.Caption) ENDIF ELSE MESSAGEBOX("El archivo esta vacio", 16, _SCREEN.Caption) ENDIF RETURN pCertContextENDPROC
PROCEDURE GetCryptStringToBinary() PARAMETERS tcStrToDecode AS String *------- Convertimos binarios a Asn1 pszString = tcStrToDecode cchString = LEN(pszString) pbBinary="" dwBufferLen=0 pdwSkip=0 pdwFlags=0 nResp = CryptStringToBinary(pszString, cchString, CRYPT_STRING_ANY, NULL, @dwBufferLen, @pdwSkip, @pdwFlags) pbBinary = SPACE(dwBufferLen) DO CASE CASE pdwFlags=0 *------- Base64, with certificate beginning and ending headers. CryptStringToBinary(pszString, cchString, CRYPT_STRING_BASE64HEADER, @pbBinary, @dwBufferLen, @pdwSkip, @pdwFlags) CASE pdwFlags=1 *------- Base64, without headers. CryptStringToBinary(pszString, cchString, CRYPT_STRING_BASE64, @pbBinary, @dwBufferLen, @pdwSkip, @pdwFlags) CASE pdwFlags=2 *------- Pure binary copy. pbCertEncoded=tcStrToDecode ENDCASE RETURN pbBinaryENDPROC
PROCEDURE SetDeclarationsAPI() DECLARE LONG CertCreateCertificateContext IN Crypt32; LONG dwCertEncodingType,; STRING pbCertEncoded,; LONG cbCertEncoded
DECLARE LONG CryptStringToBinary IN Crypt32; STRING @pszString, ; LONG cchString, ; LONG dwFlags,; STRING @pbBinary, ; LONG @pcbBinary,; LONG @pdwSkip, ; LONG @pdwFlags
ENDPROC
--
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/dd70e3a6-0cd2-4d8a-9503-89845f8ab06e%40googlegroups.com.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publice...@googlegroups.com.
Respondo la duda del hash, es un hash al archivo, no a la ruta, por lo tanto con FILETOSTR obtener el contenido del archivo y pasarlo a la función GetDigestValue con el parámetro "SHA1" al resultado del hash lo convertimos a base64 con STRCONV(cadena,13).Ahora otra duda, veo que hay 3 certificados en el nodo KeyInfo... eso suele pasar porque se pasa la ruta del p12/pfx a la librería o programa externo, y esa librería coloca cuanto certificado encuentre en el contenedor p12, si encuentra 20 certificado colocara los 20 así de errático... porque normalmente solo va el certificado del firmante, dentro del certificado del firmante va la información de la ruta de la cadena de confianza, es por eso que no es necesario incluir los certificados de CA... eso hasta donde he leído es así, ahora no se si el formato o la norma allá sea esa, de incluir todos los certificado. Que piensas tu? como son los comprobantes de FE que emiten los demás contribuyentes? también van con 3 certificados?
--
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/b1b47120-de77-4e8d-9482-3051731afb84%40googlegroups.com.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publice...@googlegroups.com.
--
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/0ca87706-6018-44c2-b8d2-ea28f66c359a%40googlegroups.com.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publice...@googlegroups.com.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/a614384b-3439-402f-a0b1-c23e6d968154%40googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/a614384b-3439-402f-a0b1-c23e6d968154%40googlegroups.com.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/eff55916-a197-4d1f-9093-95453e0031df%40googlegroups.com.