This is an area I've spent a fairly significant amount of time investigating. My conclusion was "no, there is no reliable way to do this", but I'd love to be proven wrong.
The fundamental problem is that how exactly <Python implementation> stores variables in memory is not defined as part of the implementation requirements, and so even if you can figure out a way to wipe a value from memory on one implementation, there is no guarantee that it will work on any other implementation. With CPython, you /can/ technically use "ctypes" to read and write memory directly, and by introspecting a similar object (say, an arbitrary string with known value), you can reach in and overwrite data that is /probably/ the data you're trying to wipe out. Unfortunately, this approach makes a lot of assumptions about how CPython actually structures variables in memory: assumptions that may or may not be valid today and may or may not be valid in the future (or the past, for that matter). /At best/ the only thing you can reasonably say is that this /probably/ works for the specific version of the specific implementation you have tested it on, and that it /might/ not have adverse side effects. I've also toyed with the idea of making a C extension analogous to the SecretKey structure from Java, which never lets the actual key material out of the structure, but in order to actually do anything with the key material it still needs to surface to Python at some point, which puts us back in the same position we started with. ..unless we were to re-implement all of pyca/cryptography in Cython, but that's a thought for a different time... --Matt On Fri, Feb 16, 2018 at 1:25 PM Andrew Donoho <a...@ddg.com> wrote: > Gentlefolk, > > > > Apparently, my Google-fu is weak and I come seeking advice. > > Secret management is important. In particular, I want to make sure > that any secrets I decrypt are erased from memory before the storage is > reclaimed by the VM. In other environments, I would just dig into each > object until I get the pointer for the storage and then bang zeros, ones > and randomness into the block. Then garbage collection would proceed apace. > > > > Here’s an example from the cryptography documentation, < > https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/ > >: > > >>> import os > >>> from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, > modes > >>> from cryptography.hazmat.backends import default_backend > >>> backend = default_backend() > >>> key = os.urandom(32) > >>> iv = os.urandom(16) > >>> cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) > >>> encryptor = cipher.encryptor() > >>> ct = encryptor.update(b"a secret message") + encryptor.finalize() > >>> decryptor = cipher.decryptor() > >>> decryptor.update(ct) + decryptor.finalize() > 'a secret message’ > > > The `key` above is a `bytes` object. It has storage somewhere. Even though > it is a read-only Python object, I can pierce the abstraction, if I have > to, with C. > > My question is: has someone else already done so and published the handful > of methods needed? > > If not, should this be an API added to cryptography? > > > > Anon, > Andrew > ____________________________________ > Andrew W. Donoho > Donoho Design Group, L.L.C. > a...@ddg.com, +1 (512) 750-7596 <(512)%20750-7596>, twitter.com/adonoho > > Doubt is not a pleasant condition, but certainty is absurd. > — Voltaire > > > > _______________________________________________ > Cryptography-dev mailing list > Cryptography-dev@python.org > https://mail.python.org/mailman/listinfo/cryptography-dev >
_______________________________________________ Cryptography-dev mailing list Cryptography-dev@python.org https://mail.python.org/mailman/listinfo/cryptography-dev