[求助]关于解密数据的问题
一个用_Crypt_EncryptFile加密后的文件,因为辨别的需要,向加密后的文件前部写入了几个英文字符作为文件头,但是解密的时候要忽略文件头,请问该怎么办?我用的方法是读取固定长度的字节数,然后用_Crypt_DecryptData(第四个参数设置为False),这样能初步达到目的。但是再写入文件的时候会出现在文件末尾补DEL凑字节的现象(但全是汉字的情况下不会出现这个问题)。用40字节的文本文档测试,末尾会补DEL字符使文件大小达到48字节,,这个问题怎么解决呢?有没有大神有更好的方法? 无测试代码。估计是取字节数量的问题 本帖最后由 帆船 于 2017-7-22 14:12 编辑
其实不需要标记的,我是直接试着解密,如果不行就加密
#include <Crypt.au3>
Local $sFile = "D:\Code\Crypt\Test.txt"
_CryptFile($sFile)
If @error Then ConsoleWrite(@error & @TAB & @extended & @CRLF)
Func _CryptFile($sFile, $sData = 2333, $sSave = Default)
If $sSave = Default Then $sSave = $sFile
If Not FileExists($sFile) Then Return SetError(1, 0, "")
Local $hFile = FileOpen($sFile, 16)
Local $bRead = FileRead($hFile)
FileClose($hFile)
_Crypt_Startup()
Local $hHash = _Crypt_HashData($sData, $CALG_SHA1)
Local $bWrite = _Crypt_DecryptData($bRead, $hHash, $CALG_AES_128)
If @error Then $bWrite = _Crypt_EncryptData($bRead, $hHash, $CALG_AES_128)
If @error Then Return SetError(2, @error, "")
$hFile = FileOpen($sSave, 2 + 16)
FileWrite($hFile, $bWrite)
FileClose($hFile)
_Crypt_Shutdown()
EndFunc ;==>_CryptFile
标记……我是为了区分是否是我的程序加密的。
读取字节数在256字节以上不管多大解密出来都一个结果,小于256直接失败。
上代码(这个是从0读取试水的):#include <Crypt.au3>
_Crypt_EncryptFile('123.txt','123.crypt.txt','12345678',$CALG_AES_256)
;_Crypt_DecryptFile('123.crypt.txt','123.DEcrypt.txt','12345678',$CALG_AES_256)
Local $FileHandel = FileOpen('123.crypt.txt',16)
Local $FileRead, $FileDecrypt
For $i = 1 To Ceiling(FileGetSize('123.crypt.txt') / 1024)
If $i = Ceiling(FileGetSize('123.crypt.txt') / 1024) Then
$FileRead = FileRead($FileHandel,FileGetSize('123.crypt.txt') - (($i-1) * 1024))
Else
$FileRead = FileRead($FileHandel,1024)
EndIf
$FileDecrypt &= _Crypt_DecryptData($FileRead,'12345678',$CALG_AES_256,False)
Next
Local $FileHandelNew = FileOpen('1234.txt',2 + 16)
FileWrite($FileHandelNew, $FileDecrypt)如果实在不行就用帆船的方法吧…… 回复 4# 7890qwaszx
哎呦,这么喜欢标记的的话,这样好了
#include <Crypt.au3>
Local $sFile = "D:\Code\Crypt\Test.txt"
_CryptFile_ByMark($sFile)
If @error Then ConsoleWrite(@error & @TAB & @extended & @CRLF)
Func _CryptFile_ByMark($sFile, $sMark = "Crypted", $sData = 2333, $sSave = Default)
If $sSave = Default Then $sSave = $sFile
If Not FileExists($sFile) Then Return SetError(1, 0, "")
Local $hFile = FileOpen($sFile, 16)
Local $bRead = FileRead($hFile)
FileClose($hFile)
_Crypt_Startup()
Local $hHash = _Crypt_HashData($sData, $CALG_SHA1)
Local $bWrite = ""
If BinaryToString(BinaryMid($bRead, 1, BinaryLen($sMark))) = $sMark Then
$bRead = BinaryMid($bRead, BinaryLen($sMark) + 1, BinaryLen($bRead))
$bWrite = _Crypt_DecryptData($bRead, $hHash, $CALG_AES_128)
Else
$bWrite = StringToBinary($sMark)
$bWrite &= _Crypt_EncryptData($bRead, $hHash, $CALG_AES_128)
EndIf
If @error Then Return SetError(2, @error, "")
$hFile = FileOpen($sSave, 2 + 16)
FileWrite($hFile, $bWrite)
FileClose($hFile)
_Crypt_Shutdown()
EndFunc ;==>_CryptFile_ByMark
说实话,我看不懂你那样写是什么意义 回复 5# 帆船
帮助文档说二进制变量最大为1g,照你的写法如果文件大于1g就会失败 回复 7# 7890qwaszx
2,147,483,647字节,是2G哦 回复 8# 帆船
记错了……⊙﹏⊙‖∣
不管怎样,我想找一个切实可行的方法…… 那么我再支持一下……
#include <Crypt.au3>
Local $sFile = "D:\Code\Crypt\AES\Test.txt"
_CryptFile_ByMark($sFile)
If @error Then ConsoleWrite(@error & @TAB & @extended & @CRLF)
Func _CryptFile_ByMark($sFile, $sSave = Default, $sMark = "Crypted", $sData = 2333)
If $sSave = Default Then $sSave = $sFile
If Not FileExists($sFile) Then Return SetError(1, 0, "")
Local $sTemp = StringLeft($sFile, StringInStr($sFile, "\", 0, -1)) & "Crypt_Temp.tmp"
ConsoleWrite($sTemp & @CRLF)
Local $iSize = FileGetSize($sFile), $iSpace = Round(DriveSpaceFree(StringLeft($sFile, 3)) * 1024 ^ 2)
If $iSpace < $iSize Then Return SetError(2, $iSpace, "")
Local $hFile_Temp = FileOpen($sTemp, 2 + 16)
Local $hFile_In = FileOpen($sFile, 16)
Local $bWrite = "", $bMark = StringToBinary($sMark), $iRead = 0
Local $bTitle = FileRead($sFile, BinaryLen($bMark))
If $bTitle = $bMark Then
$iRead += BinaryLen($bMark)
FileSetPos($hFile_In, $iRead, 0)
Else
FileWrite($hFile_Temp, $bMark)
EndIf
Local $hHash = _Crypt_HashData($sData, $CALG_SHA1)
Do
$bRead = FileRead($hFile_In, 1024 ^ 2)
$iRead += BinaryLen($bRead)
If $bTitle = $bMark Then
$bWrite = _Crypt_DecryptData($bRead, $hHash, $CALG_AES_128, (($iRead >= $iSize) ? True : False))
Else
$bWrite = _Crypt_EncryptData($bRead, $hHash, $CALG_AES_128, (($iRead >= $iSize) ? True : False))
EndIf
If @error Then Return SetError(3, @error, "")
FileWrite($hFile_Temp, $bWrite)
Until $iRead >= $iSize
FileClose($hFile_In)
FileClose($hFile_Temp)
FileMove($sTemp, $sSave, 1 + 8)
EndFunc ;==>_CryptFile_ByMark
回复 10# 帆船
之前我是这么想的,但这样的话效率太低了,所以我自己改了Crypt.au3,完美解决了这个问题,稍后贴改之后代码 这就是修改后的_Crypt_DecryptFile函数,支持忽略文件头解密
$sSourceFile:源文件
$sDestinationFile:结果文件
$vCryptKey:当指定 CALG_USERKEY 标记时提供的密码或密钥句柄
$iALGID:使用的算法
$Header:文件头
Func _Crypt_DecryptFile($sSourceFile, $sDestinationFile, $vCryptKey, $iAlgID, $Header = "")
Local $bTempData = 0, _
$hInFile = 0, $hOutFile = 0, _
$iError = 0, $iExtended = 0, $iFileSize = FileGetSize($sSourceFile), $iRead = 0, _
$bReturn = True
Local $Count = 0
_Crypt_Startup()
Do
If $iAlgID <> $CALG_USERKEY Then
$vCryptKey = _Crypt_DeriveKey($vCryptKey, $iAlgID)
If @error Then
$iError = @error
$iExtended = @extended
$bReturn = False
ExitLoop
EndIf
EndIf
$hInFile = FileOpen($sSourceFile, $FO_BINARY)
If @error Then
$iError = 2
$bReturn = False
ExitLoop
EndIf
$hOutFile = FileOpen($sDestinationFile, $FO_OVERWRITE + $FO_CREATEPATH + $FO_BINARY)
If @error Then
$iError = 3
$bReturn = False
ExitLoop
EndIf
Do
$Count += 1
If $Count = 1 Then
FileSetPos($hInFile, BinaryLen($Header), 0)
$bTempData = FileRead($hInFile, 1024 * 1024)
Else
$bTempData = FileRead($hInFile, 1024 * 1024)
EndIf
$iRead += BinaryLen($bTempData)
If $iRead = ($iFileSize - BinaryLen($Header)) Then
$bTempData = _Crypt_DecryptData($bTempData, $vCryptKey, $CALG_USERKEY, True)
If @error Then
$iError = @error + 400
$iExtended = @extended
$bReturn = False
EndIf
FileWrite($hOutFile, $bTempData)
ExitLoop 2
Else
$bTempData = _Crypt_DecryptData($bTempData, $vCryptKey, $CALG_USERKEY, False)
If @error Then
$iError = @error + 500
$iExtended = @extended
$bReturn = False
ExitLoop 2
EndIf
FileWrite($hOutFile, $bTempData)
EndIf
Until False
Until True
If $iAlgID <> $CALG_USERKEY Then _Crypt_DestroyKey($vCryptKey)
_Crypt_Shutdown()
If $hInFile <> -1 Then FileClose($hInFile)
If $hOutFile <> -1 Then FileClose($hOutFile)
Return SetError($iError, $iExtended, $bReturn)
EndFunc ;==>_Crypt_DecryptFile
回复 12# 7890qwaszx
然而这个函数本身也是按1MB读取的
页:
[1]