JavaRush /Java блогы /Random-KK /HTTP-ден HTTPS-ке
Viacheslav
Деңгей

HTTP-ден HTTPS-ке

Топта жарияланған
HTTP-ден HTTPS-ке дейін - 1
Мазмұны:

Кіріспе

Қазіргі әлемде сіз веб-қосымшаларсыз өмір сүре алмайсыз. Ал біз шағын эксперименттен бастаймыз. Бала кезімде барлық дүңгіршектер «Аргументы и факты» газетін қалай сататыны есімде. Мен оларды есіме түсірдім, өйткені, менің бала кезімдегі жеке қабылдауым бойынша, бұл газеттер әрқашан біртүрлі көрінетін. Мен олардың веб-сайтына бару керек пе деп шештім:
HTTP-ден HTTPS-ке дейін - 2
Егер Google Chrome анықтамасына өтсек, бұл сайт қауіпсіз қосылымды пайдаланbyteындығын және сіз сайтпен алмасатын ақпаратқа үшінші тараптар қол жетімді болуы мүмкін екенін оқимыз. Кейбір басқа жаңалықтарды, мысалы, Фонтанка электронды БАҚ-тың Санкт-Петербург жаңалықтарын тексерейік:
HTTP-ден HTTPS-ке дейін - 3
Көріп отырғаныңыздай, Фонтанка веб-сайтында бұл деректерге негізделген қауіпсіздік проблемалары жоқ. Веб-ресурстардың қауіпсіз болуы немесе қауіпсіз болмауы мүмкін екендігі белгілі болды. Біз сондай-ақ қорғалмаған ресурстарға кіру HTTP протоколы арқылы жүзеге асырылатынын көреміз. Ал егер ресурс қорғалған болса, онда деректер алмасу HTTPS протоколы арқылы жүзеге асырылады, мұндағы S соңында «Қауіпсіз» дегенді білдіреді. HTTPS протоколы rfc2818 сипаттамасында сипатталған: " HTTP Over TLS ". Өз веб-қосымшамызды жасауға тырысайық және оның қалай жұмыс істейтінін өз көзімізбен көрейік. Және осы жолда біз терминдерді түсінеміз.
HTTP-ден HTTPS-ке дейін - 4

Java тіліндегі веб-қосымша

Сонымен, біз Java тілінде өте қарапайым веб-қосымшаны жасауымыз керек. Біріншіден, бізге Java қолданбасының өзі қажет. Ол үшін біз Gradle жобасының автоматты құрастыру жүйесін қолданамыз. Бұл бізге қажетті каталог құрылымын қолмен жасамауға мүмкіндік береді + Gradle жобаға қажетті барлық кітапханаларды басқарады және codeты орындау кезінде олардың қолжетімді болуын қамтамасыз етеді. Сіз Gradle туралы толығырақ қысқа шолудан оқи аласыз: " Gradle туралы қысқаша кіріспе ". Gradle Init Plugin қолданып , пәрменді іске қосыңыз:
gradle init --type java-application
build.gradleОсыдан кейін жобамыздың қандай кітапханалардан тұратынын және Gradle бізге беретінін сипаттайтын құрастыру сценарийін ашайық . Тәжірибе жасайтын веб-serverге тәуелділікті қосайық:
dependencies {
    // Web server
    implementation 'io.undertow:undertow-core:2.0.20.Final'
     // Use JUnit test framework
     testImplementation 'junit:junit:4.12'
}
Веб-қосымша жұмыс істеуі үшін бізге міндетті түрде біздің қолданба орналастырылатын веб-server қажет. Веб-serverлердің алуан түрлілігі бар, бірақ олардың негізгілері: Tomcat, Jetty, Undertow. Бұл жолы біз Undertow-ды таңдаймыз. Осы веб-serverмен қалай жұмыс істеуге болатынын түсіну үшін Undertow ресми веб-сайтына өтіп, құжаттама бөліміне өтейік . Сіз және мен Undertow Core-ға тәуелділікті байланыстырдық, сондықтан бізді осы Core , яғни веб-serverдің негізі, негізі туралы бөлім қызықтырады . Ең оңай жолы - Undertow үшін Builder API пайдалану:
public static void main(String[] args) {
	Undertow server = Undertow.builder()
            .addHttpListener(8080, "localhost")
            .setHandler(new HttpHandler() {
                @Override
                public void handleRequest(final HttpServerExchange exchange) throws Exception {
                    exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                    exchange.getResponseSender().send("Hello World");
                }
            }).build();
    server.start();
}
Егер codeты орындасақ, біз келесі веб-ресурсқа өте аламыз:
HTTP-ден HTTPS-ке дейін - 5
Бұл қарапайым жұмыс істейді. Undertow Builder API арқасында біз HTTP тыңдаушысын localhost пен 8080 портына қосамыз. Бұл тыңдаушы веб-шолғыштан сұрауларды қабылдайды және жауап ретінде "Hello World" жолын қайтарады. Тамаша веб-қосымша. Бірақ біз көріп отырғанымыздай, біз HTTP протоколын қолданамыз, яғни. Деректер алмасудың бұл түрі қауіпсіз емес. HTTPS протоколы арқылы алмасулар қалай жүзеге асырылатынын анықтайық.
HTTP-ден HTTPS-ке дейін - 6

HTTPS талаптары

HTTPS қалай қосу керектігін түсіну үшін HTTPS сипаттамасына оралайық: " RFC-2818: HTTP Over TLS ". Спецификацияға сәйкес HTTPS протоколындағы деректер SSL немесе TLS криптографиялық хаттамалары арқылы беріледі. Адамдарды SSL және TLS концепциялары жиі жаңылыстырады. Шын мәнінде, SSL дамып, оның нұсқаларын өзгертті. Кейінірек TLS SSL хаттамасын әзірлеудегі келесі қадам болды. Яғни, TLS жай ғана SSL жаңа нұсқасы болып табылады. Техникалық сипаттамада былай делінген: «SSL және оның мұрагері TLS». Сонымен, біз SSL/TLS криптографиялық хаттамалары бар екенін білдік. SSL – Secure Sockets Layer аббревиатурасы және «қауіпсіз розетка қабаты» деп аударылады. Ағылшын тілінен аударылған розетка қосқыш болып табылады. Желі арқылы деректерді тасымалдауға қатысушылар желі арқылы бір-бірімен байланысу үшін розеткаларды бағдарламалау интерфейсі (яғни API) ретінде пайдаланады. Браузер клиент ретінде әрекет етеді және клиент ұясын пайдаланады, ал сұрауды қабылдайтын және жауап беретін server server ұясын пайдаланады. Дәл осы ұялар арасында деректер алмасу жүреді. Сондықтан протокол бастапқыда SSL деп аталды. Бірақ уақыт өтіп, хаттама дамыды. Бір кезде SSL протоколы TLS протоколына айналды. TLS – Transport Layer Security деген сөздің қысқартылған нұсқасы. TLS протоколы, өз кезегінде, SSL протоколының спецификациясының 3.0 нұсқасына негізделген. TLS протоколы бөлек мақалалар мен шолулардың тақырыбы болып табылады, сондықтан мен қызықты деп тапқан материалдарды ғана көрсетемін: Қысқаша айтқанда, HTTPS негізі - TLS қол алысуы және оның цифрлық сертификаты арқылы «Сервер идентификациясын» тексеру (яғни server сәйкестендіру). Бұл маңызды. Осыны еске түсірейік, өйткені... Бұл фактіге кейінірек ораламыз. Сонымен, бұрын serverге HTTP протоколы арқылы қалай жұмыс істеу керектігін айту үшін HttpListener қолдандық. Жоғарыдағы мысалда HTTP арқылы жұмыс істеу үшін HttpListener қоссақ, HTTPS арқылы жұмыс істеу үшін HttpsListener қосу керек:
HTTP-ден HTTPS-ке дейін - 7
Бірақ оны қосу үшін бізге SSLContext қажет. Бір қызығы, SSLContext - бұл Undertow класы емес, бірақ javax.net.ssl.SSLContext. SSLContext класы " Java Secure Socket Extension " (JSSE) деп аталатын бөлігі болып табылады - Интернетке қосылу қауіпсіздігін қамтамасыз ету үшін Java кеңейтімі. Бұл кеңейтім " Java Secure Socket Extension (JSSE) анықтамалық нұсқаулығында " сипатталған . Құжаттаманың кіріспе бөлімінен көріп отырғаныңыздай, JSSE SSL және TLS протоколдарының негізін және Java іске асыруын қамтамасыз етеді. SSLContext қалай аламыз? JavaDoc SSLContext ашыңыз және getInstance әдісін табыңыз . Көріп отырғаныңыздай, SSLContext алу үшін «Secure Socket Protocol» атауын көрсету керек. Параметрлердің сипаттамасы бұл атауларды " Java криптографиялық архитектурасының стандартты алгоритм атауы құжаттамасынан " табуға болатынын көрсетеді. Сондықтан, нұсқауларды орындап, құжаттамаға өтейік. Біз SSL және TLS арасында таңдау жасай алатынымызды көреміз:
HTTP-ден HTTPS-ке дейін - 8
Енді біз SSLContext құруымыз керек екенін түсінеміз:
public SSLContext getSSLContext() {
	// 1. Получаем контекст, в рамках которого будем работать по TLS протоколу
	SSLContext context = null;
	try {
		context = SSLContext.getInstance("TLS");
	} catch (NoSuchAlgorithmException e) {
		throw new IllegalStateException(e);
	}
	return context;
}
Жаңа контекст жасағаннан кейін, SSLContext " Java Secure Socket Extension (JSSE) анықтамалық нұсқаулығында " сипатталғанын есте ұстаймыз . «Жаңадан жасалған SSLContext init әдісін шақыру арқылы инициализациялануы керек» дегенді оқимыз және көреміз. Яғни, контекст құру жеткіліксіз. Оны инициализациялау қажет. Және бұл қисынды, өйткені қауіпсіздік туралы біз сізге TLS протоколын пайдаланғымыз келетінін ғана айттық. SSLContext инициализациясы үшін үш нәрсені қамтамасыз ету керек: KeyManager, TrustManager, SecureRandom.
HTTP-ден HTTPS-ке дейін - 9

KeyManager

KeyManager - негізгі менеджер. Ол бізбен байланысатын адамға қандай «түпнұсқалық растау деректерін» беруіне жауапты. Тіркелгі деректері жеке куәлік ретінде аударылуы мүмкін. Клиент serverдің өзі мәлімдеген және сенуге болатынына сенімді болуы үшін сәйкестендіру қажет. Сәйкестендіру ретінде не қолданылады? Естеріңізде болса, Сервер идентификациясы serverдің цифрлық сертификатымен расталады. Бұл процесті келесідей көрсетуге болады:
HTTP-ден HTTPS-ке дейін - 10
Сонымен қатар, « JSSE анықтамалық нұсқаулығы: SSL қалай жұмыс істейді » SSL «ассиметриялық криптографияны» қолданатынын айтады, бұл бізге кілттер жұбы: ашық кілт және жеке кілт қажет екенін білдіреді. Біз криптография туралы айтып жатқандықтан, «Java Cryptography Architecture» (JCA) іске қосылады. Oracle осы архитектура бойынша тамаша құжатты ұсынады: " Java Cryptography Architecture (JCA) анықтамалық нұсқаулығы ". Сонымен қатар, JavaRush бойынша JCA туралы қысқаша шолуды оқи аласыз: " Java криптографиялық архитектурасы: алғашқы танысу ." Сонымен, KeyManager-ті инициализациялау үшін бізге server сертификатын сақтайтын KeyStore керек. Кілт пен сертификаттар қоймасын жасаудың ең көп тараған жолы JDK-мен бірге келетін keytool утorтасы болып табылады. Мысалды JSSE құжаттамасынан көруге болады: " JSSE көмегімен пайдалану үшін кілт қоймасын жасау ". Сонымен, кілттер қоймасын жасау және сол жерде сертификатты жазу үшін KeyTool утorтасын пайдалану керек. Бір қызығы, кілт генерациясы бұрын -genkey арқылы көрсетілген, бірақ қазір -genkeypair пайдалану ұсынылады. Біз келесі нәрселерді анықтауымыз керек:
  • бүркеншік ат : Бүркеншік ат немесе жазба кілт қоймасында сақталатын жай атау
  • keyalg : Кілтті шифрлау алгоритмі. RSA алгоритмін таңдайық, бұл біздің мақсатымыз үшін мәні бойынша стандартты шешім болып табылады.
  • keysize : Кілт өлшемі (биттермен). Ұсынылатын ең аз өлшем – 2048, себебі... кішірек өлшем әлдеқашан жарылған. Толығырақ мына жерден оқи аласыз: « 2048 биттегі ssl сертификаты ».
  • dname : Ерекше есім, ерекше есім.
Сұралған ресурс (мысалы, https://localhost) онымен салыстырылатынын түсіну маңызды. Бұл «сәйкестендіру тақырыбы» деп аталады.
  • жарамдылық : Жасалған сертификат жарамды болатын күндердегі ұзақтығы, яғни. жарамды.
  • ext : " Аты аталған кеңейтімдер " ішінде көрсетілген сертификат кеңейтімі.
Өздігінен қол қойылған сертификаттар үшін (яғни, тәуелсіз жасалған куәліктер үшін) келесі кеңейтімдерді көрсету керек:
  • -ext san:critical=dns:localhost,ip:127.0.0.1 > SubjectAlternativeName арқылы тақырыпты сәйкестендіру үшін
  • -ext bc=ca:false > бұл сертификат басқа сертификаттарға қол қою үшін пайдаланылмайтынын көрсетеді
Пәрменді орындаймыз (Windows ОЖ үшін мысал):
keytool -genkeypair -alias ssl -keyalg RSA -keysize 2048 -dname "CN=localhost,OU=IT,O=Javarush,L=SaintPetersburg,C=RU,email=contact@email.com" -validity 90 -keystore C:/keystore.jks -storepass passw0rd -keypass passw0rd -ext san:critical=dns:localhost,ip:127.0.0.1 -ext bc=ca:false
Өйткені файл жасалады, файлды жасауға барлық құқықтарыңыз бар екеніне көз жеткізіңіз. Бұған қоса, сіз келесідей кеңестерді көресіз:
HTTP-ден HTTPS-ке дейін - 11
Мұнда бізге JKS меншікті пішім екені айтылады. Меншік бұл авторлардың жеке меншігі екенін және тек Java тілінде пайдалануға арналғанын білдіреді. Үшінші тараптың утorталарымен жұмыс істегенде, қақтығыс туындауы мүмкін, сондықтан бізге ескертіледі. Сонымен қатар, біз қатені алуымыз мүмкін: The destination pkcs12 keystore has different storepass and keypass. Бұл қате Кілттер қоймасындағы жазба мен кілт қоймасының өзі үшін құпия сөздер әртүрлі болғандықтан орын алады. Keytool құжаттамасында айтылғандай , "Мысалы, үшінші тарап құралдарының көпшілігі PKCS №12 кілт қоймасындағы дүкен рұқсаты мен пернелік рұқсаттың бірдей болуын талап етеді." Біз кілтті өзіміз көрсете аламыз (мысалы, -destkeypass entrypassw). Бірақ талаптарды бұзбау және бірдей құпия сөзді орнатпау жақсы. Сондықтан импорт келесідей болуы мүмкін:
keytool -importkeystore -srckeystore C:/keystore.jks -destkeystore C:/keystore.jks -deststoretype pkcs12
Сәттілік мысалы:
HTTP-ден HTTPS-ке дейін - 12
Куәлікті файлға экспорттау үшін келесі әрекеттерді орындауға болады:
keytool -export -alias ssl -storepass passw0rd -file C:/server.cer -keystore C:/keystore.jks
Сонымен қатар, біз келесідей Keystore мазмұнын ала аламыз:
keytool -list -v -keystore C:/keystore.jks -storepass passw0rd
Керемет, қазір бізде сертификат бар кілттер қоймасы бар. Енді оны codeтан алуға болады:
public KeyStore getKeyStore() {
	// Согласно https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#KeyStore
	try(FileInputStream fis = new FileInputStream("C:/keystore.jks")){
		KeyStore keyStore = KeyStore.getInstance("pkcs12");
		keyStore.load(fis, "passw0rd".toCharArray());
		return keyStore;
	} catch (IOException ioe) {
		throw new IllegalStateException(ioe);
	} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException e) {
		throw new IllegalStateException(e);
	}
}
Егер KeyStore болса, біз KeyManager-ді инициализациялай аламыз:
public KeyManager[] getKeyManagers(KeyStore keyStore) {
	String keyManagerAlgo = KeyManagerFactory.getDefaultAlgorithm();
	KeyManagerFactory keyManagerFactory = null;
	try {
		keyManagerFactory = KeyManagerFactory.getInstance(keyManagerAlgo);
		keyManagerFactory.init(keyStore, "passw0rd".toCharArray());
		return keyManagerFactory.getKeyManagers();
	} catch (NoSuchAlgorithmException e) {
		throw new IllegalStateException(e);
	} catch (UnrecoverableKeyException | KeyStoreException e) {
		throw new IllegalStateException(e);
	}
}
Бірінші мақсатымыз орындалды. TrustManager дегеннің не екенін анықтау қалды. TrustManager " TrustManager интерфейсі " бөліміндегі JSSE құжаттамасында сипатталған . Ол KeyManager-ге өте ұқсас, бірақ оның мақсаты қосылымды сұрайтын адамға сенуге болатынын тексеру болып табылады. Ашығын айтқанда, бұл кері бағытта KeyManager =) Бізге TrustManager қажет емес, сондықтан біз нөлге өтеміз. Содан кейін serverге сұраныс жасайтын соңғы пайдаланушыны тексермейтін әдепкі TrustManager жасалады. Құжаттамада былай делінген: «әдепкі енгізу пайдаланылады». SecureRandom бағдарламасымен бірдей. Егер біз null мәнін көрсетсек, әдепкі іске асыру пайдаланылады. SecureRandom JCA класы екенін және « SecureRandom класы » бөліміндегі JCA құжаттамасында сипатталғанын еске түсірейік . Жалпы алғанда, жоғарыда сипатталған барлық әдістерді ескере отырып, дайындық келесідей болуы мүмкін:
public static void main(String[] args) {
	// 1. Подготавливаем приложение к работе по HTTPS
	App app = new App();
	SSLContext sslContext = app.getSSLContext();
	KeyStore keyStore = app.getKeyStore();
	KeyManager[] keyManagers = app.getKeyManagers(keyStore);
	try {
		sslContext.init(keyManagers, null, null);
	} catch (KeyManagementException e) {
		throw new IllegalStateException(e);
	}
Серверді іске қосу ғана қалады:
// 2. Поднимаем server
 	int httpsPort = 443;
	Undertow server = Undertow.builder()
            .addHttpsListener(httpsPort, "localhost", sslContext)
            .setHandler(new HttpHandler() {
                @Override
                public void handleRequest(final HttpServerExchange exchange) throws Exception {
                    exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain");
                    exchange.getResponseSender().send("Hello World");
                }
            }).build();
	server.start();
}
Бұл жолы біздің server келесі мекенжайда қолжетімді болады. https://localhost:443 Дегенмен, біз бұл ресурсқа сенуге болмайтындығы туралы қатені аламыз:
HTTP-ден HTTPS-ке дейін - 13
Сертификатта не дұрыс емес екенін және бұл туралы не істеу керектігін анықтайық.
HTTP-ден HTTPS-ке дейін - 14

Сертификаттарды басқару

Сонымен, біздің server HTTPS арқылы жұмыс істеуге дайын, бірақ клиент оған сенбейді. Неліктен? Қарап көрейік:
HTTP-ден HTTPS-ке дейін - 15
Себебі, бұл куәліктің өзі қол қойылған сертификат болып табылады. Өздігінен қол қойылған SSL сертификаты өзі анықтайтын сол адам шығарған және қол қойған ашық кілт сертификатын білдіреді. Яғни, оны ешбір құрметті сертификаттау органы (CA, сертификаттау орталығы ретінде де белгілі) бермеген. Куәландыру орталығы сенімгерлік басқарушы ретінде әрекет етеді және күнделікті өмірде нотариусқа ұқсас. Ол берген сертификаттардың сенімді екендігіне сендіреді. Мұндай СА-ның сертификаттар беру қызметі ақылы, сондықтан ешкімге сенім мен беделді жоғалтудың қажеті жоқ. Әдепкі бойынша, сенімді бірнеше сертификат органдары бар. Бұл тізімді өңдеуге болады. Және әрбір операциялық жүйенің сертификаттау органдарының тізімін өз басқаруы бар. Мысалы, Windows жүйесінде бұл тізімді басқаруды мына жерден оқуға болады: " Windows жүйесінде сенімді түбірлік сертификаттарды басқару ". Қате туралы хабарда көрсетілгендей сертификатты сенімділерге қосамыз. Ол үшін алдымен сертификатты жүктеп алыңыз:
HTTP-ден HTTPS-ке дейін - 16
Windows операциялық жүйесінде Win+R пернелер тіркесімін басып, mmcбасқару консоліне қоңырау шалу үшін орындаңыз. Содан кейін ағымдағы консольге «Сертификаттар» бөлімін қосу үшін Ctrl+M пернелер тіркесімін басыңыз. Әрі қарай, «Сенімді түбірлік сертификаттау органдары» бөлімінде біз орындаймыз Действия / Все задачи / Импорт. Бұрын жүктелген файлды файлға импорттайық. Браузер сертификаттың өткен сенімді күйін есте ұстаған болуы мүмкін. Сондықтан бетті ашпас бұрын браузерді қайта іске қосу керек. Мысалы, Google Chrome-да мекенжай жолағында іске қосу керек chrome://restart. Windows операциялық жүйесінде сертификаттарды көру үшін утorтаны да пайдалануға болады certmgr.msc:
HTTP-ден HTTPS-ке дейін - 17
Егер біз бәрін дұрыс жасасақ, HTTPS арқылы serverімізге сәтті қоңырауды көреміз:
HTTP-ден HTTPS-ке дейін - 18
Көріп отырғаныңыздай, сертификат енді жарамды болып саналады, ресурс қолжетімді және қателер жоқ.
HTTP-ден HTTPS-ке дейін - 19

Төменгі сызық

Сонымен, біз веб-serverде HTTPS протоколын қосу схемасы қандай болатынын және бұл үшін не қажет екенін анықтадық. Осы сәтте қолдау криптографияға жауап беретін Java криптографиялық архитектурасының (JCA) және Java жағында TLS енгізуін қамтамасыз ететін Java Secure Socket Extension (JSSE) өзара әрекеттесуімен қамтамасыз етілетіні анық деп үміттенемін. JDK құрамына кіретін keytool қызметтік бағдарламасы KeyStore кілтімен және сертификаттар қоймасымен жұмыс істеу үшін қалай пайдаланылатынын көрдік. Сонымен қатар, біз HTTPS қауіпсіздік үшін SSL/TLS протоколдарын қолданатынын түсіндік. Мұны күшейту үшін мен сізге осы тақырып бойынша тамаша мақалаларды оқуға кеңес беремін: Осы шағын шолудан кейін HTTPS сәл ашық болады деп үміттенеміз. Егер сізге HTTPS қосу қажет болса, сіз қолданба serverлері мен жақтауларыңыздың құжаттамасынан шарттарды оңай түсіне аласыз. #Вячеслав
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION