[Python] Invalid base64 string. number of data characters(9) can not be more than a multiple...

Discussão em 'Python' iniciado por Stack, Junho 11, 2025.

  1. Stack

    Stack Membro Participativo

    I'm facing issues decrypting some AES-encrypted data after upgrading my Python runtime and related libraries.

    Previously, I was running:

    • Python: 3.8
    • pycryptodomex: 3.19.1
    • cryptography: 42.0.4

    and I was successfully able to encrypt and decrypt data. These encrypted strings were stored in MongoDB in this format:

    "query": {
    "$binary": {
    "base64": "YmpKVXZZM0wzS1VxcmhrRHFna3R3aVlQckQwRVoyNjhnY1YzcUM0RTZjWmdpQ3NuNTAzZGhKS0FyL09sSE5tZHJnVjBmaDVNUWRwMXNFUTQ=",
    "subType": "00"
    }
    }


    We upgraded our application stack to:

    • Python: 3.11
    • pycryptodomex: 3.20.0
    • cryptography: 43.0.1

    Now I'm not able to decrypt the older encrypted data any more:

    Decryption failed: Invalid padding.
    Number of data characters(9) can not be more than multiple of 4


    It was working fine in the old environment. No code changes were made to the encryption/decryption logic. The encryption key has not changed — only the Python and library versions have been upgraded.

    I have also tried installing the packages/libraries of the older version but still not working.

    Here's the exact code for both encryption and decryption:

    import base64
    import hashlib
    from Cryptodome.Cipher import AES
    from Cryptodome.Random import get_random_bytes
    import json

    # Static key (unchanged across environments)
    ENCRYPTION_KEY = "Xozwbuykf38" # example key; real one comes from env config
    __key__ = hashlib.sha256(ENCRYPTION_KEY.encode('utf-8')).digest()

    # Encryption function
    def encrypt(raw):
    raw = json.dumps(raw)
    BS = AES.block_size

    def pad(s):
    return s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

    raw = base64.b64encode(pad(raw).encode("utf8"))
    iv = get_random_bytes(AES.block_size)
    cipher = AES.new(key=__key__, mode=AES.MODE_CFB, iv=iv)
    return base64.b64encode(iv + cipher.encrypt(raw))

    # Decryption function
    def decrypt(enc):
    def unpad(s):
    return s[:-ord(s[-1:])]

    enc = base64.b64decode(enc)
    iv = enc[:AES.block_size]
    cipher = AES.new(__key__, AES.MODE_CFB, iv)
    decrypted = cipher.decrypt(enc[AES.block_size:])
    return json.loads(unpad(base64.b64decode(decrypted).decode("utf8")))


    Could there be any internal behavior changes in pycryptodomex or Python 3.11 that cause this? How do I maintain compatibility with the older AES-encrypted data? Is there a reliable fix or patch that works without re-encrypting all MongoDB data?

    Continue reading...

Compartilhe esta Página