I need to make two java proceses on the same host to communicate securely. I do not need to authenticate the processes so I don't want to use certificates.
I want to generate a random key in the server and client, exchange the keys between the processes using Elgamal; establish common symmetric key across the processes; and then communicate securely.
As far as I can think of, this can be done by implementing RMIServerSocketFactory and RMIClientSocketFactory interfaces to establish symmetric key as discussed above.
Is there already an implementation to do that?
Or is there a way to configure SslRMIServerSocketFactory and SslRMIClientSocketFactory to start using ElGamal as the key exchange protocol
ElGamal is preferred choice over RSA as ElGamal will generate random symmetric keys for each handshake while RSA will generate static keys every time.
I need to make two java proceses on the same host to communicate
securely. I do not need to authenticate the processes so I don't want
to use certificates.
Your reasoning is flawed from the start unfortunately. However "hardened" a communication channel is, you'll always want to make sure you're communicating with the intended party if you want to exchange data secretly. Authentication in one form or another is necessary to do so.
In theory, you can do away with certificates and use PSK cipher suites (which would effectively include the authentication step). This isn't supported by default with the Oracle/OpenJDK JRE. In addition, if you're working on the assumption that your certificate's private key would be compromised (as suggested by your other question), the same problem could happen with the pre-shared keys anyway.
Related
I'm writing a CMP server and I have a problem.
It is used in a centralized PKI where the RA send a private key with the associated certificate to the server, that we have to relay to the CMP client.
The problem is that I can't find how we are supposed to encrypt the private key to send it to the client and for him to be able to decrypt it.
Do we only rely on the security of https, because it sounds wrong ?
Did I miss something in the CRMF RFC ?
A solution would be, I guess, to generate a temporary keypair from the client and use it for encryption/decryption but is sounds more like a hack than the way to do it properly.
It is easy to do when the client is the one generating his keypair, but in this specific case, everything is generated by our OpenTrust RA.
PKCS#12 can be used to distribute private keys from an RA to the various clients. We have used a hardware USB token for this purpose. Data on the USB token can only be decrypted by the software on the client side (using a pre-shared secret).
If you don't want to use hardware tokens, the only option you have is to use a pre-shared secret (communicated via some out of band/out of channel means) and use that symmetric key to distribute the private key and transmit it over HTTPS. Also make sure your HTTPS is configured to use at least AES-256.
I have SSL working between two Android devices running the same app using a self-signed cert and key generated using openssl and stored in keystores.
The problem is that the private keystore must be embedded in the app package somehow, and therefore becomes available to any attacker. I believe this would allow an attacker to snoop on the session and decrypt the data between the two phones.
I'm not using or requiring any of the other features of PKI, I'm just providing two keystores because the SSL connection setup requires them.
Is there a secure SSL cipher that does not need predefined PKI and generates its own keys on the fly at runtime?
I have investigated generating my own keys at runtime - creating the keys is easily done in Java but the KeyStore.setEntry() requires an an X509 certificate chain not just the public key, and Android does not contain the JCE code to generate the X509. I can do that by including the BouncyCastle (Android compatible version is called SpongyCastle) library but that adds quite an overhead to my app package size.
There is no access to a third-party trust server on the internet, the two phones could be on a private WLAN with no internet access.
As a nice-to-have bonus I'd like to be able to trust that the app is communicating with itself, not someone sniffing the protocol from a PC, but I don't think that's going to be possible as the app package contents will always be available.
To ensure you are talking to something/someone you trust, you need a mechanism of authenticating the other party. I'm not aware of a way to achieve this without a piece of data remaining secret:
Asymmetric authentication (i.e. your current implementation) requires the private key data to remain private.
Symmetric authentication requires that the shared secret remains private.
In the future, TrustZone will allow applications to store secret data in the secure element of the handset. Until that time, however, you are always at risk of malware on your devices. Adding a password to your keystore (that the user knows, not the app) might add an additional hurdle to an attacker, however once the phone is infected then the password can be snooped.
To minimise your risk profile you should produce per-device keys, rather than a single cert/key-pair combo that you incorporate into your application. This will, of course, increase the effort required to add new users as some form of registration will be required (e.g. certifying their key). Alternatively you can push the problem out to your users and have them decide who to trust, PGP-style.
I was thinking of implementing Diffie-Hellman on android mobile systems. In this application two sides say A and B generate keys which are later exchanged to get the common secret key.Android provides support for generating the keys but i want to know what would be the most secure to conduct the exchange. If the method used for exchange is not secure it completely defeats the purpose of using this method.
Why not use your web server as a interface, which creates the corresponding public and private key, and uses it for encryption and decryption? Make sure you even encrypt the way the keys which are sent b/w server to application are encrypted.
I am trying to make a PHP script to interact a with a Java application. They will share some information, so I would like to encrypt the data that is passed between them to make it as secure as possible, on top of having an SSL certificate. However, because my website is only on a shared server at JustHost, as far as I am aware I can not use the 'mcrypt' PHP module, so I'm not sure how to do it so that both my Java application and the PHP script can encrypt data being sent and decrypt data being received!
Your SSL conversation between Java and PHP will protect it your data while it's in transit. Should you properly protect the private key with a strong password (10+ symbols) and make sure your algorithms strong no one will be able to break it by snooping on the conversation.
You won't get any extra protection by encrypting the data before sending it over the SSL conversation. And you actually might be weakening your security because in order for you to encrypt data you'll have to share some key should you choose symmetric encryption. And, by trading secret keys you're undoing much of the protection SSL gives you because the huge benefit of SSL is the fact we can encrypt data without agreeing on a secret key. If I were trying to get at your encrypted text I'd attack your client because it's easier to find your symmetric encryption key than it is to break SSL. And while you could use asymmetric encryption you'll be basically re-inventing SSL.
I would focus on making sure your SSL conversation is strong. Using only the strongest symmetric encryption: TripleDES, IDEA, AES if your server supports it. Take out the weaker algorithms so conversations can't use the weaker encryption. Generate 1024+ public/private key pairs. That might not always be easy on your shared server, but your Java application could only choose to use TripleDES, IDEA, and AES.
Make sure you validate the server's certificate on the client side so you ensure you aren't talking to a false service. That basically means taking the server's certificate and adding it to the keystore used on the client. If that's Java you can use keytool to import a certificate and use that keystore as your TrustManager/KeyManager in your SSL conversation.
If you want to encrypt the data after it's gone over the SSL conversation then you can encrypt/decrypt on the server only. But, you still have a key management problem. If you encrypt/decrypt how do you plan on securing the secret key on the server? That's always the ugly problem that doesn't have a simple answer.
A friend and me are working on a Java Game with a client/server - architecture.
It is working well, but i ran into a problem.
We use TCP Sockets for networking between server and client.
Our network protocol isnt encrypted and can just be read by anone who bothers to watch the stream.
We thought about how we could apply some kind of cryptography to it to hide login information and prevent people to write their own clients. But basic things like adding/substracting bytes seems pretty easy to figure out.
What are the usual methods used to encrypt network communication for games( or at least game login information )? And having written the server and client in java, are there any useful java libraries?
Use public-key encryption (RSA for example) and implement something like the SSL Handshake, or of course use SSL - here you can see an example.
Here's a simplified sequence:
the server sends his public RSA key to the client
the client generates a symmetric key (using AES for example)
the client encrypts the symmetric key with the server's public key and sends it to the server
the server decrypts the received symmetric key
Now both the client and the server have a key which no one eavesdropping can know. Then use that key to encrypt all data.
SSL(Secure Sockets Layer) is popular to handle this kind of problem.
Look at the javax.crypto library or bouncyCastle.
Both provide cryptographic primitives, also for encryption. Depending on how secure you want to have it, you can use symmetric or assymetric crypto. However, also think about key management in advance. Where do you store your private/shared key.
If it is a client-server, the best way would be to use assymetric crypto (i.e. RSA, Elliptic Curve) and give every user a certificate signed with the key of the server (note, this is TLS (formerly called SSL)). This way you can check if the user logging on is authentic. However, you dont prevent custom clients since the user has to have everyone can just copy the certificate.
In practice, it is quite hard to prevent custom clients.
You can use Ciphers. Some more examples here and here