Pycrypto AES 解密产生多余的 "\x07\x07\x07\x07\x07\x07\x07

1 投票
1 回答
1185 浏览
提问于 2025-04-18 18:20

在用Pycrypto的Aes解密后,经过base64解码,结果的末尾多了些额外的内容,显示为"\x07\x07\x07\x07\x07\x07\x07"

Python输出:

解密后的json消息:

b'{"EndTime":"\\/Date(1408876230508+0530)\\/","SessionID":"ddbecfdb-b87f-48d5-84dd-9dce439459ac","TestString":"WORKING FINE"}\x07\x07\x07\x07\x07\x07\x07'

未加密的Json消息:

{"EndTime":"\/Date(1408876230508+0530)\/","SessionID":"ddbecfdb-b87f-48d5-84dd-9dce439459ac","TestString":"WORKING FINE"}

还有,当我尝试用Json.loads来处理解密后的消息时,出现了类型错误。因此,我尝试使用base64.b64decode,但这也出错了,错误信息是binascii.Error: Incorrect padding。

我的REST服务编码代码:

    Dim rawdatastream As New MemoryStream
    Dim jsonserialization As New Json.DataContractJsonSerializer(GetType(AuthorizationResultType))
    jsonserialization.WriteObject(rawdatastream, c)

    Using encryptor As Aes = Aes.Create()
        encryptor.Key = {66, 16, 1, 61, 58, 16, 16, 49, 66, 16, 46, 46, 16, 146, 49, 255,
                         240, 127, 189, 191, 3, 151, 89, 124, 56, 89, 134, 164, 165, 201, 212, 216}
        encryptor.Mode = CipherMode.CBC
        encryptor.IV = {66, 16, 1, 61, 58, 16, 16, 49, 66, 16, 46, 46, 16, 146, 49, 66}
        Dim clearBytes As Byte() = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(rawdatastream.ToArray()))
        Using ms As New MemoryStream()
            Using cs As New CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)
                cs.Write(clearBytes, 0, clearBytes.Length)
                cs.Close()
            End Using
            result.Msg = Convert.ToBase64String(ms.ToArray())
        End Using
    End Using

Python代码:

import requests
import json
import base64
from Crypto.Cipher import AES

baseurl = 'http://localhost:9624/'

def LoginAccess(userid, password):
    print('Accessing Authorization info')
    response = requests.get(baseurl +'BasicServ.svc/auth/Authorize/'+userid+'/'+password+'/2')
    print (response.json())

    rawmsg =response.json()
    msg= rawmsg['AuthorizeResult']['Msg']

    cypherkey=[66, 16, 1, 61, 58, 16, 16, 49, 66, 16, 46, 46, 16, 146, 49, 255,240, 127, 189, 191, 3, 151, 89, 124, 56, 89, 134, 164, 165, 201, 212, 216]
    iv=[66, 16, 1, 61, 58, 16, 16, 49, 66, 16, 46, 46, 16, 146, 49, 66]
    cry=AES.new(bytes(cypherkey),AES.MODE_CBC,bytes(iv))
    print("decryption done")
    c = cry.decrypt(base64.b64decode(msg))
    print (c)
    print(base64.b64decode(c))
    print (json.loads(base64.b64decode(c)))
    print (rawmsg['AuthorizeResult']['MsgN'])

最后,我在解密、base64解码和json转换中犯了什么错误(我觉得所有错误都是由于生成了额外的填充)

编辑:填充后的代码:

WCF REST代码:

    Dim rawdatastream As New MemoryStream
    Dim jsonserialization As New Json.DataContractJsonSerializer(GetType(AuthorizationResultType))
    jsonserialization.WriteObject(rawdatastream, c)
    result.Unlocksize = Encoding.UTF8.GetString(rawdatastream.ToArray()).Length


    Using encryptor As Aes = Aes.Create()
        encryptor.Mode = CipherMode.CBC
        encryptor.Key = {66, 16, 1, 61, 58, 16, 16, 49, 66, 16, 46, 46, 16, 146, 49, 255, 240, 127, 189, 191, 3, 151, 89, 124, 56, 89, 134, 164, 165, 201, 212, 216}
        encryptor.IV = {66, 16, 1, 61, 58, 16, 16, 49, 66, 16, 46, 46, 16, 146, 49, 66}

        Console.WriteLine(encryptor.IV)
        Console.WriteLine(encryptor.Key)
        Dim datalen As Integer
        Dim actualcoount As Integer = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(rawdatastream.ToArray())).Count
        datalen = 32 - (Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(rawdatastream.ToArray())).Count Mod 32)
        Dim correctionbytes As String = ""
        For i = 1 To datalen
            correctionbytes = correctionbytes + "1"
        Next
        result.Unlocksize = datalen

        Dim clearBytes As Byte() = Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(rawdatastream.ToArray()) + correctionbytes)
        Using ms As New MemoryStream()
            Using cs As New CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)
                cs.Write(clearBytes, 0, clearBytes.Length)
                cs.Close()
            End Using
            result.Msg = Convert.ToBase64String(ms.ToArray())
        End Using
    End Using

1 个回答

4

看起来PyCrypto这个库并没有提供PKCS#7的填充和去填充功能(其实应该有的)。所以你需要自己实现这个功能,可以用 data = data[:-data[-1]] 这段代码来处理。你应该在调用 decrypt 之后,直接对变量 c 进行这个操作。

你可以检查所有的填充字节(在这个例子中是7个),但是如果你想防止无效的密文,最好还是加一个MAC(HMAC)来保护一下。

更多信息可以在 这里 找到。

撰写回答