-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extremely slow RSA key generation on web #113
Comments
Cc @mwcw: didn't you change JS random number generation? Maybe the issue is direct usage of the entropy source; we can probably seed Fortuna with the source instead and then pull from that, which should be faster. |
@tjcampanella I would recommend investigating the isolate idea to work in the background, at least as a hotfix to avoid freezing UI. I have an idea for an internal fix (above), but I'm not sure how feasible it is. |
@AKushWarrior Thank you for the quick response, I appreciate you and the rest of the contributors on making a great package. I will see what I can do with an isolate. |
@tjcampanella the issue might be in your code, actually. I noticed that you have Otherwise, I'll keep looking. It looks like rsa keygen isn't calling the seed method, so the only slowdown would be the seeding on construction of Fortuna (or, more concerning, that Fortuna itself is slow on web). |
@AKushWarrior This method is only called when a new user signs up. So it would normally just be getting called once per device, unless the user decides to make more than one account. And I am seeding it just doing that elsewhere and I know it gets past that part in a reasonable time. It gets stuck in this function. |
Hi, Yes it takes ages.
Let me know how you go. |
@mwcw I haven’t tried the code yet, but don’t you need to call the generateKeyPair method? Otherwise it isn’t generating the pair right? |
Sorry yes, that was an own goal. Yes it does take a long time. |
@mwcw No worries. You just got me excited for a second there lol. |
Ok that took about 370 seconds. A 2048 bit key is taking between 6 and 8 seconds. I cannot offer you an solution off the top of my head, I'll need to take a solid look at it. MW |
@mwcw Are you running on chrome in release mode or debug mode? Also I tried using 2048 earlier and it was still taking a while is there something noticeably different with the code I used? |
I just hacked up one of the tests, running it using: pub run test -p node test/key_generators/rsa_key_generator_test.dart I just had a run at 28 seconds on node and 12 seconds on chrome. Those times makes it impractical. |
Do you have any ideas about why there is such a difference in performance across mobile to web. On mobile it takes a couple seconds vs on web taking much longer. I am just wondering what are my options to run and use the library in the most performant way. Thanks for looking into this. |
I'm also using 4096bit keys, but on android, not on web. I've isolated the workload, maybe you wan't to take a look: Even on android, key generation takes about 5 seconds. I wonder if using an other random (like the on from dart directly, see #110) could speed things up? |
I have a sneaking suspicion that random number generation is not the culprit here, because it wouldn't be much slower on web than native, and the issue would not be localized to RSA. The issue might be BigInt arithmetic; RSA key generation is one of the only algorithms that uses BigInt, so that would explain why the issue is so localized. Would someone who has a testing setup mind profiling the keygen method to check where our bottleneck is? |
This comment has been minimized.
This comment has been minimized.
Maybe you could copy that to #110 so we can do the dart Random discussion there and stopp abusing this issue 😄 |
This comment has been minimized.
This comment has been minimized.
@AKushWarrior @mwcw Have either of you thought about possible solutions to this? I am unsure how to handle the long times on the web. I don't want to have to use 2048 bit keys. |
Generating 4096bit keys is a heavy operation that is usually done a lot closer to the machine than where js normally sits. As has been pointed out it is a 5 second generation time on Android and I know that implementation is a thin java wrapper that offloads some of the work to native code. I was considering doing an experiment and reaching out to either crypto on nodejs, or the crypto web api that seems to be present in all modern browsers and offload the work to that but I am not going be able to get to that in the short term. The only suggestion I can offer you right now is to generate the keys ahead of using them in the background or reach out the the underlying nodejs platform and generate the keys there but I suspect you will still need to generate the keys ahead of using them. Even on the JVM on a late model CPU it takes between 1 and 2 seconds to generate a 4096b RSA key pair. MW |
@mwcw if we're offloading work through interop, we should probably use WASM to get closer to native performance. I can investigate that. |
Generating them on mobile taking a few seconds I think is fine. The problem is on web taking minutes. I know there is another package called fast_rsa. I don’t believe you can seed their key generator though. Maybe you guys can find some insight from that package? I haven’t looked at their code or anything just the name saying fast_rsa is why I mention it. May be worth while I’m not sure. I appreciate both of you looking into this, I will have to do more research and figure out a solution. If I find anything of note I will mention it here. |
Is fast_rsa... faster than pointycastle? On web? I can take a look and do a rough diff of the code, but I don't want to waste my time chasing a red herring when that could be spent figuring out a JS interop solution. |
@AKushWarrior I don’t know if it is or not I just saw it and figured it would be worth mentioning. I haven’t done any comparisons as of now. I am just suggesting a potential lead. I will be looking into this issue more myself in the coming days. |
Yup, makes sense. If you do end up getting around to doing a comparison, let us know; it's possible that this is a bug in our particular implementation of RSA keygen, but it's hard to pinpoint it without a working example. |
@AKushWarrior The fast rsa web implementation seems to be running in web assembly directly. That is probably their claim to fame and why they used fast in their plugin title. I will do a comparison soon and show the results here. |
That's essentially what I'm proposing above. WASM is way faster than anything else on web (JS or transpiled Dart, more or less the same thing). |
@AKushWarrior I tested their generation for a 4096 key and it still took about a minute on web. It seems like generating 4096 bit keys on the web isn't feasible. I may have to switch to using 2048 bit keys. |
Well, it's FEASIBLE, as long as you wrap it in a model of concurrency; if you return to the isolate idea, that might be the best "solution". If the UI is completely dependent on the key, then yeah; 4096 bit RSA key generation is just too computationally intensive to work in that situation. |
Isolates on the web aren’t as easy as just calling the compute function on mobile. I will have to do some research on how to do it. Either way I am generating the keys at user sign up and I guess I can have it work in the background and then once they are ready allow the users to private message, but I didn’t wanna have to do that. I will have to figure something out. |
Is there any new information on this? |
any updates about this issue ? |
any updates? still the problem persists... |
Is there any news about the problem? Maybe now with Dart 3 |
any updates? thanks |
I have found a way around this for my application. Perhaps this can also help others if it doesn't necessarily have to be RSA in particular, but (as in my case) a secure key exchange with another asymmetric method is sufficient. For me, ECC works very well. It also works on the web without any problems, probably because the key length has to be significantly shorter than RSA to achieve the same cryptographic strength - 256-bit ECC corresponds to around 3072-bit RSA. More: |
Will this ever patched ? |
I am unsure if I am doing it wrong or something, but on the web using the function below to generate a RSA key pair takes over a minute if it even finishes it freezes the entire UI during the process. I have tested and I know for a fact it is getting stuck at this function. I know I could be doing this in an isolate however, the way I am generating the keys now is when a new user signs up and then I am sending a request to the server with the public key. If anyone recommendations please let know.
static AsymmetricKeyPair<PublicKey, PrivateKey> getRsaKeyPair( SecureRandom secureRandom) { var rsapars = RSAKeyGeneratorParameters(BigInt.from(65537), 4096, 5); var params = ParametersWithRandom(rsapars, secureRandom); var keyGenerator = RSAKeyGenerator(); keyGenerator.init(params); return keyGenerator.generateKeyPair(); }
The text was updated successfully, but these errors were encountered: