这个简单的类使用多个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中间层开发。
源码类资源有:
支付组件源码,短信源码,权限组件源码,一些完整系统的源码。这个可以单独出售的,需要的可以联系我。
会员也可以实现群内资源对接,可以接分包,合作等各项商业或技术业务