Skip to content
IRC-CodingIRC-Coding
PKIPublic Key InfrastructureСертификатыCertificate AuthorityTLS SSL

PKI Public Key Infrastructure: Сертификаты и TLS/SSL

PKI — фреймворк для цифровых сертификатов. Root CA, Intermediate CA, X.509, CRL, OCSP и реализация TLS/SSL с примерами.

S

schutzgeist

5 min read
PKI Public Key Infrastructure: Сертификаты и TLS/SSL

PKI Public Key Infrastructure: Зертификаты, CA и TLS/SSL

Это подробный разбор Public Key Infrastructure с фокусом на зертификаты, центры сертификации и реализацию TLS/SSL.

In a Nutshell

PKI представляет собой организационную и техническую инфраструктуру для создания, распространения, проверки и отзыва открытых ключей через зертификаты. Она обеспечивает надежную идентификацию людей, машин и сервисов.

Компактное описание

Public Key Infrastructure (PKI) состоит из Root CA и подчиненных Intermediate CAs, которые выдают, подписывают и отзывают X.509 зертификаты через CRL или OCSP.

Основные компоненты:

  • Certificate Authority (CA): выдает зертификаты
  • Registration Authority (RA): проверяет идентичность
  • Certificate Repository: хранилище зертификатов
  • Validation Authority: валидирует зертификаты

Содержимое зертификата:

  • Public Key: открытый ключ владельца
  • Identity Information: CN, SAN, OU, O, C
  • Validity Period: период действия
  • Key Usage: назначение ключа
  • Digital Signature: подпись выдавшего CA

Модель доверия:

  • Chain of Trust: иерархическая структура CA
  • Root Certificates: точки доверия в truststores
  • Certificate Validation: проверка цепи зертификатов

PKI поддерживает аутентификацию, подписи, шифрование и неотказуемость в TLS, S/MIME, Code Signing и mTLS.

Ключевые моменты

  • Root CA и Intermediate CA иерархия
  • X.509 формат и содержимое зертификатов
  • Chain of Trust и управление Truststore
  • CRL (Certificate Revocation List) и OCSP (Online Certificate Status Protocol)
  • TLS/SSL handshake с валидацией зертификатов
  • CSR (Certificate Signing Request) процесс
  • mTLS (Mutual TLS) для аутентификации клиента
  • Применимо для IT-безопасности и сетевых технологий

Основные компоненты

  1. Root Certificate Authority: верхний уровень доверия
  2. Intermediate Certificate Authority: промежуточные инстанции для делегирования
  3. End Entity Certificate: зертификат для сервера, клиента или сервиса
  4. Certificate Signing Request: запрос на выдачу зертификата
  5. Certificate Revocation List: список отозванных зертификатов
  6. OCSP Responder: онлайн проверка статуса зертификатов
  7. Truststore: хранилище доверенных Root-зертификатов
  8. Keystore: хранилище собственных зертификатов и приватных ключей

Практические примеры

Создание зертификата с OpenSSL

# Генерирование приватного ключа
openssl genrsa -out server.key 2048

# Создание Certificate Signing Request (CSR)
openssl req -new -key server.key -out server.csr \
  -subj "/C=DE/ST=Berlin/L=Berlin/O=IRC-Coding/OU=IT/CN=irc-coding.de"

# Self-signed зертификат (для тестирования)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

# Просмотр зертификата
openssl x509 -in server.crt -text -noout

# Валидация зертификата
openssl verify -CAfile ca.crt server.crt

Управление Java Keystore

// Создание Keystore с KeyTool
// keytool -genkeypair -alias server -keyalg RSA -keysize 2048 \
//   -keystore keystore.jks -validity 365

// Экспорт CSR
// keytool -certreq -alias server -keystore keystore.jks -file server.csr

// Импорт зертификата
// keytool -importcert -alias server -file server.crt \
//   -keystore keystore.jks -trustcacerts

// Java код для валидации зертификата
import java.security.cert.*;
import java.io.FileInputStream;

public class CertificateValidator {
    
    public static boolean validateCertificate(String certPath, String caPath) {
        try {
            // Загрузка зертификата
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) 
                cf.generateCertificate(new FileInputStream(certPath));
            
            // Загрузка CA-зертификата
            X509Certificate caCert = (X509Certificate) 
                cf.generateCertificate(new FileInputStream(caPath));
            
            // Валидация цепи зертификатов
            cert.checkValidity(); // Проверка периода действия
            cert.verify(caCert.getPublicKey()); // Проверка подписи
            
            // Проверка CRL/OCSP (упрощенно)
            if (isRevoked(cert)) {
                return false;
            }
            
            return true;
            
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    private static boolean isRevoked(X509Certificate cert) {
        // Реализация проверки CRL или OCSP
        return false;
    }
}

TLS сервер на Node.js

const https = require('https');
const fs = require('fs');

// Конфигурация TLS сервера
const tlsOptions = {
    key: fs.readFileSync('server.key'),
    cert: fs.readFileSync('server.crt'),
    ca: fs.readFileSync('ca.crt'), // Для аутентификации клиента
    requestCert: true,            // Требовать mTLS
    rejectUnauthorized: true       // Отклонять невалидные зертификаты
};

const server = https.createServer(tlsOptions, (req, res) => {
    // Информация о зертификате клиента
    const clientCert = req.socket.getPeerCertificate();
    
    if (clientCert) {
        console.log('Client authenticated:', clientCert.subject.CN);
        res.writeHead(200);
        res.end('Hello authenticated client!');
    } else {
        res.writeHead(401);
        res.end('Client certificate required');
    }
});

server.listen(8443, () => {
    console.log('TLS Server listening on port 8443');
});

Python TLS клиент с валидацией зертификата

import ssl
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context

class TLSAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context()
        context.check_hostname = True
        context.verify_mode = ssl.CERT_REQUIRED
        context.load_verify_locations('ca.crt')  # Загрузка CA-зертификата
        
        # mTLS с клиентским зертификатом
        context.load_cert_chain('client.crt', 'client.key')
        
        kwargs['ssl_context'] = context
        return super().init_poolmanager(*args, **kwargs)

# TLS-клиент с валидацией зертификата
session = requests.Session()
session.mount('https://', TLSAdapter())

try:
    response = session.get('https://secure-api.example.com/data')
    print("Response:", response.json())
except requests.exceptions.SSLError as e:
    print("TLS Error:", e)
except Exception as e:
    print("General Error:", e)

Отзыв зертификатов (CRL/OCSP)

// Проверка отзыва на основе CRL
import java.security.cert.*;
import java.net.URL;
import java.io.InputStream;

public class CRLValidator {
    
    public static boolean checkRevocation(X509Certificate cert) {
        try {
            // Извлечение CRL Distribution Points из зертификата
            String crlUrl = getCRLDistributionPoint(cert);
            
            if (crlUrl != null) {
                // Загрузка CRL
                URL url = new URL(crlUrl);
                InputStream in = url.openStream();
                
                // Загрузка и валидация CRL
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                X509CRL crl = (X509CRL) cf.generateCRL(in);
                
                // Проверка был ли зертификат отозван
                return !crl.isRevoked(cert);
            }
            
            return true; // CRL недоступна
            
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    private static String getCRLDistributionPoint(X509Certificate cert) {
        // Извлечение CRL Distribution Point из расширений зертификата
        // Реализация потребует ASN.1 парсинга
        return null;
    }
}

PKI иерархия и цепь доверия

Типичная структура PKI

Root CA (самоподписанный)
├── Intermediate CA 1 (для веб-серверов)
│   ├── irc-coding.de
│   └── api.irc-coding.de
├── Intermediate CA 2 (для подписей кода)
│   ├── desktop-app.exe
│   └── mobile-app.apk
└── Intermediate CA 3 (для E-Mail)
    ├── user1@irc-coding.de
    └── user2@irc-coding.de

Цепь валидации зертификатов

public class ChainValidator {
    
    public static boolean validateChain(X509Certificate[] chain, 
                                       X509Certificate[] trustedCAs) {
        try {
            // Инициализация Trust Anchors
            Set<TrustAnchor> trustAnchors = new HashSet<>();
            for (X509Certificate ca : trustedCAs) {
                trustAnchors.add(new TrustAnchor(ca, null));
            }
            
            // Конфигурация PKIX-параметров
            PKIXParameters params = new PKIXParameters(trustAnchors);
            params.setRevocationEnabled(true); // Активировать проверку CRL/OCSP
            
            // Certificate Path Builder
            CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
            X509CertSelector selector = new X509CertSelector();
            selector.setCertificate(chain[0]);
            
            PKIXBuilderParameters builderParams = 
                new PKIXBuilderParameters(trustAnchors);
            builderParams.setRevocationEnabled(true);
            
            // Валидация цепи зертификатов
            CertPathBuilderResult result = builder.build(builderParams);
            CertPathValidator validator = CertPathValidator.getInstance("PKIX");
            CertPathValidatorResult validatorResult = 
                validator.validate(result.getCertPath(), params);
            
            return true;
            
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

Преимущества и недостатки

Преимущества PKI

  • Безопасность: мощная криптографическая основа
  • Масштабируемость: иерархическая структура для крупных организаций
  • Стандартизация: X.509 широко распространен
  • Гибкость: применимо к различным сценариям (TLS, Code Signing, и т.д.)
  • Неотказуемость: цифровые подписи подтверждают авторство

Недостатки

  • Сложность: трудозатратная настройка и обслуживание
  • Стоимость: коммерческие CA берут плату
  • Операционная нагрузка: ротация ключей, управление зертификатами
  • Единая точка отказа: сбой Root CA влияет на всю PKI

Типичные вопросы

  1. В чем разница между Root CA и Intermediate CA? Root CA самоподписана и служит точкой доверия, Intermediate CA подписана Root CA и делегирует выдачу зертификатов.

  2. Объясните Chain of Trust! Иерархическая валидация от конечного зертификата через Intermediate CAs к Root CA.

  3. Какова цель CRL и OCSP? Проверка, был ли зертификат отозван до истечения (компрометация, смена должности, и т.д.).

  4. Когда использовать mTLS? Для взаимной аутентификации между сервером и клиентом (APIs, Microservices).

Основные ссылки

  1. https://de.wikipedia.org/wiki/Public-Key-Infrastruktur
  2. https://tools.ietf.org/html/rfc5280
  3. https://www.ietf.org/rfc/rfc5280.txt
Назад к блогу
Share:

Похожие статьи