vfp使用win32 API 函数加密和解密文件

文章介绍了一个使用VisualFoxPro(VFP)编写的类,该类利用win32API函数来实现文件的加密和解密。通过调用如CryptAcquireContext、CryptCreateHash等API,实现了基于MD5和RC4的加密流程。同时,文章提及了一个名为狐友会的社区,该社区接受关于VFP和其他技术的投稿,鼓励分享知识和实践经验。
摘要由CSDN通过智能技术生成

ad24696416b2d6664ced0d3fc24197b0.gif

这个简单的类使用多个win32API 函数来实现文件加密和解密。

下面是加密文件的代码示例:

LOCAL oEnc As EncryptDecrypt  
oEnc = CREATEOBJECT("EncryptDecrypt")  


WITH oEnc  
  IF NOT .GenerateKey("foxpro")  && a password  
    ? .errorno, .errormessage  
  ELSE  
    IF NOT .EncryptFile("c:\myfiles\somefile.txt",;  
      "c:\myfiles\somefile.enc")  
      ? .errorno, .errormessage  
    ENDIF  
  ENDIF  
ENDWITH

解密同样简单:

WITH oEnc  
  IF NOT .GenerateKey("foxpro")  && use same password  
    ? .errorno, .errormessage  
  ELSE  
    IF NOT .DecryptFile("c:\myfiles\somefile.enc",;  
      "c:\myfiles\somefile.enc.txt")  
      ? .errorno, .errormessage  
    ENDIF  
  ENDIF  
ENDWITH

类代码如下

#DEFINE PROV_RSA_FULL 1
#DEFINE CRYPT_VERIFYCONTEXT 0xf0000000
#DEFINE KEYLENGTH 0x00800000
#DEFINE CRYPT_EXPORTABLE 1


#DEFINE ALG_CLASS_HASH BITLSHIFT(4, 13)
#DEFINE ALG_TYPE_ANY 0
#DEFINE ALG_SID_MD5 3
#DEFINE CALG_MD5 BITOR(ALG_CLASS_HASH, ALG_TYPE_ANY, ALG_SID_MD5)


#DEFINE ALG_CLASS_DATA_ENCRYPT BITLSHIFT(3, 13)
#DEFINE ALG_TYPE_STREAM BITLSHIFT(4, 9)
#DEFINE ALG_SID_RC4 1
#DEFINE CALG_RC4 BITOR(ALG_CLASS_DATA_ENCRYPT, ALG_TYPE_STREAM, ALG_SID_RC4)


#DEFINE CALG_3DES 0x6603 && Triple DES encryption algorithm.
#DEFINE CALG_DES 0x6601 && DES encryption algorithm.


DEFINE CLASS EncryptDecrypt As Session
PROTECTED hProvider, hKey, signature
  hProvider=0
  hKey=0
  signature="VFP_ENCRYPT_DECRYPT"
  errorno=0
  errormessage=""


PROCEDURE Init
  THIS.declare
  THIS.AcquireContext


PROCEDURE Destroy
  THIS.DestroyKey
  THIS.ReleaseContext


FUNCTION EncryptFile(cSourceFile, cTargetFile) As Boolean
RETURN THIS.ProcessFile(cSourceFile, cTargetFile, .T.)


FUNCTION DecryptFile(cSourceFile, cTargetFile) As Boolean
RETURN THIS.ProcessFile(cSourceFile, cTargetFile, .F.)


PROTECTED PROCEDURE ReleaseContext
  IF THIS.hProvider <> 0
    = CryptReleaseContext(THIS.hProvider, 0)
    THIS.hProvider=0
  ENDIF


PROTECTED PROCEDURE DestroyKey
  IF THIS.hKey <> 0
    = CryptDestroyKey(THIS.hKey)
    THIS.hKey=0
  ENDIF


PROTECTED PROCEDURE AcquireContext
  THIS.ReleaseContext
  THIS.ClearError


  LOCAL hProvider, nResult
  hProvider=0


  IF CryptAcquireContext(@hProvider, NULL, NULL,;
    PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) = 0
    THIS.SetError(GetLastError(),;
      "Call to CryptAcquireContext failed.")
    RETURN .F.
  ELSE
    THIS.hProvider = m.hProvider
  ENDIF
RETURN .T.


PROCEDURE GenerateKey(cPassword)
  THIS.ClearError
  THIS.DestroyKey


  LOCAL hHash, hKey, lResult
  STORE 0 TO hHash, hKey


  IF CryptCreateHash(THIS.hProvider, CALG_MD5, 0, 0, @hHash)=0
    THIS.SetError(GetLastError(),;
      "Call to CryptCreateHash failed.")
    lResult=.F.
  ELSE
    IF CryptHashData(m.hHash, @cPassword, LEN(cPassword), 0)=0
      THIS.SetError(GetLastError(),;
        "Call to CryptHashData failed.")
      lResult=.F.
    ELSE
      IF CryptDeriveKey(THIS.hProvider, CALG_RC4,;
        m.hHash, KEYLENGTH, @hKey)=0
        THIS.SetError(GetLastError(),;
          "Call to CryptDeriveKey failed.")
        lResult=.F.
      ELSE
        THIS.hKey = m.hKey
        lResult=.T.
      ENDIF
    ENDIF
  ENDIF
  
  IF (m.hHash <> 0)
    = CryptDestroyHash(m.hHash)
  ENDIF
RETURN m.lResult


FUNCTION EncryptBuffer(cBuffer) As Boolean
  THIS.ClearError


  IF THIS.hProvider=0
    THIS.SetError(-1,;
      "Cryptographic Service Provider handle is invalid.")
    RETURN .F.
  ENDIF
  IF THIS.hKey=0
    THIS.SetError(-1,;
      "Cryptographic session key is invalid.")
    RETURN .F.
  ENDIF


  LOCAL nTextSize, nBufsize, lResult
  nTextSize = LEN(m.cBuffer)


  * call the function first time to determine
  * the correct buffer size
  = CryptEncrypt(THIS.hKey, 0, 1, 0,;
    NULL, @nTextSize, nBufsize)


  nBufsize = nTextSize
  nTextSize = LEN(m.cBuffer)
  cBuffer = PADR(cBuffer, nBufsize, CHR(0))


  IF CryptEncrypt(THIS.hKey, 0, 1, 0, @cBuffer,;
    @nTextSize, nBufsize)=0
    THIS.SetError(GetLastError(), "Call to CryptEncrypt failed.")
    RETURN .F.
  ENDIF
RETURN .T.


FUNCTION DecryptBuffer(cBuffer) As Boolean
  THIS.ClearError


  IF THIS.hProvider=0
    THIS.SetError(-1,;
      "Cryptographic Service Provider handle is invalid.")
    RETURN .F.
  ENDIF
  IF THIS.hKey=0
    THIS.SetError(-1,;
      "Cryptographic session key is invalid.")
    RETURN .F.
  ENDIF


  LOCAL nBufsize, lResult
  nBufsize = LEN(m.cBuffer)
  IF CryptDecrypt(THIS.hKey, 0, 1, 0,;
    @cBuffer, @nBufsize)=0
    THIS.SetError(GetLastError(),;
      "Call to CryptDecrypt failed.")
    RETURN .F.
  ENDIF
  cBuffer = PADR(m.cBuffer, m.nBufsize)
RETURN .T.


PROTECTED FUNCTION ProcessFile(cSourceFile,;
      cTargetFile, lEncrypt) As Boolean
  LOCAL cBuffer, ex As Exception, lResult
  TRY
    cBuffer = FILETOSTR(m.cSourceFile)
  CATCH TO ex
  ENDTRY
  
  IF VARTYPE(m.ex) = "O"
    THIS.SetError(ex.ErrorNo, ex.Message)
    RETURN .F.
  ENDIF


  IF m.lEncrypt
    cBuffer = THIS.signature + cBuffer
    lResult = THIS.EncryptBuffer(@cBuffer)
  ELSE
    lResult = THIS.DecryptBuffer(@cBuffer)
    IF lResult
      IF AT(THIS.signature, m.cBuffer) <> 1
        THIS.SetError(-1, "Invalid password")
        RETURN .F.
      ENDIF
      cBuffer = SUBSTR(cBuffer, LEN(THIS.signature)+1)
    ENDIF
  ENDIF


  IF m.lResult
    TRY
      STRTOFILE(m.cBuffer, m.cTargetFile)
    CATCH TO ex
    ENDTRY


    IF VARTYPE(m.ex) = "O"
      THIS.SetError(ex.ErrorNo, ex.Message)
      RETURN .F.
    ENDIF
    RETURN .T.
  ENDIF
RETURN .F.


PROTECTED PROCEDURE SetError(nError, cMsg)
  THIS.errorno = m.nError
  THIS.errormessage = m.cMsg


PROTECTED PROCEDURE ClearError
  THIS.SetError(0, "")


PROCEDURE declare
  DECLARE INTEGER GetLastError IN kernel32
  DECLARE INTEGER CryptDestroyHash IN advapi32 INTEGER hHash
  DECLARE INTEGER CryptDestroyKey IN advapi32 INTEGER hKey


  DECLARE INTEGER CryptCreateHash IN advapi32;
    INTEGER hProv, INTEGER Algid, INTEGER hKey,;
    INTEGER dwFlags, INTEGER @phHash


  DECLARE INTEGER CryptAcquireContext IN advapi32;
    INTEGER @hProvHandle, STRING cContainer, ;
    STRING cProvider, INTEGER nProvType, INTEGER nFlags


  DECLARE INTEGER CryptReleaseContext IN advapi32;
    INTEGER hProvHandle, INTEGER nReserved


  DECLARE INTEGER CryptHashData IN advapi32;
    INTEGER hHash, STRING @pbData,;
    LONG dwDataLen, LONG dwFlags


  DECLARE INTEGER CryptDeriveKey IN advapi32;
    INTEGER hProv, INTEGER Algid, INTEGER hBaseData,;
    LONG dwFlags, INTEGER @phKey


  DECLARE INTEGER CryptEncrypt IN advapi32;
    INTEGER hKey, INTEGER hHash, INTEGER Final,;
    LONG dwFlags, STRING @pbData,;
    LONG @pdwDataLen, LONG dwBufLen


  DECLARE INTEGER CryptDecrypt IN advapi32;
    INTEGER hKey, INTEGER hHash, INTEGER Final,;
    LONG dwFlags, STRING @pbData, LONG @pdwDataLen


ENDDEFINE

猫猫的心里话

加菲猫的VFP|狐友会社群接收投稿啦

加菲猫的VFP,用VFP不局限VFP,用VFP混合一切。无论是VFP,还是JS,还是C,只要能混合起来,都可以发表。

商业模式,销售技巧、需求规划、产品设计的知识通通可以发表。

暂定千字50元红包,,优秀的文章红包更大,一经发表,红包到手。

如何帮助使用VFP的人?

用VFP的人,有专业的,有非专业了,很多人其实是小白,问出的问题是小白,如果问题不对,我们引导他们问正确的问题。无论如何请不要嘲笑他们说帮助都不看,这么简单的问题都不会,嘲笑别人不行,而无法提出建设性答案,是很low的。

我们无论工作需要,还是有自己的软件,都是是需要真正的知识,如何让更多人学习真正的VFP知识呢,只需要点赞,在看,能转发朋友圈就更好了。

加菲猫的vfp倡导用"VFP极简混合开发,少写代码、快速出活,用VFP,但不局限于VFP,各种语言混合开发"

我已经带领一百多名会员成功掌到VFP的黑科技,进入了移动互联网时代,接下来我们要进入物联网领域。

2023年狐友会社群会员继续招募中

社群会员获取的权益有:

祺佑三层开发框架商业版(猫框),终身免费升级,终身技术支持。

开放的录播课程有:

微信小程序,微信公众号开发,H5 APP开发,Extjs BS开发,VFP面向对象进阶,VFP中间层开发。

源码类资源有:

支付组件源码,短信源码,权限组件源码,一些完整系统的源码。这个可以单独出售的,需要的可以联系我。

会员也可以实现群内资源对接,可以接分包,合作等各项商业或技术业务

d46510b44b8150195d2b48ac8079d4e4.gif

085729f607033a871ac51e641b864312.jpeg

9b34e8070870f5a20d4b86158714521f.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值