#INCLUDE ONCE "BCrypt.inc"
MACRO ALG_ID = DWORD
'//-----------------------------------------------------------------------
'// 生成MD5密码 16位
'//-----------------------------------------------------------------------
FUNCTION MD5_ComputeHash(BYVAL pass AS STRING) AS STRING
LOCAL i AS LONG
LOCAL hCryptProv AS DWORD
LOCAL hCryptHash AS DWORD
LOCAL lcHashValue AS DWORD
LOCAL lnHashSize AS DWORD
LOCAL lnStatus AS LONG
LOCAL HashLen AS DWORD
LOCAL p AS BYTE PTR
LOCAL md5 AS STRING
'// 获得指定CSP的密钥容器的句柄
lnStatus = CryptAcquireContext(hCryptProv, BYVAL %NULL, BYVAL %NULL, %PROV_RSA_FULL, %CRYPT_VERIFYCONTEXT)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//创建一个HASH对象, 指定HASH算法
lnStatus = CryptCreateHash(hCryptProv, %CALG_MD5, 0, 0, hCryptHash)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//将要计算 md5 值的数据提供给这个哈希对象中
lnStatus = CryptHashData(hCryptHash, BYVAL STRPTR(pass), LEN(pass), 0)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//获取HASH结果的大小
lnHashSize = LEN(pass)
lnStatus = CryptGetHashParam(hCryptHash, %HP_HASHSIZE, HashLen, lnHashSize, 0)
IF(lnStatus<>1 OR HashLen=0) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
p = VARPTR(HashLen)
HashLen = @p
'GLOBALMEM ALLOC HashLen TO lcHashValue '分配缓存空间
DIM buf(HashLen-1) AS BYTE '分配缓存空间
'//获取HASH结果
lnStatus = CryptGetHashParam(hCryptHash, %HP_HASHVAL, BYVAL VARPTR(buf(0)), HashLen, 0)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
p = VARPTR(lcHashValue)
FOR i=0 TO HashLen-1
md5 = md5 + CHR$(buf(i))
NEXT i
ERASE buf()
'GLOBALMEM FREE lcHashValue TO lcHashValue
IF(hCryptHash>0) THEN CryptDestroyHash(hCryptHash)
IF(hCryptProv>0) THEN CryptReleaseContext(hCryptProv, 0)
FUNCTION = md5
END FUNCTION
'//-----------------------------------------------------------------------
'// 生成SHA1密码 32位 20位
'//-----------------------------------------------------------------------
FUNCTION SHA1_ComputeHash(BYVAL pass AS STRING) AS STRING
LOCAL i AS LONG
LOCAL VersionInformation AS OSVERSIONINFOW
LOCAL CSP_NAME AS STRING
LOCAL hCryptProv AS DWORD
LOCAL hCryptHash AS DWORD
LOCAL lnHashSize AS DWORD
LOCAL lnStatus AS LONG
LOCAL HashLen AS DWORD
LOCAL p AS BYTE PTR
LOCAL sha1 AS STRING
GetVersionEx(VersionInformation)
CSP_NAME = $$MS_ENH_RSA_AES_PROV_XP_W
IF VersionInformation.dwMajorVersion<>5 THEN
CSP_NAME = $$MS_ENH_RSA_AES_PROV_W
END IF
'// 获得指定CSP的密钥容器的句柄
lnStatus = CryptAcquireContext(hCryptProv, BYVAL %NULL, MS_ENH_RSA_AES_PROV, %PROV_RSA_AES, %CRYPT_VERIFYCONTEXT)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//创建一个HASH对象, 指定HASH算法
lnStatus = CryptCreateHash(hCryptProv, %CALG_SHA1, BYVAL %NULL, BYVAL %NULL, hCryptHash)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//计算HASH数据
lnStatus = CryptHashData(hCryptHash, BYVAL STRPTR(pass), LEN(pass), 0)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//获取HASH结果的大小
lnHashSize = LEN(pass)
lnStatus = CryptGetHashParam(hCryptHash, %HP_HASHSIZE, HashLen, lnHashSize, 0) '获取哈希值缓存大小
IF(lnStatus<>1 OR HashLen=0) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
p = VARPTR(HashLen)
HashLen = @p
DIM buf(HashLen-1) AS BYTE '分配缓存空间
'//获取HASH结果
lnStatus = CryptGetHashParam(hCryptHash, %HP_HASHVAL, BYVAL VARPTR(buf(0)), HashLen, 0)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
FOR i=0 TO UBOUND(buf)
sha1 = sha1 + CHR$(buf(i))
NEXT i
ERASE buf()
IF(hCryptHash>0) THEN CryptDestroyHash(hCryptHash)
IF(hCryptProv>0) THEN CryptReleaseContext(hCryptProv, 0)
FUNCTION = sha1
END FUNCTION
'//-----------------------------------------------------------------------
'// 生成SHA256密码 32位
'//-----------------------------------------------------------------------
FUNCTION SHA256_ComputeHash(BYVAL pass AS STRING) AS STRING
LOCAL i AS LONG
LOCAL VersionInformation AS OSVERSIONINFOW
LOCAL CSP_NAME AS STRING
LOCAL hCryptProv AS DWORD
LOCAL hCryptHash AS DWORD
LOCAL lnHashSize AS DWORD
LOCAL lnStatus AS LONG
LOCAL HashLen AS DWORD
LOCAL p AS BYTE PTR
LOCAL sha256 AS STRING
GetVersionEx(VersionInformation)
CSP_NAME = $$MS_ENH_RSA_AES_PROV_XP_W
IF VersionInformation.dwMajorVersion<>5 THEN
CSP_NAME = $$MS_ENH_RSA_AES_PROV_W
END IF
'// 获得指定CSP的密钥容器的句柄
lnStatus = CryptAcquireContext(hCryptProv, BYVAL %NULL, MS_ENH_RSA_AES_PROV, %PROV_RSA_AES, %CRYPT_VERIFYCONTEXT)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//创建一个HASH对象, 指定HASH算法
lnStatus = CryptCreateHash(hCryptProv, %CALG_SHA_256, BYVAL %NULL, BYVAL %NULL, hCryptHash)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//计算HASH数据
lnStatus = CryptHashData(hCryptHash, BYVAL STRPTR(pass), LEN(pass), 0)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//获取HASH结果的大小
lnHashSize = LEN(pass)
lnStatus = CryptGetHashParam(hCryptHash, %HP_HASHSIZE, HashLen, lnHashSize, 0) '获取哈希值缓存大小
IF(lnStatus<>1 OR HashLen=0) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
p = VARPTR(HashLen)
HashLen = @p
DIM buf(HashLen-1) AS BYTE '分配缓存空间
'//获取HASH结果
lnStatus = CryptGetHashParam(hCryptHash, %HP_HASHVAL, BYVAL VARPTR(buf(0)), HashLen, 0)
IF(lnStatus<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
FOR i=0 TO UBOUND(buf)
sha256 = sha256 + CHR$(buf(i))
NEXT i
ERASE buf()
IF(hCryptHash>0) THEN CryptDestroyHash(hCryptHash)
IF(hCryptProv>0) THEN CryptReleaseContext(hCryptProv, 0)
FUNCTION = sha256
END FUNCTION
'//-----------------------------------------------------------------------
'// 生成AES密码 32位
'//-----------------------------------------------------------------------
FUNCTION AES_ComputeHash(BYVAL buf AS STRING, BYVAL pass AS STRING, BYVAL Algid AS ALG_ID) AS STRING
LOCAL i AS LONG
LOCAL hCryptProv AS DWORD
LOCAL hCryptHash AS DWORD
LOCAL hCryptKey AS DWORD
LOCAL bRet AS LONG
LOCAL pData AS BYTE PTR
LOCAL aes AS STRING
LOCAL dwDataLength, dwBufferLength, dwKeyLength AS DWORD
'// 获得指定CSP的密钥容器的句柄
bRet = CryptAcquireContext(hCryptProv, BYVAL %NULL, BYVAL %NULL, %PROV_RSA_AES, %CRYPT_VERIFYCONTEXT)
IF(bRet<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//创建一个HASH对象, 指定HASH算法
bRet = CryptCreateHash(hCryptProv, %CALG_MD5, BYVAL %NULL, 0, hCryptHash)
IF(bRet<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//计算HASH数据
bRet = CryptHashData(hCryptHash, BYVAL STRPTR(pass), LEN(pass), 0)
IF(bRet<>1) THEN
FUNCTION = ""
EXIT FUNCTION
END IF
'//生成加密hCryptKey
SELECT CASE Algid
CASE %CALG_AES_128
bRet = CryptDeriveKey(hCryptProv, %CALG_AES_128, hCryptHash, %CRYPT_EXPORTABLE, hCryptKey) '16 * 8
IF bRet>0 THEN MSGBOX "128"
CASE %CALG_AES_192
bRet = CryptDeriveKey(hCryptProv, %CALG_AES_192, hCryptHash, %CRYPT_EXPORTABLE, hCryptKey) '24 * 8
IF bRet>0 THEN MSGBOX "192"
CASE %CALG_AES_256
bRet = CryptDeriveKey(hCryptProv, %CALG_AES_256, hCryptHash, %CRYPT_EXPORTABLE, hCryptKey) '32 * 8
IF bRet>0 THEN MSGBOX "256"
END SELECT
pData = STRPTR(buf)
dwDataLength = LEN(buf)+1
dwBufferLength = %MAX_PATH
bRet = CryptEncrypt(hCryptKey, BYVAL %NULL, %TRUE, 0, pData, dwDataLength, dwBufferLength)
'bRet = CryptDecrypt(hCryptKey, BYVAL %NULL, %TRUE, 0, pData, BYREF dwDataLength)
FOR i=0 TO dwDataLength-1
aes = aes + CHR$(@pData[i])
NEXT i
IF(hCryptKey>0) THEN CryptDestroyKey(hCryptKey)
IF(hCryptHash>0) THEN CryptDestroyHash(hCryptHash)
IF(hCryptProv>0) THEN CryptReleaseContext(hCryptProv, 0)
FUNCTION = aes
END FUNCTION
'//-----------------------------------------------------------------------
'// 生成CNG_MD5密码 16位
'//-----------------------------------------------------------------------
FUNCTION CNG_MD5_ComputeHash(BYVAL PassWord AS STRING) AS STRING
LOCAL i AS LONG
LOCAL bRet AS LONG
LOCAL hCryptProv AS DWORD
LOCAL hCryptHash AS DWORD
LOCAL cbHashObject AS DWORD
LOCAL cbHash AS DWORD
LOCAL cbData AS DWORD
LOCAL pbHashObject AS BYTE PTR
LOCAL pbHash AS BYTE PTR
LOCAL Md5Key AS STRING
hCryptProv = %NULL
hCryptHash = %NULL
cbHash = 0
cbHashObject = %NULL
cbData = 0
bRet = BCryptOpenAlgorithmProvider(hCryptProv, $$BCRYPT_MD5_ALGORITHM, BYVAL %NULL, 0) '加载MD5算法
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
bRet = BCryptGetProperty(hCryptProv, $$BCRYPT_OBJECT_LENGTH, BYREF cbHashObject, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbHashObject = HeapAlloc(GetProcessHeap(), 0, cbHashObject)
IF pbHashObject = %NULL THEN
GOTO Cleanup
END IF
bRet = BCryptCreateHash(hCryptProv, hCryptHash, pbHashObject, cbHashObject, BYVAL %NULL, 0, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
bRet = BCryptGetProperty(hCryptProv, $$BCRYPT_HASH_LENGTH, BYREF cbHash, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbHash = HeapAlloc(GetProcessHeap(), 0, cbHash)
IF pbHash = %NULL THEN
GOTO Cleanup
END IF
LOCAL pbInput AS BYTE PTR
pbInput = STRPTR(PassWord)
bRet = BCryptHashData(hCryptHash, pbInput, LEN(PassWord), 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
'将加密的MD5密码存放至pbHash地址,cbHash缓存区为大小
bRet = BCryptFinishHash(hCryptHash, pbHash, cbHash, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
FOR i=0 TO cbHash-1
Md5Key = Md5Key + CHR$(@pbHash[i])
NEXT i
Cleanup:
IF(pbHashObject) THEN HeapFree(GetProcessHeap(), 0, pbHashObject)
IF(pbHash) THEN HeapFree(GetProcessHeap(), 0, pbHash)
IF(hCryptHash) THEN BCryptDestroyHash(hCryptHash)
IF(hCryptProv) THEN BCryptCloseAlgorithmProvider(hCryptProv,0)
FUNCTION = Md5Key
END FUNCTION
'//------------------------------------------------------------------------------------------
'// s = "FXCM-USDDemo02 - FXCM Australia Pty. Limited"
'// Md5Key = CNG_MD5_ComputeHash("g4hpfwm")
'// s1 = CNG_AES_ComputeEncrypt(s, Md5Key, CryptKey, CNG_AES_128)
'// s2 = CNG_AES_ComputeDecrypt(s1, Md5Key, CryptKey, CNG_AES_128)
'//------------------------------------------------------------------------------------------
'// 明文加密
'// bu_data 数据源
'// Private_Key长度必须为16字节
'// Public_Key指定公匙长度: 16,24,32字节
'// Algid 为指定加密方式: CNG_AES_128位, CNG_AES_192位, CNG_AES_256位 除以8等于对应字节数
'//------------------------------------------------------------------------------------------
FUNCTION CNG_AES_ComputeEncrypt(BYVAL buf_data AS STRING, BYVAL Private_Key AS STRING, BYVAL Public_Key AS STRING, BYVAL Algid AS DWORD) AS STRING
LOCAL i AS LONG
LOCAL bRet AS LONG
LOCAL hCryptProv AS DWORD
LOCAL hCryptKey AS DWORD '密匙句柄
LOCAL cbKeySize AS DWORD '公匙长度
LOCAL pbKeyObject AS BYTE PTR '存放公匙地址指针
LOCAL cbBlockSize AS DWORD '区块大小
LOCAL pbBlockObject AS BYTE PTR '区块指针
LOCAL cbPlainText AS DWORD '明文长度
LOCAL pbPlainText AS BYTE PTR '明文指针
LOCAL cbCipherText AS DWORD '密文长度
LOCAL pbCipherText AS BYTE PTR '密文指针
LOCAL pbSecret AS BYTE PTR '公钥算法地址
LOCAL cbSecret AS DWORD 'AES算法类型大小 16,24,32
LOCAL cbData AS DWORD
LOCAL cbc_mode AS WSTRING
LOCAL aes AS STRING
LOCAL Md5Key AS STRING
'Md5Key = CNG_MD5_ComputeHash(Private_Key) '用户密码生成的MD5 Private_Key
'dim PrivateKey(len(Md5Key)-1) as byte at strptr(Md5Key)
'dim PublicKey(len(Public_Key)-1) as byte at strptr(Public_Key)
hCryptProv = %NULL
hCryptKey = %NULL
pbBlockObject = %NULL
pbKeyObject = %NULL
pbPlainText = %NULL
pbCipherText = %NULL
pbCipherText = %NUll
cbBlockSize = 0
cbKeySize = 0
cbPlainText = 0
cbCipherText = 0
cbData = 0
IF LEN(Private_Key) <> 16 AND (Algid <> 128 OR Algid <> 192 OR Algid <> 256) THEN
GOTO Cleanup
END IF
bRet = BCryptOpenAlgorithmProvider(hCryptProv, $$BCRYPT_AES_ALGORITHM, BYVAL %NULL, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
bRet = BCryptGetProperty(hCryptProv, $$BCRYPT_OBJECT_LENGTH, BYREF cbKeySize, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbKeyObject = HeapAlloc(GetProcessHeap(), 0, cbKeySize)
IF pbKeyObject = %NULL THEN
GOTO Cleanup
END IF
bRet = BCryptGetProperty(hCryptProv, $$BCRYPT_BLOCK_LENGTH, BYREF cbBlockSize, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbBlockObject = HeapAlloc(GetProcessHeap(), 0, cbBlockSize)
IF pbBlockObject = %NULL THEN
GOTO Cleanup
END IF
IF cbBlockSize <> LEN(Private_Key) THEN '16 byte
GOTO Cleanup
END IF
MEMORY COPY STRPTR(Private_Key), pbBlockObject, LEN(Private_Key) '私匙
cbc_mode = $$BCRYPT_CHAIN_MODE_CBC
bRet = BCryptSetProperty(hCryptProv, $$BCRYPT_CHAINING_MODE , BYVAL STRPTR(cbc_mode), LEN(cbc_mode), 0) '%BCRYPT_PUBLIC_KEY_FLAG
IF BCRYPT_SUCCESS(bRet) = %false THEN '%BCRYPT_PRIVATE_KEY_FLAG
GOTO Cleanup
END IF
cbSecret = Algid/8
pbSecret = HeapAlloc(GetProcessHeap(), 0, cbSecret)
IF pbSecret = %NULL THEN
GOTO Cleanup
END IF
ZeroMemory(pbSecret, cbSecret)
MEMORY COPY STRPTR(Public_Key), pbSecret, LEN(Public_Key) '公匙复制到分配空间
bRet = BCryptGenerateSymmetricKey(hCryptProv, hCryptKey, pbKeyObject, cbKeySize, pbSecret, cbSecret, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
'计算系统用于存放转换后公匙的结构大小
bRet = BCryptExportKey(hCryptKey, BYVAL %NULL, $$BCRYPT_OPAQUE_KEY_BLOB, BYVAL %NULL, 0, BYREF cbBlockSize, 0) 'cbBlockSize = 560字节
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
'上面的pbBlockObject中存放加密是私匙
pbBlockObject = HeapAlloc(GetProcessHeap(), 0, cbBlockSize)
IF pbBlockObject = %NULL THEN
GOTO Cleanup
END IF
'将加密后的密匙导出至Block块中,并返回指向Block的地址 560字节
bRet = BCryptExportKey(hCryptKey, BYVAL %NULL, $$BCRYPT_OPAQUE_KEY_BLOB, pbBlockObject, cbBlockSize, BYREF cbBlockSize, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
'// 验证密匙长度,不符合规范则退出
bRet = BCryptGetProperty(hCryptKey, $$BCRYPT_KEY_LENGTH, BYREF cbKeySize, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
IF cbKeySize <> Algid THEN
GOTO Cleanup
END IF
cbPlainText = LEN(buf_data)
pbPlainText = HeapAlloc(GetProcessHeap(), 0, cbPlainText)
IF pbBlockObject = %NULL THEN
GOTO Cleanup
END IF
MEMORY COPY STRPTR(buf_data), pbPlainText, cbPlainText '明文数据
'************************************************************************************************************
'OPEN "mt4_data.cer" FOR BINARY AS #1
' FOR i=0 TO cbBlockSize-1
' PUT #1,, @pbBlockObject[i]
' NEXT i
'CLOSE #1
' pbBlockObject = 这里存放着加密后的私匙 , 不释放这个空间的话,后面可以通过 BCryptImportKey 导出 hCryptKey
' cbBlockSize = 560 byte
'*************************************************************************************************************
'计算出密文所需的缓存区大小
bRet = BCryptEncrypt(hCryptKey, pbPlainText, cbPlainText, BYVAL %NULL, pbBlockObject, cbBlockSize, BYVAL %NULL, 0, BYREF cbCipherText, %BCRYPT_BLOCK_PADDING)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbCipherText = HeapAlloc(GetProcessHeap(), 0, cbCipherText)
IF pbCipherText = %NULL THEN
GOTO Cleanup
END IF
bRet = BCryptEncrypt(hCryptKey, pbPlainText, cbPlainText, BYVAL %NULL, pbBlockObject, cbBlockSize, pbCipherText, cbCipherText, BYREF cbData, %BCRYPT_BLOCK_PADDING)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
FOR i=0 TO cbData-1
aes = aes + CHR$(@pbCipherText[i])
NEXT i
Cleanup:
cbBlockSize = 0
cbKeySize = 0
cbPlainText = 0
cbCipherText = 0
cbSecret = 0
IF(pbKeyObject) THEN HeapFree(GetProcessHeap(), 0, pbKeyObject)
IF(pbBlockObject) THEN HeapFree(GetProcessHeap(), 0, pbBlockObject)
IF(pbPlainText) THEN HeapFree(GetProcessHeap(), 0, pbPlainText)
IF(pbCipherText) THEN HeapFree(GetProcessHeap(), 0, pbCipherText)
IF(pbSecret) THEN HeapFree(GetProcessHeap(), 0, pbSecret)
IF(hCryptKey) THEN BCryptDestroyKey(hCryptKey)
IF(hCryptProv) THEN BCryptCloseAlgorithmProvider(hCryptProv,0)
FUNCTION = aes
END FUNCTION
'//------------------------------------------------------------------------------------------
'// 密文解密
'// bu_data 数据源
'// Private_Key长度必须为16字节
'// Public_Key指定公匙长度: 16,24,32字节
'// Algid 为指定加密方式: CNG_AES_128位, CNG_AES_192位, CNG_AES_256位 除以8等于对应字节数
'//------------------------------------------------------------------------------------------
FUNCTION CNG_AES_ComputeDecrypt(BYVAL buf_data AS STRING, BYVAL Private_Key AS STRING, BYVAL Public_Key AS STRING, BYVAL Algid AS DWORD) AS STRING
LOCAL i AS LONG
LOCAL bRet AS LONG
LOCAL hCryptProv AS DWORD
LOCAL hCryptKey AS DWORD '密匙句柄
LOCAL cbKeySize AS DWORD '公匙长度
LOCAL pbKeyObject AS BYTE PTR '存放公匙地址指针
LOCAL cbBlockSize AS DWORD '区块大小
LOCAL pbBlockObject AS BYTE PTR '区块指针
LOCAL cbPlainText AS DWORD '明文长度
LOCAL pbPlainText AS BYTE PTR '明文指针
LOCAL cbCipherText AS DWORD '密文长度
LOCAL pbCipherText AS BYTE PTR '密文指针
LOCAL pbSecret AS BYTE PTR
LOCAL cbSecret AS DWORD
LOCAL cbData AS DWORD
LOCAL aes AS STRING
LOCAL Md5Key AS STRING
LOCAL cbc_mode AS WSTRING
'Md5Key = CNG_MD5_ComputeHash(PassWord) '用户密码生成的MD5 Private_Key
'dim PrivateKey(len(Md5Key)-1) as byte at strptr(Md5Key)
'dim PublicKey(len(Public_Key)-1) as byte at strptr(Public_Key)
hCryptProv = %NULL
hCryptKey = %NULL
pbBlockObject = %NULL
pbKeyObject = %NULL
pbPlainText = %NULL
pbCipherText = %NULL
pbCipherText = %NUll
cbBlockSize = 0
cbKeySize = 0
cbPlainText = 0
cbCipherText = 0
cbData = 0
IF LEN(Private_Key) <> 16 AND (Algid <> 128 OR Algid <> 192 OR Algid <> 256) THEN
GOTO Cleanup
END IF
bRet = BCryptOpenAlgorithmProvider(hCryptProv, $$BCRYPT_AES_ALGORITHM, BYVAL %NULL, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
bRet = BCryptGetProperty(hCryptProv, $$BCRYPT_OBJECT_LENGTH, BYREF cbKeySize, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbKeyObject = HeapAlloc(GetProcessHeap(), 0, cbKeySize)
IF pbKeyObject = %NULL THEN
GOTO Cleanup
END IF
bRet = BCryptGetProperty(hCryptProv, $$BCRYPT_BLOCK_LENGTH, BYREF cbBlockSize, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbBlockObject = HeapAlloc(GetProcessHeap(), 0, cbBlockSize)
IF pbBlockObject = %NULL THEN
GOTO Cleanup
END IF
IF cbBlockSize <> LEN(Private_Key) THEN
GOTO Cleanup
END IF
MEMORY COPY STRPTR(Private_Key), pbBlockObject, cbBlockSize '私匙
cbc_mode = $$BCRYPT_CHAIN_MODE_CBC
bRet = BCryptSetProperty(hCryptProv, BYREF $$BCRYPT_CHAINING_MODE, BYVAL STRPTR(cbc_mode), LEN(cbc_mode), 0) '%BCRYPT_PUBLIC_KEY_FLAG
IF BCRYPT_SUCCESS(bRet) = %false THEN '%BCRYPT_PRIVATE_KEY_FLAG
GOTO Cleanup
END IF
cbSecret = Algid/8
pbSecret = HeapAlloc(GetProcessHeap(), 0, cbSecret)
IF pbSecret = %NULL THEN
GOTO Cleanup
END IF
ZeroMemory(pbSecret, cbSecret)
MEMORY COPY STRPTR(Public_Key), pbSecret, LEN(Public_Key) '公匙复制到分配空间
bRet = BCryptGenerateSymmetricKey(hCryptProv, hCryptKey, pbKeyObject, cbKeySize, pbSecret, cbSecret, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
'计算系统用于存放转换后公匙的结构大小
bRet = BCryptExportKey(hCryptKey, BYVAL %NULL, $$BCRYPT_OPAQUE_KEY_BLOB, BYVAL %NULL, 0, BYREF cbBlockSize, 0) 'cbBlockSize = 560字节
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbBlockObject = HeapAlloc(GetProcessHeap(), 0, cbBlockSize)
IF pbBlockObject = %NULL THEN
GOTO Cleanup
END IF
'将加密后的密匙导出至Block块中,并返回指向Block的地址 560字节
'表示导出的是对称密钥,密钥用hPubKey指定的公钥加密
bRet = BCryptExportKey(hCryptKey, BYVAL %NULL, $$BCRYPT_OPAQUE_KEY_BLOB, pbBlockObject, cbBlockSize, BYREF cbBlockSize, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
'// 验证密匙长度,不符合规范则退出
bRet = BCryptGetProperty(hCryptKey, $$BCRYPT_KEY_LENGTH, BYREF cbKeySize, 4, BYREF cbData, 0)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
IF cbKeySize <> Algid THEN
GOTO Cleanup
END IF
cbCipherText = LEN(buf_data)
pbCipherText = HeapAlloc(GetProcessHeap(), 0, cbCipherText)
IF pbBlockObject = %NULL THEN
GOTO Cleanup
END IF
MEMORY COPY STRPTR(buf_data), pbCipherText, cbCipherText '密文数据
bRet = BCryptDecrypt(hCryptKey, pbCipherText, cbCipherText, BYVAL %NULL, pbBlockObject, cbBlockSize, BYVAL %NULL, 0, BYREF cbPlainText, %BCRYPT_BLOCK_PADDING)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
pbPlainText = HeapAlloc(GetProcessHeap(), 0, cbPlainText)
IF pbPlainText = %NULL THEN
GOTO Cleanup
END IF
MEMORY COPY STRPTR(buf_data), pbPlainText, cbCipherText '密文数据
bRet = BCryptDecrypt(hCryptKey, pbCipherText, cbCipherText, BYVAL %NULL, pbBlockObject, cbBlockSize, pbPlainText, cbPlainText, BYREF cbData, %BCRYPT_BLOCK_PADDING)
IF BCRYPT_SUCCESS(bRet) = %false THEN
GOTO Cleanup
END IF
FOR i=0 TO cbData-1
aes = aes + CHR$(@pbPlainText[i])
NEXT i
Cleanup:
cbBlockSize = 0
cbKeySize = 0
cbPlainText = 0
cbCipherText = 0
cbSecret = 0
IF(pbKeyObject) THEN HeapFree(GetProcessHeap(), 0, pbKeyObject)
IF(pbBlockObject) THEN HeapFree(GetProcessHeap(), 0, pbBlockObject)
IF(pbPlainText) THEN HeapFree(GetProcessHeap(), 0, pbPlainText)
IF(pbCipherText) THEN HeapFree(GetProcessHeap(), 0, pbCipherText)
IF(pbSecret) THEN HeapFree(GetProcessHeap(), 0, pbSecret)
IF(hCryptKey) THEN BCryptDestroyKey(hCryptKey)
IF(hCryptProv) THEN BCryptCloseAlgorithmProvider(hCryptProv,0)
FUNCTION = aes
END FUNCTION
PowerBasic CNG加解密编程
于 2022-09-24 12:22:20 首次发布