whyoleg / cryptography-kotlin

Kotlin Multiplatform cryptography / crypto library
https://whyoleg.github.io/cryptography-kotlin/
Apache License 2.0
247 stars 11 forks source link

Support password hashing algorithms like Argon2, PBKDF2, scrypt, bcrypt. #22

Open elonzh opened 4 months ago

elonzh commented 4 months ago

Those algorithms are useful when developing multiplatform applications with ktor.

Jadarma commented 4 months ago

Came here looking for this. In my opinion PBKDF2 would be an amazing addition, as it would come in handy as a key derivation for the AES cypher.

whyoleg commented 4 months ago

Hey! Thanks for the interest. The story with PBKDF2 is rather straightforward (as all providers have support for it), we just need to design an API for PRF/KDF operations. So I will see how much work is needed here and will try to implement it in next release. Though, no dates, Im pretty busy right now with other stuff.

The story with other algorithms is not that easy - they are not supported by available providers, this means that they should be implemented from scratch. This will bring a precedent to the library for a cryptography operation implementation instead of usage of providers. There is no existing KMP libraries for this and wrapping some random external libraries is not an option. So this should be properly designed, and most likely will take much more time, than adding PBKDF2, so for sure it will not be available soon.

Just a check, @elonzh, will it be enough for your use case to have just PBKDF2?

elonzh commented 4 months ago

A multiplatform PBKDF2 implementation looks good for me according to Password Storage Cheat Sheet - OWASP Cheat Sheet Series.

elonzh commented 4 months ago

Can we implement multiplatform cryptography algorithms by migrating the Java code of the bouncycastle project to Kotlin?

Is that a good idea?

Jadarma commented 4 months ago

@elonzh In general, porting cryptography libraries in another language is not really feasible because cryptography is a very sensitive and bug prone area. It would involve a lot of maintenance effort to keep up to date with the reference project and back-port all the bug fixes (some of which won't be trivial because your copy isn't 1:1), and also other bugs introduced by you alone which won't be noticed and reported as quickly as in other popular projects because you lack the user base / community. For Kotlin in particular, it would also be quite cumbersome as low level libraries like kotlinx-io are still in their infancy, so you would need to reinvent a lot of wheels to be truly multiplatform. Fortunately, Kotlin has awesome integration with platform-specific code, which is why an abstraction via delegation layer like this library is possible, which in my opinion is preferable to use the closest thing to "first party" solutions on each platform under the hood, than implement the common denominator from scratch.

whyoleg commented 4 months ago

Thanks @Jadarma! I was planned to write something similar! Additional thoughts here:

  1. Licensing: while BC is covered by MIT license, it still would be better to somehow communicate with BC authors regarding copy/rewriting a lot of their stuff, just in case
  2. JDK and internal BC API usage: I fast checked how some algorithms (Argon2 and BCrypt) are implemented and saw, that to port any algorithms will require to rewrite a lot of both main and test sources, this means, that we will need not only to ensure, that cryptography operations are implemented correctly after rewrite, but also that rewritten tests are working properly. It's not something unrealistic, but it means that we will need to rewrite 11 years of history :)

Though, for now, my idea is to mostly use available providers for cryptography operations. I believe that may be, in some not so distant future, it will be possible to use OpenSSL3 on other platforms (JVM, Wasm) and so amount of available algorithms on all platforms will be increased. There is already a project which wraps libsodium in a KMP library, so it's not something unrealistic.

whyoleg commented 4 months ago

Preliminary API design (not final, just a POC): https://github.com/whyoleg/cryptography-kotlin/commit/c646bf41bbb64d1578043485b49ab43aa2416569 Also, it shows which algorithms (most likely) will be supported initially: PBKDF2, HKDF, DH, ECDH (availability of each algorithm per provider will be available later)