Что такое сертификаты?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Сертификаты
Сертификат — это электронный документ, подписанный доверенным органом (центром сертификации), который подтверждает подлинность и безопасность соединения между клиентом и сервером. Главный тип — SSL/TLS сертификат.
Основные компоненты сертификата
1. Открытый ключ (Public Key)
- Передаётся клиентам
- Используется для шифрования сообщений
- Может быть известен всем
2. Приватный ключ (Private Key)
- Хранится только на сервере
- Используется для расшифровки и подписания
- Никогда не передаётся
3. Метаданные
- Доменное имя (CN — Common Name)
- Организация
- Дата выдачи и истечения
- Подпись центра сертификации (CA)
Как работает HTTPS/TLS
# Python: проверка сертификата при HTTPS запросе
import requests
import ssl
from urllib.request import urlopen
from urllib.error import URLError
# Запрос С проверкой сертификата (по умолчанию)
try:
response = requests.get('https://google.com', verify=True)
print("Сертификат валиден")
except requests.exceptions.SSLError as e:
print(f"Ошибка сертификата: {e}")
# Опасно: игнорирование проверки сертификата (МИТМ атаки!)
response = requests.get('https://google.com', verify=False) # ❌ Плохо!
# Проверка деталей сертификата
import ssl
import socket
hostname = 'google.com'
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
print(f"Сертификат для: {cert['subject']}")
print(f"Действителен до: {cert['notAfter']}")
print(f"Издатель: {cert['issuer']}")
Типы сертификатов
1. Self-Signed (самоподписанный)
- Подписан самим владельцем
- Браузер выдаст предупреждение
- Используется в разработке и тестировании
# Создание самоподписанного сертификата
# openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
import ssl
from http.server import HTTPServer, BaseHTTPRequestHandler
class SimpleHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, HTTPS!')
# Запуск HTTPS сервера с самоподписанным сертификатом
server = HTTPServer(('localhost', 8443), SimpleHandler)
server.socket = ssl.wrap_socket(
server.socket,
certfile='cert.pem',
keyfile='key.pem',
server_side=True
)
print('HTTPS сервер запущен на https://localhost:8443')
server.serve_forever()
2. Signed by CA (подписанный центром сертификации)
- Подписан доверенным органом (Let's Encrypt, Comodo, DigiCert)
- Браузер доверяет такому сертификату
- Для production используется
3. Wildcard сертификат
- Действителен для всех поддоменов: *.example.com
- Экономит на сертификатах
# *.example.com покроет:
# api.example.com
# app.example.com
# admin.example.com
4. SAN (Subject Alternative Name)
- Один сертификат для нескольких доменов
- example.com, www.example.com, api.example.com
Работа с сертификатами в Python
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from datetime import datetime, timedelta
# 1. Генерируем приватный ключ
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
backend=default_backend()
)
# 2. Создаём сертификат
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COUNTRY_NAME, 'RU'),
x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, 'Moscow'),
x509.NameAttribute(NameOID.LOCALITY_NAME, 'Moscow'),
x509.NameAttribute(NameOID.ORGANIZATION_NAME, 'My Org'),
x509.NameAttribute(NameOID.COMMON_NAME, 'example.com'),
])
cert = x509.CertificateBuilder().subject_name(
subject
).issuer_name(
issuer
).public_key(
private_key.public_key()
).serial_number(
x509.random_serial_number()
).not_valid_before(
datetime.utcnow()
).not_valid_after(
datetime.utcnow() + timedelta(days=365)
).add_extension(
x509.SubjectAlternativeName([x509.DNSName('example.com')]),
critical=False,
).sign(private_key, hashes.SHA256(), default_backend())
# 3. Сохраняем ключ и сертификат
with open('key.pem', 'wb') as f:
f.write(private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
))
with open('cert.pem', 'wb') as f:
f.write(cert.public_bytes(serialization.Encoding.PEM))
Let's Encrypt: бесплатные сертификаты
# Установка Certbot
sudo apt-get install certbot python3-certbot-nginx
# Получение сертификата для nginx
sudo certbot certonly --nginx -d example.com -d www.example.com
# Автоматическое продление (добавляется в cron)
sudo certbot renew --dry-run
Flask с HTTPS
from flask import Flask
import ssl
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, HTTPS!'
if __name__ == '__main__':
# Запуск с самоподписанным сертификатом
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain('cert.pem', 'key.pem')
app.run(host='0.0.0.0', port=443, ssl_context=ssl_context)
Проверка срока действия сертификата
import ssl
import socket
from datetime import datetime
def check_cert_expiry(hostname):
context = ssl.create_default_context()
with socket.create_connection((hostname, 443)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
not_after_str = cert['notAfter']
# Парсим дату
not_after = datetime.strptime(not_after_str, '%b %d %H:%M:%S %Y %Z')
days_left = (not_after - datetime.now()).days
print(f"Сертификат для {hostname} действителен ещё {days_left} дней")
if days_left < 30:
print("⚠️ Внимание: срок действия сертификата истекает!")
check_cert_expiry('google.com')
Лучшие практики
-
Никогда не коммить приватные ключи в Git
echo "key.pem" >> .gitignore -
Используй环境 переменные для пути к сертификатам
import os cert_path = os.getenv('CERT_PATH') key_path = os.getenv('KEY_PATH') -
Автоматизируй продление (Let's Encrypt с Certbot)
-
Проверяй срок действия перед истечением
-
Используй HTTPS везде (даже в разработке)
-
Не игнорируй SSL ошибки в production
Сертификаты — основа безопасности в интернете. Правильное управление ими критично для защиты данных пользователей.