5 ms·
by explicitly clearing it when an operation is finished. example: https://github.com/andy-goryachev/PasswordSafe/blob/master/src/goryachev/crypto/MemCrypt.jav
by java-man 7y ago
by explicitly clearing it when an operation is finished.
example:
https://github.com/andy-goryachev/PasswordSafe/blob/master/src/goryachev/crypto/MemCrypt.java https://github.com/andy-goryachev/PasswordSafe/blob/master/s...
byte[] key = generateKey();
try
{
// sensitive operation
}
finally
{
Crypto.zero(key);
}
once the operation finishes, the memory is cleared (and possibly subject to gc)
the problem is that some java classes, for instance BigInteger, are not designed for cryptographic operations - it's underlying arrays are not easily accessible (save for reflection).
- pstrateman 7y agoThat operation is almost certainly optimized out.
- java-man 7y agoWould you elaborate please?
- marvin-83 7y agoI believe he is referring to compiler optimisation which removes wasteful or extraneous operations. I don't write in Java though, so can't comment more than that.
- pstrateman 7y agoThe compiler will see that your operation does nothing and simply not do it.
- java-man 7y agoWhat I mean was: do you know this to be the case for JVM 8 later? This is an interesting subject. Was there a study or a paper you can refer me to?
- pstrateman 7y agoJVM 8 isn't an implementation, it's a specification. Assuming you mean oracles implementation, it's likely that it is. https://www.sjoerdlangkemper.nl/2016/05/22/should-passwords-be-cleared-from-memory/ https://www.sjoerdlangkemper.nl/2016/05/22/should-passwords-... http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buf... https://man.openbsd.org/explicit_bzero.3 https://man.openbsd.org/explicit_bzero.3
- java-man 7y agoThank you. I was hoping for a more definitive answer, may be a reference to an explicit test involving memory dump analysis.
- saurik 7y agoIn that code, after generateKey, during the sensitive operation, the system might need to do a garbage collection, at which point this array might have been copied to a different location in memory before your call to zero. You have to also "pin" (afaik this is the usual terminology for this) that array to a fixed location (which would then have to be a feature of that runtime and garbage collector) after allocating it but before generating the key.
- java-man 7y agoSo what you are saying is that JVM copying surviving object between generational pools might expose secrets in memory? A very good point, thank you. What could be done to mitigate this? Direct ByteBuffer per https://stackoverflow.com/questions/5670862/bytebuffer-allocate-vs-bytebuffer-allocatedirect https://stackoverflow.com/questions/5670862/bytebuffer-alloc... ?
- MarkSweep 7y agoIn .NET you can pin memory in the GC heap, either using something like the fixed expression in C# or GCHandle. A quick Googleing did not turn up something usable directly by Java, except ByteBuffer.
- rurban 7y agoJava also has no mfence or clflush support, so crypto.zero would never be secure. It might overwrite the key in the store buffer only, but not on the heap immediately, so prone to sidechannel attacks.
- java-man 7y agoThis is interesting. Could you explain this please?