Управление файлами ключей в программах на Python
Работа с ключевыми файлами в Python
Ключевые файлы (key files) обычно содержат криптографические ключи (RSA, ECDSA), токены доступа (API key) или пароли. В Python их чтение и запись требуют внимания к безопасности, кодировкам и обработке ошибок.
Основной подход: чтение приватного RSA ключа из PEM-файла
Библиотека cryptography позволяет безопасно загружать ключи. Код:
from cryptography.hazmat.primitives import serialization
with open('private.key', 'rb') as key_file:
private_key = serialization.load_pem_private_key(
key_file.read(),
password=None # если ключ без пароля
)
print('Ключ загружен, тип:', type(private_key))ввод программ на python (ввод данных в программе python)
Если ключ защищён паролем, передаётся password=None (байтовая строка).
Типичная ошибка:
ValueError: Could not deserialize key data. Возникает, если файл испорчен, имеет неверный формат или пароль не совпадает. Решение: проверить содержимое файла, убедиться, что он начинается с -----BEGIN PRIVATE KEY-----.
Как прочитать ключ из текстового файла?
Простые текстовые ключи (API токен) хранятся в одну строку. Читаем как обычный текст:
with open('api_key.txt', 'r') as f:
api_key = f.read().strip()
print('API ключ:', api_key[:5], '...') # частичный вывод для безопасностиPython file io (ввод-вывод файлов в python)
Проблема:
Случайное добавление переноса строки или пробела в конце ключа. Решение: использовать strip(). Также нельзя выводить ключ целиком в логах.
Как записать ключ в файл с минимальными правами?
Для приватных ключей важно установить права 600 (только владелец). В Python можно использовать os.chmod после записи:
import os
key_data = b'-----BEGIN PRIVATE KEY-----\n...'
with open('private.key', 'wb') as f:
f.write(key_data)
os.chmod('private.key', 0o600)
Python temp files (временные файлы в python)
Ошибка:
Если файл уже существует, права могут остаться от предыдущего владельца. Решение: удалять файл перед записью или использовать временный файл.
Как хранить ключи в INI-файлах?
Модуль configparser удобен для конфигураций с секциями. Пример:
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
api_key = config.get('DEFAULT', 'api_key')
print('Ключ из INI:', api_key[:5])Python index files (индексация файлов в python)
Файл config.ini:
[DEFAULT]
api_key = my_secret_token
Проблема:
Ключ может быть прочитан в кодировке, отличной от UTF-8, что вызовет UnicodeDecodeError. Решение: указывать encoding='utf-8' при открытии файла.
Как безопасно сохранить ключ в зашифрованном виде?
Используйте шифрование симметричным ключом, например Fernet из cryptography:
from cryptography.fernet import Fernet
# Генерация ключа шифрования (хранить отдельно)
encryption_key = Fernet.generate_key()
cipher = Fernet(encryption_key)
# Шифрование оригинального ключа
original_key = b'my-api-key'
encrypted_key = cipher.encrypt(original_key)
with open('encrypted.key', 'wb') as f:
f.write(encrypted_key)
# Расшифровка
with open('encrypted.key', 'rb') as f:
loaded = cipher.decrypt(f.read())
print('Расшифрованный ключ:', loaded)Типичная ошибка:
Потеря ключа шифрования приводит к невозможности расшифровки. Решение: хранить ключ шифрования в переменной окружения или в защищённом хранилище.
Расширенные примеры работы с ключевыми файлами
Пример 1: Генерация и сохранение RSA ключа с паролем
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import rsa
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
# Защита паролем
password = b'my_password'
pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.BestAvailableEncryption(password)
)
with open('private_encrypted.pem', 'wb') as f:
f.write(pem)
print('Зашифрованный key file создан')Зашифрованный key file создан
Пример 2: Чтение ключа из переменной окружения и запись во временный файл
import os
import tempfile
key_content = os.environ.get('SSH_PRIVATE_KEY', '').encode()
if key_content:
with tempfile.NamedTemporaryFile(delete=False, suffix='.key') as tmp:
tmp.write(key_content)
tmp_path = tmp.name
print('Ключ сохранён во временный файл:', tmp_path)Ключ сохранён во временный файл: /tmp/tmpXXXXXX.key
Пример 3: Массовая загрузка ключей из JSON-файла
import json
with open('keys.json', 'r') as f:
data = json.load(f)
for service, key in data.items():
print(f'Сервис {service}: ключ длиной {len(key)} символов')Файл keys.json:
{
"aws": "AKIA...",
"github": "ghp_..."
}
Сервис aws: ключ длиной 20 символов
Сервис github: ключ длиной 40 символов
Пример 4: Чтение публичного ключа из SSH файла (authorized_keys)
import paramiko
with open('~/.ssh/authorized_keys', 'r') as f:
for line in f:
if line.strip() and not line.startswith('#'):
key = paramiko.RSAKey(data=line.encode())
print('Публичный ключ:', key.get_fingerprint())Публичный ключ: SHA256:...