buddy-core
buddy-core copied to clipboard
buddy creates EC keypairs when namespaces are required, slowing down startup
I was wondering why my clojure app is sometimes taking ~10min to start up on this virtual machine I'm using. Looking at jstack (see below) shows that it's stuck in org.bouncycastle.crypto.generators.ECKeyPairGenerator.generateKeyPair(), which gets run when buddy.core.jwk.keys.ec is required, which is required (transitively) by e.g. buddy.sign.jwt.
The key generation is probably slow because entropy is depleted, but I haven't been able to verify this yet.
I think a suitable fix would be to (delay ...) the curve creation until they're actually used. I can provide a PR if this sounds reasonable.
jstack output
Thread 23662: (state = IN_NATIVE)
- java.io.FileInputStream.readBytes(byte[], int, int) @bci=0 (Interpreted frame)
- java.io.FileInputStream.read(byte[], int, int) @bci=4, line=255 (Interpreted frame)
- sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(byte[]) @bci=19, line=539 (Interpreted frame)
- sun.security.provider.SeedGenerator.generateSeed(byte[]) @bci=4, line=144 (Interpreted frame)
- sun.security.provider.SecureRandom$SeederHolder.<clinit>() @bci=20, line=203 (Interpreted frame)
- sun.security.provider.SecureRandom.engineNextBytes(byte[]) @bci=21, line=221 (Compiled frame)
- java.security.SecureRandom.nextBytes(byte[]) @bci=5, line=468 (Compiled frame)
- org.bouncycastle.util.BigIntegers.createRandom(int, java.security.SecureRandom) @bci=29 (Interpreted frame)
- org.bouncycastle.util.BigIntegers.createRandomBigInteger(int, java.security.SecureRandom) @bci=7 (Interpreted frame)
- org.bouncycastle.crypto.generators.ECKeyPairGenerator.generateKeyPair() @bci=22 (Interpreted frame)
- org.bouncycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi$EC.generateKeyPair() @bci=26 (Interpreted frame)
- buddy.core.keys.jwk.ec$get_curve.invokeStatic(java.lang.Object) @bci=60, line=87 (Interpreted frame)
- buddy.core.keys.jwk.ec$get_curve.invoke(java.lang.Object) @bci=3, line=83 (Interpreted frame)
- buddy.core.keys.jwk.ec__init.load() @bci=386, line=91 (Interpreted frame)
- buddy.core.keys.jwk.ec__init.<clinit>() @bci=15 (Interpreted frame)
I managed to verify via strace that the process is indeed waiting for entropy:
$ sudo strace -p 24260 | tee strace.log
strace: Process 24260 attached
read(16, "\234\30\3040\234\22", 7) = 6
^C
$ sudo ls -l /proc/24260/fd/16
lr-x------. 1 deploy deploy 64 Apr 2 09:11 /proc/24260/fd/16 -> /dev/random
just adding a quick note:
- this is on openjdk 8 & 11
- running java with
-Djava.security.egd=file:/dev/urandomfixes the immediate problem
Hi @opqdonut
That's interesting, because I've used SHA1PRNG to avoid blocking entropy waiting calls. Overall approach for getting curve parameters is flawed right now. I will try to improve it today.
PR #71 will fix this
I ran into this problem recently where my virtual machine app was taking between ~5min and ~25min to start up. I wound up downgrading from buddy/buddy-core from 1.6 to 1.4. But I just verified the workaround using -Djava.security.egd=file:/dev/urandom worked for me with 1.6.
If you had a deps.edn or pom.xml in this repo then I would have been able to use a git reference to the fixed version in my deps.edn and avoid workarounds.
Added pom.xml