invesdwin / invesdwin-context-integration

invesdwin-context modules that provide integration features
GNU Lesser General Public License v3.0
1 stars 0 forks source link

implement channel for netty-tcnative-boringssl #19

Closed subes closed 1 year ago

subes commented 2 years ago

tcp transport with ssl encryption (ideally a native epoll socket) https://netty.io/wiki/forked-tomcat-native.html

maybe there is also a way to use this with nio sockets?

subes commented 1 year ago

we could implement our own pipeline for encryption similar to FragmentSynchronousWriter/FragmentSynchronousReader

Here the ticket where an application-side solution like this is discussed at aeron: https://github.com/real-logic/aeron/issues/203 And here a discussion at akka: https://github.com/akka/akka-meta/issues/16

subes commented 1 year ago

AES implementation in java uses AES-NI nowadays and has acceleration for GCM: https://github.com/gerritjvv/crypto/tree/master/crypto-perf

(c code) https://github.com/kasbekarameya/AES-NI-Encryption

(could also use CTR mode, though GCM is supposed to be better) https://stackoverflow.com/questions/53706907/extremely-slow-built-in-aes-encryption-with-java

(GCM example) https://github.com/gerritjvv/crypto/blob/master/crypto-core/src/main/java/crypto/AES.java (though should use zero-copy and reuse objects)

(could also use google tink which supports key rotation, though I think key renegotiation is more interesting?) https://github.com/google/tink/blob/master/docs/JAVA-HOWTO.md


XChaCha20 with Poly1305 could be an alternative to AES256-CTR-HMAC256: https://crypto.stackexchange.com/questions/84081/how-to-choose-parameters-for-argon2-for-a-password-vault => nope, performance can not compete: https://www.bearssl.org/speed.html

subes commented 1 year ago

We can encrypt any package using SSLEngine like this (we can then use tcnative openssl/boringssl and jdk impl):

https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/test/jdk/javax/net/ssl/DTLS/DTLSOverDatagram.java

(source https://stackoverflow.com/a/57512677)

More sources for DTLS: https://github.com/mobius-software-ltd/java-dtls https://github.com/snf4j/snf4j

subes commented 1 year ago

commons-crypto seems to support a AES-NI binding via JNA nowadays: https://mvnrepository.com/artifact/org.apache.commons/commons-crypto/1.1.0

subes commented 1 year ago

TODO:

subes commented 1 year ago

HMAC-SHA256 signature is used by signal messenger to ensure messages are not corrupted: https://soatok.blog/2020/05/13/why-aes-gcm-sucks/

here how this could be added to a stream: https://www.javatips.net/api/conceal-master/benchmarks/src/com/facebook/crypto/benchmarks/mac/streams/MacLayeredInputStream.java

Akka also planned to use HMAC-SHA256: https://github.com/akka/akka-meta/issues/16

First verify mac, then work on the data: https://moxie.org/2011/12/13/the-cryptographic-doom-principle.html (mac the encrypted payload)

https://netnix.org/2015/04/19/aes-encryption-with-hmac-integrity-in-java/ https://stackoverflow.com/questions/7124735/hmac-sha256-algorithm-for-signature-calculation


Don't use the same key for AES and HMAC, instead derive two keys from the secret (which can also then be shorter than the required key length): https://crypto.stackexchange.com/questions/8081/using-the-same-secret-key-for-encryption-and-authentication-in-a-encrypt-then-ma https://crypto.stackexchange.com/questions/76588/multiple-aes-key-derivation-from-a-master-key

We can also expand an IV from this: https://stackoverflow.com/questions/45985661/is-hkdf-implemented-in-java-cryptography-architecture (we then send the counter instead of the whole IV)

HKDF impls:


Though HKDF can only be used with random enough keys. When using a password that is not strong/random enough, one should instead use bcrypt or PBKDF2 to strenghen/stretch the password. https://crypto.stackexchange.com/questions/46550/benchmark-differences-between-sha-512-and-bcrypt

Bcrypt could also be used with a salt before using HKDF: https://security.stackexchange.com/questions/71566/encryption-and-hmac-with-the-same-password

I guess the best approach would be to create a TLS connection using private/public keys, exchange a randomly generated key through that and then use HKDF to derive the other keys from that random key.

A less secure way to do this would be to SHA-256 a password and then use the first 128 bits and the last 128 bits is independent keys. (https://crypto.stackexchange.com/questions/8081/using-the-same-secret-key-for-encryption-and-authentication-in-a-encrypt-then-ma)


Confirms that a combination of Password+PBKDF2+HKDFexpands//Random+HKDFextract+HKDFexpands are they way to go: https://crypto.stackexchange.com/questions/20960/pbkdf-vs-hkdf-for-pretty-long-key We can derive AES-KEY, AES-IV, MAC-KEY from this.

Password+PBKDF2+HKDFexpands is also used by firefox sync: https://blog.mozilla.org/services/2014/04/30/firefox-syncs-new-security-model/ (the last paragraph)

Don't use the same salt for multiple keys: https://security.stackexchange.com/questions/48000/why-would-you-need-a-salt-for-aes-cbs-when-iv-is-already-randomly-generated-and

Bcrypt is better than Scrypt (until it is proven, which it is by now) and PBKDF2 (easily cracked by GPUs): https://medium.com/@mpreziuso/password-hashing-pbkdf2-scrypt-bcrypt-1ef4bb9c19b3 Argon2 is better than Scrypt or Bcrypt: https://medium.com/analytics-vidhya/password-hashing-pbkdf2-scrypt-bcrypt-and-argon2-e25aaf41598e

Native Argon2 has the benefit of support parallelization and using off-heap memory: https://github.com/phxql/argon2-jvm So we use that as the winner.

subes commented 1 year ago

TODO:

subes commented 1 year ago

HMAC256 is very slow. CMAC with AES would be a better option: https://crypto.stackexchange.com/questions/52009/fastest-algorithm-for-message-authentication https://stackoverflow.com/questions/60670117/cmac-aes-rfc-4493-calculation-in-java

A native SHA implementation: https://github.com/nayuki/Native-hashes-for-Java Though better to use the amazon native provider: https://github.com/corretto/amazon-corretto-crypto-provider (as discussed here: https://stackoverflow.com/a/59166873) Should check if corretto is faster than commons-crypto, in that case use JCA in commons-crypto if corretto is enabled (only on linux, commons-crypto can then still be used on windows and mac).

Another alternative would be GMAC: https://stackoverflow.com/questions/48548394/how-to-verify-a-gmac Though no padding is required for AES/GCM mode: https://crypto.stackexchange.com/questions/42412/gcm-padding-or-not

Though should also implement CtrCryptoInput/OutputStream for AES/GCM, might be faster than AES/CTR+[H|C|G]MAC with amazon corretto provider.

subes commented 1 year ago

https://github.com/wildfly-security/wildfly-openssl another native binding (only for SslEngine)

commons-crypto does not bind to openssl 3.0.2 and has no embedded version: https://issues.apache.org/jira/projects/CRYPTO/issues/CRYPTO-164

conscrypt also has many ciphers based on boringssl: https://github.com/google/conscrypt/blob/master/common/src/main/java/org/conscrypt/OpenSSLProvider.java Seems to have everything that commons-crypto has. Need to also check if SecureRandom implementation uses intel instructions.

subes commented 1 year ago

done and working. performance tests and docs will be handled outside of the ticket