7890qwaszx 发表于 2017-7-21 22:53:55

[求助]关于解密数据的问题

一个用_Crypt_EncryptFile加密后的文件,因为辨别的需要,向加密后的文件前部写入了几个英文字符作为文件头,但是解密的时候要忽略文件头,请问该怎么办?

我用的方法是读取固定长度的字节数,然后用_Crypt_DecryptData(第四个参数设置为False),这样能初步达到目的。但是再写入文件的时候会出现在文件末尾补DEL凑字节的现象(但全是汉字的情况下不会出现这个问题)。用40字节的文本文档测试,末尾会补DEL字符使文件大小达到48字节,,这个问题怎么解决呢?有没有大神有更好的方法?

afan 发表于 2017-7-22 11:49:13

无测试代码。估计是取字节数量的问题

帆船 发表于 2017-7-22 14:11:23

本帖最后由 帆船 于 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

7890qwaszx 发表于 2017-7-23 20:30:08

标记……我是为了区分是否是我的程序加密的。
读取字节数在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)如果实在不行就用帆船的方法吧……

帆船 发表于 2017-7-23 21:52:18

回复 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

说实话,我看不懂你那样写是什么意义

7890qwaszx 发表于 2017-7-24 18:20:38

回复 5# 帆船


    帮助文档说二进制变量最大为1g,照你的写法如果文件大于1g就会失败

帆船 发表于 2017-7-24 18:35:19

回复 7# 7890qwaszx
2,147,483,647字节,是2G哦

7890qwaszx 发表于 2017-7-24 19:53:10

回复 8# 帆船


   记错了……⊙﹏⊙‖∣
 不管怎样,我想找一个切实可行的方法……

帆船 发表于 2017-7-24 21:24:41

那么我再支持一下……
#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

7890qwaszx 发表于 2017-7-25 22:24:08

回复 10# 帆船


    之前我是这么想的,但这样的话效率太低了,所以我自己改了Crypt.au3,完美解决了这个问题,稍后贴改之后代码

7890qwaszx 发表于 2017-7-25 22:42:19

这就是修改后的_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

帆船 发表于 2017-7-27 13:19:34

回复 12# 7890qwaszx
然而这个函数本身也是按1MB读取的
页: [1]
查看完整版本: [求助]关于解密数据的问题