Te paso el código para crear Hash con VFP9 o Superiores, saludos.
*------------------------- CNG
DECLARE LONG BCryptOpenAlgorithmProvider IN BCrypt;
LONG @phAlgorithm,;
STRING pszAlgId,;
STRING pszImplementation,;
LONG dwFlags
DECLARE LONG BCryptGetProperty IN BCrypt;
LONG hObject,;
STRING pszProperty,;
LONG @pbOutput,;
LONG cbOutput,;
LONG @pcbResult,;
LONG dwFlags
DECLARE LONG BCryptCreateHash IN BCrypt;
LONG hAlgorithm,;
LONG @phHash,;
STRING @pbHashObject,;
LONG cbHashObject,;
STRING pbSecret,;
LONG cbSecret,;
LONG dwFlags
DECLARE LONG BCryptHashData IN BCrypt;
LONG hHash,;
STRING pbInput,;
LONG cbInput,;
LONG dwFlags
DECLARE LONG BCryptFinishHash IN BCrypt;
LONG hHash,;
STRING @pbOutput,;
LONG cbOutput,;
LONG dwFlags
DECLARE LONG BCryptDestroyHash IN BCrypt;
LONG hHash
DECLARE LONG BCryptDestroyKey IN BCrypt;
LONG hKey
DECLARE LONG BCryptCloseAlgorithmProvider IN BCrypt;
LONG hAlgorithm,;
LONG dwFlags
*------------------------ Kernel32
DECLARE INTEGER GetLastError IN Kernel32
DECLARE LONG FormatMessage IN Kernel32;
LONG dwFlags,;
STRING @lpSource,;
LONG dwMessageId,;
LONG dwLanguageId,;
STRING @lpBuffer,;
LONG nSize,;
LONG Arguments
*------------------------ Constantes
#DEFINE FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
*----------------------- Main
CLEAR
*!* cFile=GETFILE("PDF")
*!* IF EMPTY(cFile)
*!* RETURN
*!* ENDIF
lcAlgoritmo = "SHA256" &&"SHA1", "SHA512", etc.
lcTextoHash = "Texto que deseo encriptar"
*lcTextoHash = FILETOSTR(cFile)
tcDataSign = GetDigestValue(lcTextoHash, lcAlgoritmo)
? "ALGORITMO: " + TRANSFORM(lcAlgoritmo)
? "Digest Value ASN1: " + TRANSFORM(tcDataSign)
? "Digest Value B64: " + TRANSFORM(STRCONV(tcDataSign,13))
? "Digest Value HEX: " + TRANSFORM(STRCONV(tcDataSign,15))
?
*-------------------------- Región de Procedures
PROCEDURE GetDigestValue(tcData, tcHashAlg)
*SET STEP ON
lnAlg = 0
nRespBCOAP = BCryptOpenAlgorithmProvider(@lnAlg, STRCONV(tcHashAlg,5)+CHR(0), NULL, 0)
IF nRespBCOAP<>0
MESSAGEBOX("ERROR AL ABRIR ALGORITMO")
RETURN ""
ENDIF
*----- Determinamos cuántos bytes necesitamos para almacenar el objeto hash
lnSizeObj = 0
lnData = 0
nRespNCGP = BCryptGetProperty(lnAlg, STRCONV("ObjectLength",5)+CHR(0), @lnSizeObj, 4, @lnData, 0)
IF nRespNCGP<>0
MESSAGEBOX("ERROR AL OBTENER PROPIEDAD DE ENCRIPTACION")
RETURN ""
ENDIF
*----- Determinamos la longitud de valor hash
lnSizeHash = 0
nRespNCGP = BCryptGetProperty(lnAlg, STRCONV("HashDigestLength",5)+CHR(0), @lnSizeHash, 4, @lnData, 0)
IF nRespNCGP<>0
MESSAGEBOX("ERROR AL OBTENER PROPIEDAD DE ENCRIPTACION")
RETURN ""
ENDIF
*----- Creamos un objeto Hash
LOCAL lnHash, lcHashObj
lnHash = 0
lcHashObj = SPACE(lnSizeObj)
nRespBCCH = BCryptCreateHash(lnAlg, @lnHash, @lcHashObj, lnSizeObj, NULL, 0, 0)
IF nRespBCCH<>0
MESSAGEBOX("ERROR AL CREAR OBJETO HASH")
RETURN ""
ENDIF
*----- Para crear el valor hash agregamos datos al objeto hash. Puede repetir este paso según sea necesario
nLenData = LEN(tcData)
nRespBCHD = BCryptHashData(lnHash, tcData, nLenData, 0)
IF nRespBCHD<>0
nRespBCHD = BCryptHashData(lnHash, tcData, nLenData, 0)
IF nRespBCHD<>0
=GetMensajeError(nRespBCHD)
RETURN ""
ENDIF
ENDIF
*----- Indicamos al objeto hash que hemos terminado. El algoritmo ahora calcula el valor de hash y lo devuelve.
lcHash = SPACE(lnSizeHash)
=BCryptFinishHash(lnHash, @lcHash, lnSizeHash, 0)
IF lnAlg<>0
BCryptCloseAlgorithmProvider(lnAlg, 0)
ENDIF
IF lnHash<>0
BCryptDestroyHash(lnHash)
ENDIF
RETURN lcHash
ENDPROC
PROCEDURE GetMensajeError(tcNumError)
IF VARTYPE(tcNumError)=="N"
lnErrorCode = tcNumError
ELSE
lnErrorCode = GetLastError()
ENDIF
lpBuffer = SPACE(128)
=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 'WINERROR.H', lnErrorCode, 0, @lpBuffer, 128 , 0)
=MESSAGEBOX(lpBuffer, 16, "Error: " + TRANSFORM(lnErrorCode,"@0"))
ENDPROC