Search code examples
pythonhmachashlib

Trying to create hash using timestamp and base64 encoded json string, getting memory error


This simple script dies with a memory error and I'm not sure why.

import simplejson as json
import hmac
import hashlib
from time import time
import base64
sso_user={'a':'foo','b':'bar'}
ssoKey=b'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
timestamp = round(time() * 1000)
s=json.dumps(sso_user)
userDataJSONBase64 = base64.b64encode(s.encode())
verificationHash = hmac.new(
    bytes(timestamp)+userDataJSONBase64,
    ssoKey,
    hashlib.sha256
).hexdigest()
print(verificationHash)

it's choking on hmac.new()


Solution

  • The problem is that you're using the bytes built-in in python3 which behaves differently than it does in python2. In python2.7, bytes is an alias for str. In python3, the constructor which takes an integer makes an array of N 0s. Since you're passing in something like 1,617,219,736,292 (on March 31st, 2021), you're initializing an array of size 1.6 trillion and running out of memory: MemoryError .

    $ python2
    >>> print(bytes.__doc__)
    str(object='') -> string
    
    Return a nice string representation of the object.
    If the argument is a string, the return value is the same object.
    ^C
    $ python3
    >>> print(bytes.__doc__)
    bytes(iterable_of_ints) -> bytes
    bytes(string, encoding[, errors]) -> bytes
    bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
    bytes(int) -> bytes object of size given by the parameter initialized with null bytes
    bytes() -> empty bytes object
    
    Construct an immutable array of bytes from:
      - an iterable yielding integers in range(256)
      - a text string encoded using the specified encoding
      - any object implementing the buffer API.
      - an integer