How to encrypt and decrypt data to be transmitted via sockets?

Asked

Viewed 1,192 times

1

I have a program that logs in with my server, however the connection is without any protection. I looked for some ways to protect but it seems that some of them have a pass code on the client, but I need to make the encrypted connection, and prevent the person who has the client from being able to figure out how to intercept the other users' connection, how and that I should fix this?

  • What language is used? Are you using any webserver How is Apache, Tomcat, IIS, etc, or your server a common program? I suggest simply using SSL/TLS, but to give an example I would need the language (virtually all of them have some library ready to assist with this, the most "annoying" is to properly configure the certificate).

1 answer

2


You can encrypt the data to be sent and decrypt the data to be received via sockets, using the algorithm AES.

import java.util.Formatter;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class AES {

private byte[] chave;
private byte[] mensagem;

public AES(byte[] chave, byte[] mensagem) {
    this.chave = chave;
    this.mensagem = mensagem;
}

public AES() {
}

public static void main(String args[]) throws Exception {

    byte[] mensagem = "oi".getBytes();
    byte[] chave = "0123456789abcdef".getBytes();

    System.out.println("Tamanho da chave: " + chave.length);

    byte[] encriptado = Encripta(mensagem, chave);
    System.out.println("String encriptada: " + new String(encriptado));

    byte[] decriptado = Decripta(encriptado, chave);
    System.out.println("String decriptada: " + new String(decriptado));

}

public static byte[] Encripta(byte[] msg, byte[] chave) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(chave, "AES"));
    byte[] encrypted = cipher.doFinal(msg);
    return encrypted;
}

public static byte[] Decripta(byte[] msg, byte[] chave) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(chave, "AES"));
    byte[] decrypted = cipher.doFinal(msg);
    return decrypted;
}
}

inserir a descrição da imagem aqui

I believe that one way to solve your problem is for the server to request a login and for a security measure, the client informs only the hash of this login to the server, and never in plain text. Later the server uses a key associated with that login (it can be a piece of the password hash of that user, which is already saved on the server) to encrypt the data using the AES. In the client you repeat the algorithm, hash the password and use it as the AES key. If the password is equal to the server, both will use the same key and the communication will occur in a fluid and protected way.

I think it is unnecessary for you to inform the password to the server, since with a correct decryption of the data it is already understood that the client entered the correct password. But if this is necessary, I recommend that you never send the password in plain text. Send the password hash and make sure that you are doing this safely.

Edited

At the suggestion of mgibsonbr It is interesting that you use more time consuming hash algorithms, such as PBKDF2, Bcrypt or scrypt. I believe that if you use SHA-3, but with a greater amount of iterations (1000x, for example) it will also have a similar effect.

  • The general idea is ok, but there are some details that make this approach quite unsafe: 1) "this can be transmitted publicly, without any protection" and if someone intercepts this login, will he discover the password? Login needs protection yes! 2) Use a safer mode of operation such as CBC or CTR, never the ECB. Where is the penguin? 3) Deriving a key from the password is ok, but use a slow hash like PBKDF2 or Bcrypt or scrypt, or you will be vulnerable to exhaustive search attacks.

  • @mgibsonbr why the login cannot be transmitted this way if the password will be protected? Should you pass a hash on the login as well? 2) Corrected 3) Corrected. Thank you for your suggestions, feel free to modify and increase my reply.

  • When the client sends the password to the server, if this is done in plain text anyone can intercept that password, and either run a Mitm or later log in as that user. Then everything else goes down. One option would be to use a protocol where the client does not reveal the pro server password, like SRP, another would simply be to use SSL (I’m trying to write a response to that). P.S. I was the one who denied, because point 1 is the most serious, and as your answer is accepted despite this problem, I found it necessary to signal this clearly. Correct and I withdraw.

  • 1

    I think I expressed myself badly. The idea I had is to pass the hash in the user password and use a part of this hash as a key for AES. Therefore, only the login would be informed in plain text, the client would inform the password to the server already with the encrypted data (or would not need to send the password, since the communication would already be encrypted and a correct decryption by the server is already understood that the client entered the correct password).

  • On the server, the same algorithm would be executed, because the password hash would already be in the database, just using a part of it as a key. I’ll edit my answer again.

  • Okay, it’s gotten a lot better, I’ve already withdrawn the negative vote. This strategy is not yet fully secure (it is vulnerable to replay attacks, for example, and using a part of the hash as a key negates the benefit of using a hash), but the problems are minor if done that way (without the client sending the password to the server).

  • A replay attack would be to use a network Sniffer and repeat the encrypted data? How could I improve this technique without using the hash as a password? I am developing an application where I use something similar to what I did in my answer. Can I abuse your knowledge and ask a question? This is a subject that interests me very much. = P

  • Haha I was just going to suggest this! : ) If you want to ask a question, go ahead, but if you prefer you can also call me in the chat and I explain better what I meant.

Show 4 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.