That's particularly tricky under Python. The main datatype I know of is Python's bytearray(), which can be treated like a byte string in many (but not all) cases. Since it's mutable, you can then zero it out afterwards.
The problem is that any time you try to populate it, or hand it off to another function, a temporary byte copy may be made in memory, which may linger. For example, I could do ...
buf = bytearray("\x00" * 6)
buf = b"s"
buf = b"e"
buf = b"c"
buf = b"r"
buf = b"e"
buf = b"t"
... which would semi-securely populate the byte array without the string "secret" every being allocated by the Python VM (as described in http://stackoverflow.com/a/14667881/681277
). Of course, you've got to figure out how to populate it from the password source without *that* code ever creating a Python string.
But that problem aside, even doing something as simple as ...
digest = hashlib.sha256(buf).hexdigest()
... can't be trusted, as there's no guarantee (without examining the source for the particular VM & sha256 implementation) that doing ``sha256(buf)`` doesn't create a lingering copy in memory as the Python->C interface translates your input into something it can hand off to the underlying sha256 engine.
All that said, if I were to approach achieving that, bytearray() would probably be my preferred choice. (mmap'ing the file containing the password might also be useful).
With specific regards to Passlib ... sadly it
doesn't handle bytearrays to well just yet, and creates lingering copies
of byte objects in a few places. I'm looking into fixing that for the far future, but it's never been a priority, because it's always felt like an impossible battle to strive for such a guarantee in passlib, when I can't trust the VM won't make me a liar in an unexpected place.
For what it's worth, hope that helps :)