5 ms·
Show HN: MemSafeCrypto, Java cryptography primitives using DirectByteBuffer
- java-man 5y agoA subset of Bouncycastle primitives (Argon2, Blake2b, DigestRandomGenerator, HKDFBytesGenerator, Poly1305, Salsa20Engine, Scrypt, SHA256Digest, XSalsa20Engine) refactored to use DirectByteBuffer instead of primitive arrays, for the purpose of minimizing leaking information through garbage collector.
- The_rationalist 5y agoI wonder if region pinning is relevant here https://openjdk.java.net/jeps/423#:~:text=G1%20permanently%20pins%20humongous%20regions,exceeds%20a%20specified%20liveness%20threshold https://openjdk.java.net/jeps/423#:~:text=G1%20permanently%2.... Looks like a great project Javaman :)
- java-man 5y agoThank you. I would rather see maybe an annotation instructing the compiler and the runtime not to move allocated objects: @UnmovableMemory byte[] bytes = new byte[...];
- The_rationalist 5y agoYeah like https://doc.rust-lang.org/std/pin/ https://doc.rust-lang.org/std/pin/ Maybe you could propose the idea to the jdk tracker or mailing lists?https://mail.openjdk.java.net/pipermail/jdk-dev/2022-February/006368.html https://mail.openjdk.java.net/pipermail/jdk-dev/2022-Februar...
- java-man 5y agoAll my life, large corporations did nothing but ignore me. I basically gave up at this point. You are right - something like Pin in rust. It will be a new language feature, there are backward compatibility aspects, and the fact that it will need to be correctly done by all implementations (or it would fail its stated purpose). DirectByteBuffer provides a certain guarantee as it is. On the other hand, the secrets might still be leaked via paging, so even this solution is a partial one.
- skanga 5y agoAre there any docs besides the unit tests?
- java-man 5y agoIt's a replacement for Bouncycastle classes, using DirectByteBuffer wrappers to replace primitive arrays. One difference is explicit zero() method via ICryptoZeroable interface which clears the buffers.
- msgilligan 5y agoAny chance you might add ECDSA?
- java-man 5y agoI will not turn down a reasonable contract offer ;-)
- msgilligan 5y agoI'll keep that in mind, but not ready to fund it at this point.
- pjmlp 5y agoLooks quite interesting, thanks for showing it.
- cafxx 5y agoI don't see anything preventing the OS, or the hypervisor on which the OS is running, from moving/copying the memory contents around to different physical pages, or potentially to swap or even over the network (e.g. for live migration). This is obviously a step in the right direction, as it at least partially removes the JVM from the equation, but the devil is in the details and this by itself is not enough. Also worth pointing out that, according to the docs, there is no guarantee that direct buffers are allocated outside the java GC heap: > The contents of direct buffers may reside outside of the normal garbage-collected heap https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffe... A better alternative would be to actually mmap some memory for the buffer, and then use mlock/mprotect/madvise to prevent paging, unexpected accesses at the wrong time, and core dumps of sensitive materials. Still far from perfect, but already substantially better.
- java-man 5y agoYou are correct. DirectByteBuffer only guarantees that the memory will not be moved as a result of garbage collection, for example, when talking with native code. It does not prevent the OS from paging the whole memory block to disk, or writing it to a file in case of a VM saving its state. It's just marginally better than using plain primitive arrays, plus there is an extra method to explicitly clear the buffers via ICryptoZeroable, something that I think is missing from stock Bouncycastle.
- needusername 5y agomemfd_secret is probably what you want
- exabrial 5y agoBriliant, thank you! We don't have a real application for this, but just reading the code has been fascinating.