Best asymetric encryption scheme for logging - java

I am using java spring boot and adding functions to log exceptions.
Although I try to remove as much sensitive information as possible, I am trying to encrypt all logs that I store in case my server is breached (so no sensitive plaintext information is shown to hackers).
My plan originally was to encrypt all incoming exceptions and information about that incident using an RSA public key and store it in my database.
When it comes time for me to read through the logs, I can use my private key to decrypt the information and read it (obviously, we would never use symmetric encryption here, as if my server was hacked into, then the hacker would be able to decrypt my logs). Here comes the problem: RSA is very slow, due to it's bit length, and my server may really struggle or crash in the event of large loads of data logging.
Are there better asymmetric encryption schemes java supports that give the same amount of security that say RSA-4096 provides that are significantly quicker?
I tried ECDSA/ECDH, but that is only for signing stuff, not for string encryption and decryption.

I tried ECDSA/ECDH, but that is only for signing stuff, not for string
encryption and decryption.
If you must, you can use ECDH:
Have a securely stored EC keypair (A) (stored in some vault/secured keystore)
Give A.pub to the application
During runtime, generate a new EC keypair (B)
With A.pub and B.priv generate a common secret key (symmetric)
Store the B.pub in a database with keyId
Encrypt logging with common secret (using AES-GCM) and include keyId in the logging so you know what key was used
(for next part you might want a separate application for decrypting the logs)
When you want to read the logs: lookup B.pub in database with keyId.
Get your A.priv from your secure place
Regenerate common secret with A.priv and B.pub. (Given DH, this is same as the encryption key).
Decrypt the logs with the common secret key (again, with AES-GCM)

Related

how to securely store Masterkey in the application?

I have a spring boot java application in which all of the necessary data including clients' passwords, P12 passwords, ... are encrypted by the Masterkey.
The encryption type is Symmetric.
At the start point of the application, the operator should enter the Masterkey. On the other hand, Operators want to run the app as a service so that when the app is stopped for any reason, the Operation System is able to run the application automatically.
A bad solution is to store plaintext MasterKey in a file. (Bad Solution)
A good solution is to store plaintext MasterKey in an HSM device. But it is not possible for me at the moment.
Is there a good solution for storing Masterkey and passing it to the app in the startup of the application?

How do I tell the php backend which encryption key the Android app frontend uses?

Hardcoding an encryption key in an Android app is a bad idea - nothing new about that (see also https://medium.com/swlh/an-android-hacking-primer-3390fef4e6a0).
I found another article about encryption and a key generator which key is saved into Android Keystore (https://medium.com/#josiassena/using-the-android-keystore-system-to-store-sensitive-information-3a56175a454b) - seems like a good idea.
But: I'd like to send any information (e-mail addresses, passwords, usernames and so forth) encrypted to my backend. So I use Encryption Between PHP & Java to encrypt the data that goes over the Internet from a phone to my backend.
The method (from the StackOverflow link) to encrypt uses a hardcoded encryption key, and I avoid that by using a key generator. But my backend needs to know that key, that is created by the frontend.
How do I send this key to the backend? Encrypted with another key, that is hardcoded in my app? It's an one-time only communication between the frontend (app) and the backend (php server). Or should send the key unencrypted to the backend? Or should I execute the key generator both at the frontend and the backend - with the risk that the keys aren't equal?
Hope to get some wise words on how to make the connection secure "enough".

Decrypt TLS https data traffic

I have implemented a Java network packet sniffer similar to that proposed by
http://www.freeproject.co.in/source/Network-Packet-Sniffer.aspx?pf=Java&t=web or
http://packetsnifferusingjpcap.blogspot.it/
Now I would like to decrypt the data stream coming from an https, in an attempt to do so I set the variable SSLKEYLOGFILE, in this way the browser will write the values used to generate TLS session keys out to a file indicated by this variable see https://isc.sans.edu/forums/diary/Psst+Your+Browser+Knows+All+Your+Secrets/16415/
As it is explained in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
The file indicated by SSLKEYLOGFILE is a series of lines. Comment lines begin with a sharp character ('#'). Otherwise the line takes one of these formats.
RSA <space> <16 bytes of hex encoded encrypted pre master secret> <space> <96 bytes of hex encoded pre master secret>
CLIENT_RANDOM <space> <64 bytes of hex encoded client_random> <space> <96 bytes of hex encoded master secret>
How can I use the SSL / TLS secrets log file in order to decrypt network packages in a java code ?
Since wireshark already implements all necessary logic, you could just pipe your captured data through tshark, and parse the output text back into your application.
You could possibly also do it on your own with the help of a crypto library like bouncycastle, but it would be a lot of effort, because you would still have to parse the handshake and everything (The SSLKEYLOGFILE contains just the really secret bits, a lot of context is still needed to successfully decrypt traffic!).
To answer your specific question, you need to create a TLS client. There are a number of good TLS Java libraries available but you might give the JRE bundled Java Secure Socket Extension (JSSE) a try before trying the third-party tools. JSSE has nice integration to the rest of the Java crypto tools. To get started, you can use these JSSE samples.
If the APIs in the default JSSE implementation don't suit your needs, take a look at these two good open-source TLS libraries for Java:
The Legion's Bouncy Castle
Amazon's s2n
Once you have decrypted the packets you still, of course, need to handle the HTTP traffic. To do that you can hand the packets back to the browser, or another HTTP client library.
Note 1: the ephemeral secrets created during the TLS handshake are good for only the specific TLS session. Collecting these ephemeral secrets does not allow you to create a general proxy, as Mallory would want to mount a generic man-in-the-middle attack but it does, however, give you access to the TLS-encrypted information, so if Alice is signing into her bank, Alice's username and password would be part of the TLS-encrypted data that is now available. This is one reason, username-password schemes have poor security characteristic even if Alice creates a "strong" password.
Note 2: in TLS, Alice has to trust her TLS client, i.e., when Alice uses public terminal, Alice is trusting that her browser is Google's version of Chrome, not Chuck's or Malloy's version of Chromium.
Note 3: in TLS, Alice has to trust that only Bob has access to Bob's private key when she connects to Bob's server. If Chuck captures Bob's private key, then Chuck can proxy Bob's site without Alice noticing (and, sadly, it often takes Bob a long time to notice) -- unfortunately, there are a number of IT operational weaknesses that make this particular scenario relatively easy but that's not technical attack on TLS itself.
Note 4: Mallory could use the Key Compromise Impersonation attack as a general man-in-the-middle technical attack on TLS, if the client is vulnerable and the server obliges; KCI is mostly mitigated at this point.
You could possibly use Charles Proxy (30 day free), it is written in Java, will allow inspection of https traffic unencrypted and is much more friendly than WireShark. But Charles Proxy only handles http/https, wireshark is more general.

Java SSL: does a server and client have to have a copy of the same keystore file?

im kind of new to this and I was just wondering, in an ssl application, ideally in a real world situation, would the server and client both have copies of the exact same .keystore file, or would this be a security risk. Is there any other way to do this without the client having a copy of the actual keystore file?
No, the client and server do not need the same keystore (and usually they are not the same), although it will work if they are the same.
An SSL connection relies on asymmetric public/private key encryption during the handshaking phase switching to symmetric key encryption once the connection is established.
The basics are:
the server sends its public key to the client.
the client responds encrypting a symetric key with the servers public key.
only the server has the private key needed to decrypt the symetric key, which it does.
the client and server then use the symetric key to encrypt all the data passed between them.
Like I say that's the basics, there a little more that goes on with regards to checking certificates and the way the handshaking works as described here.
DEFINITELY NOT
It would be a major security breach for two entities to be using the same private key and certificate. The private key is meant to be, err, private, and the certificate is intended to correspond to a unique identity that owns that private key. Any violation of that principle is a fundamental security error.

Client and Server side password encryption in Java

I am making a small social network website using Java/JSP. I want to have passwords encrypted and then stored in database. I want to know is it nowadays needed to encrypt passwords client side using javascript (sha1,md5,..) and then send it to server or it is safe enough to ignore client side and just encrypt passwords at server side.
You need to transmit the passwords between the client and server via TLS (SSL). Then, use bcrypt with a cost factor of 16 or more (or PBKDF2 with 64k iterations or more) to hash the password at the server.
If you do not use SSL then there will be security holes with doing client side encryption or hashing in Javascript since a man in the middle attacker could just remove the client side hashing code before passing the page on to the user.
If you do use SSL then there is little to be gained by implementing additional client side security. The only scenario where it would be a benefit is where an attacker can compromise the encryption but not the integrity of the stream (so they can only sniff the data). This seems unlikely, but it is possible.
The additional security to prevent this would require that you first hash the password to match how the server has it hashed (so including the salt), and then hash that with a server provided randomly generated token (that the server also remembers in the session). This ensures that the password cannot be obtained by someone sniffing the connection (provided that the integrity of the stream is not compromised) as well as ensuring that the hashed version cannot be used in a replay attack (random server token prevents its reuse). If you only hash the password by itself client side then there is nothing to prevent an attacker from just using that hashed value to login themselves. Remember, this is in addition to SSL, not in place of it.
Regardless of how the password is transmitted, you should only store a salted hashed version of the password in your database. Ideally using a per user salt (that you store as well), and a secure hash function (SHA-2 for instance instead of SHA-1 or MD5).
The best way to do it is use:
SSL
Client and Server side encryption.
Option 1 is usually enough, however it can still be sniffed and thus it can be useful to send a hashed/encrypted version. This sent version shouldn't be what you store in the database though, it should have some kind of other entropy.

Categories

Resources