2

I had another question posted at Throughput for PointyCastle's aes cbc? but I don't consider this a duplicate.

I am trying to encrypt files using AES-CBC in flutter and came across the PointyCastle and Cryptography packages. Both appear to be software implementations of AES and are not using AES-NI, the built in AES instructions on modern processors. I am seeing that PointyCastle is significantly slower (15 seconds vs. 1.5 seconds for 100mb on my machine) than the Cryptography package. I have a gist created here to test both of these packages. You can add the packages with these commands:

flutter pub add cryptography
flutter pub add pointycastle

https://gist.github.com/hootyjeremy/58ff2cd7d11423f3cf5e6cd11afd6b3b

I have followed the example from PointyCastle to encrypt but maybe I'm doing something else wrong? Can you reproduce this disparity in performance also? I probably wouldn't make this post if the timings were slightly slower but to take 15 seconds for 100mb (on my machine) seems very very high.

mirkaim
  • 145
  • 1
  • 10
  • I used a different implementation with PointyCastle (`CBCBlockCipher`, `PaddedBlockCipherImpl`), but the result is comparable to your implementation and also about 8 times slower than Cryptography. My implementation allows the specification of the engine and with `AESFastEngine` instead of `AESEngine` the performance is much better and only less than 2 times slower than Cryptography. Unfortunately, `AESFastEngine` is deprecated for security reasons due to be open for timing attacks. Nevertheless, this points to the engine as a possible cause. – Topaco Sep 13 '22 at 08:45
  • 1
    By the way, in my opinion it is clumsy just for this test to derive the key with PBKDF2 in the PointyCastle code, but not in the Cryptography code. This is misleading because PBKDF2 intentionally reduces performance and you only see at second glance that the key derivation is not included in the time measurement at all. Moreover, the Cryptography code performs authentication in addition to encryption under the hood, while the PointyCastle Code does not. It would be better to compare identical functionalities. For the PointyCastle balance, this means that it is even worse. – Topaco Sep 13 '22 at 08:57
  • If you are concerned about performance, consider using Dart FFI to talk to a C implementation. Just be sure to pick one that uses AES-NI. If you aren't required to use CBC, the GCM implementation in libsodium is fast and easy to bind with FFI. – Richard Heap Sep 13 '22 at 12:47
  • @Topaco Yeah, I wasn't thinking about the key derivation since I wasn't including the initial key setup in the stopwatch timing. I switched Cryptography's macAlgorithm to empty instead of SHA256 and that only made the disparity worse, like you said, since I don't see where PointyCastle is using an hmac in it's cbc. – mirkaim Sep 13 '22 at 19:51
  • 1
    @RichardHeap thanks for the info. I had seen libsodium but the only package I found does not work with Windows which is what I'm mainly targeting. It may be that I'm not great at searching pub.dev for packages that have the specific things I need, though. I think the Cryptography package, being faster, has good enough timings for me for now but it doesn't seem to let me break large files into smaller ones and encrypt chunks while PointyCastle seems to. Cryptography wants to encrypt and pad it all inside `.encrypt()` – mirkaim Sep 13 '22 at 19:51
  • Pointycastle is even slower on Web. For AES-GCM encrypting 1MB file takes around 10s, which equates to about 100KB/s speed. I use `AESEngine`, tested on Chrome on a single main thread, my CPU `Ryzen 7 5800U`. – Tom Raganowicz Jan 03 '23 at 10:52
  • @mirkaim If you encrypt/decrypt data in chunks using Pointycastle, be aware there are few bugs which I've reported and fixed on my side, perhaps if someone from PC team will have some time they might merge it back in: https://github.com/bcgit/pc-dart/issues/182 – Tom Raganowicz Jan 03 '23 at 10:55
  • @NeverEndingQueue I ended up forking another package called `cryptography` (abandoned?) since it was a lot faster. It uses the same unsecure "fast engine" logic with pre-built tables that pc-dart deprecated but I just wanted AES-CBC for cold storage at the moment and I think the security issue might not apply to me (need to verify that). The `cryptography` package went from 100mb in 10 seconds to 1 second. I have the fork here if you're interested but it doesn't chunk AES-GCM, only AES-CBC. You might be able to update it based on my PR for Aes-Gcm: https://github.com/hootyjeremy/cryptography – mirkaim Jan 03 '23 at 19:16

0 Answers0