I have implemented a Kerberos server/client using sockets in Java, where the client sends his service-TGT to the server, and the server knows the client is authentic.
My main concern is the snooping 'man-in-the-middle' attack. Someone could capture the TGT, and pretend to be the client.
In a pure Java implementation, this is no problem, as further communication is encrypted with the service session keys (GSSContext.wrap()/GSSContext.unwrap()), which the snooper does not have.
But the client app needs to be re-written in C#.
I figure my two options for keeping communication encrypted are:
Write my own wrap() and unwrap() methods in C#
Use SSL/TLS.
Is option 1 possible, before I look into SSL as an option?
Option 1 involves some heavy code porting which you may or not may have time to do.
Option 2 sounds good.
There is option 3 which depends on your constraints, use a private encrypted TCP channel, which should be faster than SSL/TLS, but as I said may not be applicable. It could use symmetric encryption, having initialized by the session keys (which are secret)
Related
AWS Elasticache is offering as a feature encryption In-Transit and At-Rest.
I would like to know if there is way to verify through a client if the Redis cluster you are connected to is using At-Rest Encryption and/or In-Transit Encryption.
It seems logical that the client would know about In-Transit, but I would like to know if it is possible to verify both using the most common Java Redis client libraries.
The feature that I have in mind would require safe temporary storage for caching some data, and if an encrypted Redis instance is not available the intention is to fall back to something else, or prompt a warning that the storage might be unsafe for the data being stored.
For In-Transit Encryption, you could try to connect with a client (Jedis for example) that has ssl option disabled. If it could not connect, try ssl option enable. If first try failed, and second try succeeded, that means In-Transit Encryption is in place.
For At-Rest Encryption, the only way I'm aware of is using AWS SDK to describe the cluster and see if the field is true. https://docs.aws.amazon.com/cli/latest/reference/elasticache/describe-cache-clusters.html (This also would help on In-Transit Encryption).
I want to write a secure method of authentication over TCP sockets in Java. I've read reasonably extensively on the subject, but I am by no means an expert. There seems to be a bit of variance in opinion on how this is best done.
I know pretty well had to generate my password hashes, but that doesn't do me a whole lot of good if an attacker can simply glean the passwords/password hashes while in transit. So I want to create a reasonably secure method of sending this data across.
The most popular method seems to be using SSL sockets. However, my code will not be used as a single server (as an online game might be) but instead will have many instances run by various consumers. I personally don't have a means to purchase an SSL certificate, and I can't really ask my consumers to do that either. Creating self-signed certificates and then installing them in a keystore for each client seems both difficult and a little insecure. If I were handling all server instances, this would be a much more viable option, since I would only need one certificate, but as it stands now
So I worked on simply securing the TCP socket while performing log ins. I can do this pretty well using a Diffie-Hellman algorithm. However, as I research this, people kept saying to use SSL instead.
How can I securely transmit passwords over Java TCP sockets in an efficient but portable manner?
You can use the Diffie-Hellman key exchange algorithm. This is exactly for your use case, to exchange keys over a public network. See the Oracle Diffie-Hellman example.
Have you considered RSA encryption? RSA encryption is the same encryption that SSL uses:
https://en.wikipedia.org/wiki/RSA_(cryptosystem)
If I am using any of the TLS_PSK_* cipher suites, then all I need to use some pre-shared key among client and server for encrypting and decrypting the message.
Would it matter whether I am sending the encrypted message over normal Socket or SSLSocket? How?
Although it is not impossible to create a secure connection yourself (which I presume you are hinting at) there are so many pitfalls that the answer is usually "yes". Use TLS if it is available, the newer the protocol & ciphersuite the better...
We have a multiclient system where the client is written in Flash and the server is written in Java. Currently, communication is done in Flash by usage of flash.net.Socket and the protocol is written in JSON. The server uses a custom port to receive connections and then proceed to talk with each client. As expected, data is sent and received on both fronts as raw bytes, which are then decoded as needed.
We would like to encrypt the communication between clients and server. I have some basic understanding about public/private key encryption, but I do not know what is the best way to exchange keys or what libraries are available (on both languages) to do this.
What would be the best strategy to attack this problem and where should I start looking for libraries/methods to implement this encryption?
No need to reinvent the wheel. Use ssl/tls. There's an as3 ssl implementation that we've used in several commercial projects. Make sure you create a root cert store for the as3 component and populate it with at least the root ca for your server cert. On the server, use java's built in ssl server socket.
Alternatively, you could do away with the custom server, if this is at all possible, and use https, kind of like you would with Ajax in HTML/JavaScript.
I have two java applications that need to talk to each other over an encrypted TCP socket, but they don't need to authenticate each other (one will accept() a connection from the other). Can anyone point me to a tutorial/code-snippet that will help me set these up?
I'm looking for something fairly simple and I'd like to not have to supply any keystore or truststore material.
EDIT: I should be more specific here. I meant that they don't have to authenticate each other via SSL. I have some non-trivial authentication that I have to do at the application level, so I can't use any sort of SSL-based authentication scheme.
Also, some of the links in the answers posted so far (as of noon 3/10/2010) require keystore files. Is there a simple way I can programmatically generate the keys I need?
To reiterate Chris Jester-Young's advice - if you don't have authentication, then you might be communicating securely, but you have no idea who you're communicating securely with. You could simply be communicating very securely with the bad guy himself (who is relaying everything you're saying onto the person you hoped you were talking directly to).
However, there is a quite lightweight authentication scheme that might suit your purposes, called TOFU (Trust On First Use). This is where you use SSL and generate self-signed certificates for each side - however you do not skip certificate validation. Instead, on the first connection with a given peer you accept any certificate and store it locally; on subsequent connections with that peer, you only accept that saved certificate. This is similar to the way that ssh works by default for host authentication, and provides authentication of the "the guy I'm talking to now is the same guy I was talking to yesterday" variety.
You can use the anonymous Diffie-Hellman ciphersuites if you insist on ignoring Chris Jester-Young's sage advice. Those ciphersuites are not enabled by default, you have to explicitly enable them, for example by using the SSLSocket.setEnabledCipherSuites() method.
If you absolutely do not want to use SSL with certificates, you can roll your own, though it won't be as secure obviously. I'm just improvising here, mixing a little asymmetric crypto with port-knocking.
First, create a random RSA key pair in the client, in-memory, no need to store it anywhere. Client then connects to server using a plain Socket, and upon connection, sends the server the public key (encode as you wish, so that you can read it easily on the server). Server then generates a random 128-bit key, starts ANOTHER ServerSocket in a random port, and encrypts the 128-bit key and the new server port number, using the client's public key, and sends the data back to the client. Server must wait for a short period of time to receive a connection from the same client on the new port.
Client closes connection, deciphers data, and opens a new Socket to the server on the specified port. Then both client and server must wrap the socket's InputStream and OutputStream on a CipherInputStream and CipherOutputStream using AES/CBC/PKCS5Padding (or RC4 if you prefer) with the specified 128-bit key. Voilá, you have a secure connection between client and server, without any authentication.
If you want to handle authentication you can do so over the secure connection, or on the first connection the server can have RSA key pair as well, they exchange keys and the server can send a challenge to the client (the server sends the challenge to the client using the client's public key and the client responds to the challenge using the server's public key). But that's unnecessarily complicated and I think you'd be better off using standard SSL with keystores anyway... perhaps you can get create an in-memory KeyStore on the client and send it to the server as explained above using the first connection (encrypt the keystore with the server's public key) and then you can set up the second connection to use SSL with that keystore which is temporary and will be discarded when the client disconnects.