0

使用 RSA 在我的客户端/服务器套接字中有一些奇怪的东西。如果我在本地主机上测试它,一切都很好,但是如果我把客户端放在电脑上,服务器放在其他电脑上,就会出错。

客户端调用connect后,调用与服务器交换公钥的方法。这部分代码工作正常。在此之后,客户端向服务器发送请求:

strcpy(send_pack->op, "help\n");
RSA_public_encrypt(strlen(send_pack->op), send_pack->op, 
        encrypted_send->op, rsa_server, padding);

rw_value = write(server, encrypted_send, sizeof (encrypted_pack));
if (rw_value == -1) {
    stampa_errore(write_error);
    close(server);
    exit(1);
}
if (rw_value == 0) {
    stampa_errore(no_response);
    close(server);
    exit(1);
}
printf("---Help send, waiting for response\n");
set_alarm();
rw_value = read(server, encrypted_receive, sizeof (encrypted_pack));
alarm(0);
if (rw_value == -1) {
    stampa_errore(read_error);
    exit(1);
}
if (rw_value == 0) {
    stampa_errore(no_response);
    close(server);
    exit(1);
}
RSA_private_decrypt(RSA_size(rsa), encrypted_receive->message, 
        receive_pack->message, rsa, padding);
printf("%s\n", receive_pack->message);
return;
}

但是当服务器尝试在服务器端解密接收消息时,“帮助”字符串不会出现。这只发生在网络上,在本地主机上,相同的代码工作正常......

编辑:

typedef struct pack1 {
unsigned char user[encrypted_size];
unsigned char password[encrypted_size];
unsigned char op[encrypted_size];
unsigned char obj[encrypted_size];
unsigned char message[encrypted_size];
int id;
}encrypted_pack;

encrypted_size 是 512,使用的填充是 RSA_PKCS1_PADDING

4

1 回答 1

0

You are assuming that you read the whole thing, 512 sizeof (encrypted_pack) bytes, in one go. This doesn't always happen. You can get less than that, so you should read(2) in a loop until you have your complete application message.

Edit 0:

You are trying to decrypt not complete message. TCP is a stream of bytes, and you have to treat it as such. It doesn't know about your application message boundaries. You should be doing something like this:

char buffer[sizeof( encrypted_pack )];
size_t to_read = sizeof( encrypted_pack );
size_t offset = 0;

while ( true ) {
    ssize_t rb = ::read( fd, buffer + offset, to_read - offset );
    if ( rb == -1 ) { /* handle error */ }
    else if ( rb == 0 ) { /* handle EOF */ }
    else {
        offset += rb;
        to_read -= rb;
        if ( to_read == 0 ) break;
    }
}

// handle complete message in buffer

You should do the same - write bytes into the socket in a loop - on the sending side too.

It "works" over loopback because MTU of that virtual interface is usually around 16K vs. 1500 for normal ethernet, so TCP transfers your data in one chunk. But you cannot rely on that.

于 2012-09-15T21:35:57.870 回答