SSL सॉकेट में एक साधारण सॉकेट चालू करें


115

मैंने सरल सी प्रोग्राम लिखे, जो सॉकेट ('क्लाइंट' और 'सर्वर') का उपयोग कर रहे हैं। (यूनिक्स / लिनक्स उपयोग)

सर्वर साइड बस एक सॉकेट बनाता है:

sockfd = socket(AF_INET, SOCK_STREAM, 0);

और फिर इसे सदकाड्रा में बांधता है:

bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

और सुनता है (और स्वीकार करता है और पढ़ता है):

listen(sockfd,5);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
read(newsockfd,buffer,255);

क्लाइंट सॉकेट बनाता है, और फिर उसे लिखता है।

अब, मैं इस सरल कनेक्शन को SSL कनेक्शन में, सबसे सरल, सबसे रमणीय, सबसे साफ और सबसे तेज़ तरीके से परिवर्तित करना चाहता हूं।

मैंने अपने प्रोजेक्ट में ओपनएसएसएल को जोड़ने की कोशिश की है , लेकिन मुझे जो चाहिए उसे लागू करने का आसान तरीका नहीं मिल रहा है।


यदि आप विशेष रूप से एसएसएल के बजाय "एक सुरक्षित कनेक्शन" की तलाश कर रहे हैं, तो आप proxychains.sourceforge.net जैसी किसी चीज़ को देख सकते हैं, जो आपके एप्लिकेशन के बाहर रहती है, और SSH कनेक्शन पर ट्रैफ़िक भेजने के लिए सेट अप करें। जहाँ तक एसएसएल / टीएलएस के काम करने का तरीका समझा जाता है, अगर इन-एप्लिकेशन एसएसएल, ओपनएसएसएल बहुत आसान है। यदि आप एक विकल्प चाहते हैं, तो yaSSL या gnuTLS आज़माएँ।
बोरेलिड

3
'आसान तरीका' को परिभाषित करें। ओपनएसएसएल सी प्रोग्रामर के लिए मानक है। यदि आपको इससे कठिनाई हो रही है तो आपको इसके बारे में पूछना चाहिए।
लोरेन का मार्किव

OpenSSL प्रोग्रामिंग (Par t I) का यह एक परिचय देखें । भाग II मेरे लिए बहुत उन्नत और कठिन है। लेकिन part2 एक नज़र लेने लायक है।
रिक

ओपनएसएसएल एपीआई के साथ सुरक्षित प्रोग्रामिंग की भी जांच करें । लेकिन मैंने सिर्फ राय सुनी है कि ओपन्सल कितना बुरा है और अन्य विकल्प एक कोशिश के लायक हैं।
रिक

एक अन्य विकल्प बाहरी SSL आवरण उपकरण का उपयोग करना है जैसे stunnel, stunnel4पैकेज डेबियन-आधारित डिस्ट्रोस में है और इसका उपयोग करना आसान है। आपके सर्वर में उचित SSL समर्थन जोड़ने की तुलना में कुछ सीमाएँ हैं, लेकिन यह त्वरित समाधान के लिए अच्छा हो सकता है। मुझे स्टनलाइन पसंद है क्योंकि यह UNIX सॉफ़्टवेयर टूल्स दृष्टिकोण के साथ फिट बैठता है।
सैम वाटकिंस

जवाबों:


150

ओपनएसएसएल का उपयोग करते समय कई चरण होते हैं। आपके पास एक एसएसएल प्रमाणपत्र होना चाहिए, जिसमें प्रमाणपत्र हो सकता है जिसमें निजी कुंजी के साथ प्रमाणपत्र का सटीक स्थान निर्दिष्ट करना सुनिश्चित हो (यह उदाहरण मूल में है)। वहाँ बहुत सारे अच्छे ट्यूटोरियल हैं।

कुछ में शामिल हैं:

#include <openssl/applink.c>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

आपको ओपनएसएसएल को इनिशियलाइज़ करने की आवश्यकता होगी:

void InitializeSSL()
{
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();
}

void DestroySSL()
{
    ERR_free_strings();
    EVP_cleanup();
}

void ShutdownSSL()
{
    SSL_shutdown(cSSL);
    SSL_free(cSSL);
}

अब कार्यक्षमता के थोक के लिए। आप कनेक्शन पर कुछ समय लूप जोड़ना चाह सकते हैं।

int sockfd, newsockfd;
SSL_CTX *sslctx;
SSL *cSSL;

InitializeSSL();
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd< 0)
{
    //Log and Error
    return;
}
struct sockaddr_in saiServerAddress;
bzero((char *) &saiServerAddress, sizeof(saiServerAddress));
saiServerAddress.sin_family = AF_INET;
saiServerAddress.sin_addr.s_addr = serv_addr;
saiServerAddress.sin_port = htons(aPortNumber);

bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

listen(sockfd,5);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

sslctx = SSL_CTX_new( SSLv23_server_method());
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);

int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);

cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, newsockfd );
//Here is the SSL Accept portion.  Now all reads and writes must use SSL
ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0)
{
    //Error occurred, log and close down ssl
    ShutdownSSL();
}

तब आप पढ़ या लिख ​​सकते हैं:

SSL_read(cSSL, (char *)charBuffer, nBytesToRead);
SSL_write(cSSL, "Hi :3\n", 6);

अद्यतनSSL_CTX_new टीएलएस विधि है कि सबसे अच्छा फिट क्रम में अपनी आवश्यकताओं के बजाय सुरक्षा के नए संस्करण का समर्थन करने के साथ बुलाया जाना चाहिए SSLv23_server_method()। देखें: OpenSSL SSL_CTX_new विवरण

TLS_method (), TLS_server_method (), TLS_client_method ()। ये सामान्य प्रयोजन के संस्करण-लचीले एसएसएल / टीएलएस तरीके हैं। उपयोग किए जाने वाले वास्तविक प्रोटोकॉल संस्करण को क्लाइंट और सर्वर द्वारा पारस्परिक रूप से समर्थित उच्चतम संस्करण से बातचीत की जाएगी। समर्थित प्रोटोकॉल SSLv3, TLSv1, TLSv1.1, TLSv1.2 और TLSv1.3 हैं।


9
जैसा कि मैंने सोचा था कि इतना आसान नहीं है, लेकिन अंत में (भगवान का शुक्र है!) मुझे कुछ कोड दिखाई दे रहे हैं। क्या यह क्रॉस-प्लेटफ़ॉर्म या यूनिक्स / यूनिक्स जैसी प्रणालियों के लिए है?
जूलियोमालेग्रिया

3
मैंने कई प्लेटफार्मों पर समान कोड का उपयोग किया है: हाथ, लिनक्स और खिड़कियां।
कैप्टनबली

2
ifहालांकि अंतिम गलत है। यह if (ssl_err <= 0) {केवल तब होना चाहिए जब यह एक त्रुटि हो। सफलता पर SSL_accept()रिटर्न 1, 0"नियंत्रित विफलता" और -1"घातक विफलता" पर। मैन पेज देखें
Jite

2
इसके अलावा, अगर SSL_CTX_set_tmp_dh[_callback]()बुलाया नहीं जाता है तो डीएच सिफर काम नहीं करेगा । अभी-अभी पता चला है कि इसके बिना काम करने वाला कठिन रास्ता नहीं पता चलेगा, अलर्ट नंबर 40 का निर्माण किया।
रोमन दिमित्रिको

5
@DevNull SSLv23_server_method()बताता है कि सर्वर SSLv2 और v3 को समझता है और अब पदावनत हो गया है। टीएलएस 1.1 और 1.2 का समर्थन करने के लिए उस विधि को बदलें TLS_server_method()source
ezPaint 15:23

17

ओपनएसएसएल काफी कठिन है। यह बिल्कुल सही ढंग से बातचीत न करके गलती से आपकी सभी सुरक्षा को फेंक देना आसान है। (हेक, मुझे व्यक्तिगत रूप से एक बग ने काट लिया है जहां कर्ल ओपनएसएसएल अलर्ट को बिल्कुल सही नहीं पढ़ रहा था, और कुछ साइटों से बात नहीं कर सका।)

यदि आप वास्तव में त्वरित और सरल चाहते हैं, तो अपने कार्यक्रम के सामने स्टड लगाओ , यह एक दिन है। एक अलग प्रक्रिया में एसएसएल होने से आपको धीमा नहीं पड़ेगा: http://vincent.bernat.im/en/blog/2011-ssl-benchmark.html


11
यह एक व्यावहारिक जवाब है, लेकिन यह वास्तव में सवाल का जवाब नहीं देता है।
स्विस

4
2016 में छोड़ दिया गया था। रेडमी ने सिफारिश की: github.com/varnish/hitch
चार्ल्स

7

मेरे जैसे दूसरों के लिए:

demos/ssl/C ++ में उदाहरण कोड के साथ निर्देशिका में एसएसएल स्रोत में एक बार एक उदाहरण था । अब यह केवल इतिहास के माध्यम से उपलब्ध है: https://github.com/openssl/openssl/tree/691064c47fd6a7d11189df00a0d1b94d8051cbe0/dosos/ssl

आपको शायद एक कार्यशील संस्करण ढूंढना होगा, मैंने मूल रूप से 6 नवंबर 2015 को यह उत्तर पोस्ट किया था। और मुझे स्रोत को संपादित करना था - ज्यादा नहीं।

प्रमाण पत्र: .pem demos/certs/apps/: https://github.com/openssl/openssl/tree/master/demos/certs/apps


-1

यहाँ मेरा उदाहरण ssl सॉकेट सर्वर थ्रेड्स (एकाधिक कनेक्शन) https://github.com/breakermind/CppLinux/blob/master/QtSslServerThreads/breakermindsslserver.cpp

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <iostream>

#include <breakermindsslserver.h>

using namespace std;

int main(int argc, char *argv[])
{
    BreakermindSslServer boom;
    boom.Start(123,"/home/user/c++/qt/BreakermindServer/certificate.crt", "/home/user/c++/qt/BreakermindServer/private.key");
    return 0;
}

कृपया समाधान को सीधे अपने SO पोस्ट में शामिल करें।
मैकीज जुरेस्को
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.