クライアントとサーバーの間に2つのチャネルを確立する必要があります。最初はデータ送信用のUDPチャネルで、もう1つは鍵を送信するためのTCPチャネル、UDPチャネルのAES-128ではivです。openSSL:解読が正しいプレーンテキストにならない
次のようにTCPソケットがサーバーで作成されます。
listen_fd = socket (AF_INET, SOCK_STREAM, 0);
// sa_serv contains TCP port
error = bind(listen_fd, (struct sockaddr*) &sa_serv, sizeof (sa_serv));
次のようにUDPソケットがサーバーで作成されます。
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
// local contains UDP port
error = bind(sock_fd, (struct sockaddr*) &local, sizeof(local));
Serverは、複数のクライアントに接続できるようにする必要があり、 TCPおよびUDPソケットは、次のようにselect()で使用されます。
max = (listen_fd > sock_fd) : listen_fd : sock_fd;
fd_set set;
FD_ZERO(&set);
FD_SET(listen_fd, &set); FD_SET(sock_fd, &set);
while(1)
{
select(max + 1, &set, NULL, NULL, NULL);
if(FD_ISSET(listen_fd, &set){
// server accepts connection
// server receives key and IV over TCP connection
}
if(FD_ISSET(sock_fd, &set){
// server receives encrypted data from client using UDP socket
}
}
サーバーがデータiを受信するとn UDPソケットでは、サーバーはTCP接続を使用して受信したキーとIVを使用してそれを復号化します。クライアントから受信した暗号鍵とIVと一緒に、この関数に渡され
int decrypt(unsigned char *plain, unsigned char *key, unsigned char *iv, unsigned char *cipher, int len)
{
int i;
unsigned char buf[3000];
int outlen, tmplen;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
if(!EVP_DecryptUpdate(&ctx, buf, &outlen, cipher, len))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
if(!EVP_DecryptFinal_ex(&ctx, buf + outlen, &tmplen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return 0;
}
outlen += tmplen;
EVP_CIPHER_CTX_cleanup(&ctx);
printf("\nLength decrypted :%d\n",outlen);
printf("\nBuf: ");
for(i=0; i<outlen; i++){
plain[i] = outbuf[i];
printf(" %02x ",buf[i]);
}
printf("\n");
return outlen;
}
が、結果プレーンテキストが正しい(8周りのバイトが間違っている)であることが判明していない次のように復号化コードがあります。さて、暗号が間違っているかもしれないと主張するかもしれないし、鍵やivが問題を抱えているかもしれません。私はそれらのすべてを検証した。
しかし、私のサーバーが1台のクライアントにしか接続されていないと思うと、復号化コードが正しく解読されるという奇妙な状況があります。 select()でTCPソケットを使用せずにselect()を使用して接続を受け入れるとき&キー/ ivをただ1つのクライアントから取得する(接続を受け取り、クライアントからキー/ ivを受け取るコードは正確ですselect()内で使用した場合と同じ)、select()でUDPソケットを使用してデータを送受信します。受信した暗号化データが正しく解読されます。
私が理解できないことは、select()fd_setにTCPソケットを置くことによって、なぜ同じ暗号化コードが問題を作り出しているのか、ということです。正しい暗号、鍵、IVを得ることができます。
誰でも説明がありますか?
ありがとうございました。
TCPソケットでkey/ivを送信することをお勧めしますか?鍵交換プロトコル(SCEP ?!)を使用する必要があります。 –