Encode in Laravel, decode in Python

后端 未结 3 1019
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-23 16:56

I\'m using Laravel\'s encryptString method to encrypt some data on my website. This uses OpenSSL\'s 256-bit AES-CBC encryption without any serialization. I\'m now trying to decr

3条回答
  •  闹比i
    闹比i (楼主)
    2021-01-23 17:25

    I notice this haven't been active for a while but I'm trying to do the same and can't seem to make it work.

    What I noticed is that the encoded password string stored by Laravel is a base 64 encoded json object, which wasn't taken into consideration in the original question:

    pass_obj = base64.b64decode('eyJpdiI6ImdxY0VcLzFodmpISFV4allSWmJDdEpRPT0iLCJ2YWx1ZSI6IkxXd0ZJaUd2bTUweW5pNm0wUjQwOFM2N1wvWEs5SlYrNB4xNlR7Qkh1U3FvPSIsIm1hYyI6Ijc5ZWM0YTYxYjljZGFiNzgwNjY2NDU1ZmQ5Yjc1ZmJlOGU4NzBkMjQzMzA3MmVhYzE3NzY4ZmU1MWIyMjZlOTQifQ==')
    print(pass_obj)
    >>> b'{"iv":"gqcE\\/1hvjHHUxjYRZbCtJQ==","value":"LWwFIiGvm50yni6m0R408S67\\/XK9JV+4\x1e16T{BHuSqo=","mac":"79ec4a61b9cdab780666455fd9b75fbe8e870d2433072eac17768fe51b226e94"}'
    

    From that you can get the IV and the encrypted value, both seem to be base64 encoded. But I still get a decoding error at the end like;

    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfa in position 0: invalid start byte

    Here is my complete code;

    password = 'eyJpdiI6ImJGNDNNZjN3YWtpcDQ5VEJVXC9IazF3PT0iLCJ2YWx1ZSI6IkNVRW1VQUY1dXArYlFkU3NlY1pnZUE9PSIsIm1hYyI6ImM3ODk0NWQ0NjgxMzM4YjE0M2JhN2MzZWRmOWEwMWJiMjI2Y2FhYmUxYjFhYzAyYjY4YWZkZGE3N2EyMDYwNWYifQ=='
    key = 'some secret key that i can't share'.encode()
    p_obj = json.loads(base64.b64decode(password).decode())
    decobj = AES.new(key, AES.MODE_CBC, base64.b64decode(p_obj['iv']))
    data = decobj.decrypt(base64.b64decode(p_obj['value']))
    print(data)
    >>> b'l\xee:f\x9eZ\x90rP\x99\xca&@\x1d1\x9f'
    data.decode()
    >>> Traceback (most recent call last):
      File "", line 1, in 
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xee in position 1: invalid continuation byte
    

    @Pecans did you ever figure this out?

    Thank you.


    Full working code EDIT

    I fugured it out, I had a problem with my key initially. So here's the full snippet for future reference;

    import base64
    import json
    from phpserialize import unserialize
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad, unpad
    
    key = b'my secret key'
    enc_pass = 'eyJpdiI6ImJGNDNNZjN3YWtpcDQ5VEJVXC9IazF3PT0iLCJ2YWx1ZSI6IkNVRW1VQUY1dXArYlFkU3NlY1pnZUE9PSIsIm1hYyI6ImM3ODk0NWQ0NjgxMzM4YjE0M2JhN2MzZWRmOWEwMWJiMjI2Y2FhYmUxYjFhYzAyYjY4YWZkZGE3N2EyMDYwNWYifQ=='
    
    p_obj = json.loads(base64.b64decode(password).decode())
    decobj = AES.new(key, AES.MODE_CBC, base64.b64decode(p_obj['iv']))
    data = decobj.decrypt(base64.b64decode(p_obj['value']))
    dec_pass = unserialize(unpad(data, 16)).decode()
    

    You will have the decrypted password in dec_pass.

    Note that sometimes Laravel generates the key in base64. In that case the string will be something like base64:sdfsdjfhjsdf32, then you have to decode first.

    Cheers!

提交回复
热议问题