C 套接字和 openssl (RSA)

标签 c sockets unix openssl

我使用 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;
}

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

编辑:

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;

加密大小为 512,使用的填充为 RSA_PKCS1_PADDING

最佳答案

您假设您一口气读完了整个内容,512 sizeof (encrypted_pa​​ck) 字节。这种情况并不总是发生。您得到的可能会少于这个值,因此您应该循环read(2),直到获得完整的申请消息。

编辑0:

您正在尝试解密不完整的消息。 TCP 是一个字节流,你必须这样对待它。它不知道您的应用程序消息边界。你应该做这样的事情:

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

您应该做同样的事情 - 在循环中将字节写入套接字 - 在发送端也如此。

它可以通过环回“工作”,因为该虚拟接口(interface)的 MTU 通常约为 16K,而普通以太网则为 1500,因此 TCP 会以一个 block 的形式传输数据。但你不能依赖这一点。

关于C 套接字和 openssl (RSA),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12438352/

相关文章:

c - C 程序中的字符串

c - while 循环中的套接字和连接调用

c# - NET中的SocketAsyncEventArgs和线程安全

c - 无法创建共享内存C

python - Python 中的 'ulimit' 是什么?

c - 使用 fopen 打开文件进行读取时遇到问题

c - 如何将多个结构体连续放入内存?

python - 用户无法与代理通信

iphone - iPhone socket -3G与WiFi

unix - shell 脚本中方括号的用途