Saturday, December 18, 2010

Erase keys and credit card numbers in Python

Not to start a long discussion on system security and the advisability of doing crypto in potentially compromised environments, suffice it to say it is still good practice to erase keys, credit card numbers, and other sensitive information when no longer needed. Overwriting the sensitive content with garbage will not prevent leakage but it can reduce the likelihood.

Unfortunately Python's assignment statement
  key = "Kilroy was here!"
    ...
  key = "qwerty" 
does not overwrite previous string values. True, key now points to "qwerty" but this is a new string. The old string is not overwritten and still resides in memory flagged for garbage collection. When it will be collected and reused is indeterminate, and even then, there is no assurance it will be overwritten. This problem is common to many scripting languages, not just Python.

Python's ctypes' c_buffer() has an interesting property. Operations on the buffer's contents occur in a fixed memory location making it attractive for the later clearing of sensitive content. Consider this:
  from ctypes import c_buffer, addressof

  TEMPLATE = '  %s: key location: 0x%X, value: %s'

  # instantiate key
  key = c_buffer(16)
  print '  key: %s' % key

  # set the key value
  key.value = 'Kilroy was here!'
  print TEMPLATE % ('set', addressof(key), key.value)

  # use the key in some way
  pass

  # overwrite the key
  key.value = '-'*16
  print TEMPLATE % ('clr', addressof(key), key.value)
If you are using ctypes to access an AES routine written in C, simply pass the variable key which, as it turns out, is essentially a pointer to the character array. The above approach also works for other data types such as int and ulong.

Enjoy.

Labels: , ,