Rsa python: RSA шифрование и дешифрование в Python
Содержание
RSA шифрование и дешифрование в Python
Мне нужна помощь в использовании шифрования и дешифрования RSA в Python.
Я создаю пару закрытых / открытых ключей, шифрую сообщение ключами и записываю сообщение в файл. Затем я читаю зашифрованный текст из файла и расшифровываю текст с помощью ключа.
У меня возникли проблемы с расшифровкой. Как вы можете видеть в моем коде ниже, когда я вставляю decrypted = key.decrypt(message)
, что программа работает, но расшифрованное сообщение снова шифруется. Похоже, что он не читает зашифрованный текст из файла.
Может ли кто-нибудь помочь мне написать этот код так, чтобы расшифровка считывала зашифрованный текст из файла, а затем использовала ключ для расшифровки зашифрованного текста?
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate public and private keys
publickey = key. publickey # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print 'encrypted message:', encrypted #ciphertext
f = open ('encryption.txt', 'w'w)
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open ('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(message)
print 'decrypted', decrypted
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
python
encryption
rsa
pycrypto
Поделиться
Источник
Unknown
05 мая 2015 в 15:08
6 ответов
- RSA шифрование и дешифрование частичного шифротекста?
Я успешно построил и скомпилировал приложение на моем PC, которое будет генерировать пару ключей RSA (я использовал GPK для длинной арифметики). Затем я проверил шифрование/дешифрование на строке Hello World (сначала преобразование ASCII —> Hex). Вопрос у меня такой: можно ли математически…
- RSA шифрование и дешифрование на разных машинах
Я пытаюсь реализовать действительно простой алгоритм RSA в C++, и я не использовал функцию openSSL. У меня есть 3 функции: generateParameter , шифрование и дешифрование . Задачей каждой функции является : Функция generateParameter генерирует два простых числа (p и q), модуль (n), публичный…
48
Для того чтобы он работал, вам нужно преобразовать ключ из str в кортеж перед расшифровкой(функция ast.literal_eval). Вот фиксированный код:
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
import ast
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate pub and priv key
publickey = key. publickey() # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print 'encrypted message:', encrypted #ciphertext
f = open ('encryption.txt', 'w')
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(ast.literal_eval(str(encrypted)))
print 'decrypted', decrypted
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
Поделиться
Esdes
05 мая 2015 в 15:56
8
# coding: utf-8
from __future__ import unicode_literals
import base64
import os
import six
from Crypto import Random
from Crypto.PublicKey import RSA
class PublicKeyFileExists(Exception): pass
class RSAEncryption(object):
PRIVATE_KEY_FILE_PATH = None
PUBLIC_KEY_FILE_PATH = None
def encrypt(self, message):
public_key = self. _get_public_key()
public_key_object = RSA.importKey(public_key)
random_phrase = 'M'
encrypted_message = public_key_object.encrypt(self._to_format_for_encrypt(message), random_phrase)[0]
# use base64 for save encrypted_message in database without problems with encoding
return base64.b64encode(encrypted_message)
def decrypt(self, encoded_encrypted_message):
encrypted_message = base64.b64decode(encoded_encrypted_message)
private_key = self._get_private_key()
private_key_object = RSA.importKey(private_key)
decrypted_message = private_key_object.decrypt(encrypted_message)
return six.text_type(decrypted_message, encoding='utf8')
def generate_keys(self):
"""Be careful rewrite your keys"""
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
private, public = key.exportKey(), key.publickey().exportKey()
if os.path.isfile(self.PUBLIC_KEY_FILE_PATH):
raise PublicKeyFileExists('Файл с публичным ключом существует. Удалите ключ')
self.create_directories()
with open(self.PRIVATE_KEY_FILE_PATH, 'w') as private_file:
private_file.write(private)
with open(self.PUBLIC_KEY_FILE_PATH, 'w') as public_file:
public_file.write(public)
return private, public
def create_directories(self, for_private_key=True):
public_key_path = self.PUBLIC_KEY_FILE_PATH.rsplit('/', 1)
if not os.path.exists(public_key_path):
os.makedirs(public_key_path)
if for_private_key:
private_key_path = self.PRIVATE_KEY_FILE_PATH.rsplit('/', 1)
if not os.path.exists(private_key_path):
os.makedirs(private_key_path)
def _get_public_key(self):
"""run generate_keys() before get keys """
with open(self.PUBLIC_KEY_FILE_PATH, 'r') as _file:
return _file.read()
def _get_private_key(self):
"""run generate_keys() before get keys """
with open(self.PRIVATE_KEY_FILE_PATH, 'r') as _file:
return _file. read()
def _to_format_for_encrypt(value):
if isinstance(value, int):
return six.binary_type(value)
for str_type in six.string_types:
if isinstance(value, str_type):
return value.encode('utf8')
if isinstance(value, six.binary_type):
return value
И использовать
KEYS_DIRECTORY = settings.SURVEY_DIR_WITH_ENCRYPTED_KEYS
class TestingEncryption(RSAEncryption):
PRIVATE_KEY_FILE_PATH = KEYS_DIRECTORY + 'private.key'
PUBLIC_KEY_FILE_PATH = KEYS_DIRECTORY + 'public.key'
# django/flask
from django.core.files import File
class ProductionEncryption(RSAEncryption):
PUBLIC_KEY_FILE_PATH = settings.SURVEY_DIR_WITH_ENCRYPTED_KEYS + 'public.key'
def _get_private_key(self):
"""run generate_keys() before get keys """
from corportal.utils import global_elements
private_key = global_elements.request.FILES.get('private_key')
if private_key:
private_key_file = File(private_key)
return private_key_file. read()
message = 'Hello мой friend'
encrypted_mes = ProductionEncryption().encrypt(message)
decrypted_mes = ProductionEncryption().decrypt(message)
Поделиться
Nick Korolkov
23 января 2017 в 07:07
6
PKCS#1 OAEP-это асимметричный шифр, основанный на RSA и заполнении OAEP
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Cipher import PKCS1_OAEP
def rsa_encrypt_decrypt():
key = RSA.generate(2048)
private_key = key.export_key('PEM')
public_key = key.publickey().exportKey('PEM')
message = input('plain text for RSA encryption and decryption:')
message = str.encode(message)
rsa_public_key = RSA.importKey(public_key)
rsa_public_key = PKCS1_OAEP.new(rsa_public_key)
encrypted_text = rsa_public_key.encrypt(message)
#encrypted_text = b64encode(encrypted_text)
print('your encrypted_text is : {}'. format(encrypted_text))
rsa_private_key = RSA.importKey(private_key)
rsa_private_key = PKCS1_OAEP.new(rsa_private_key)
decrypted_text = rsa_private_key.decrypt(encrypted_text)
print('your decrypted_text is : {}'.format(decrypted_text))
Поделиться
Rajan saha Raju
21 марта 2019 в 05:54
- X.509 RSA Шифрование / Дешифрование iOS
Мне нужно реализовать шифрование / дешифрование с использованием пары открытых / закрытых ключей X.509 RSA. До сих пор у меня есть кое-что, что, как я думаю, будет работать для шифрования, но у меня нет способа расшифровать, чтобы проверить. Все, что я пытаюсь сделать, имеет проблемы с чтением…
- RSA шифрование и дешифрование в Python с использованием OpenSSL
У меня есть открытый ключ, закрытый ключ и зашифрованное сообщение ( e, n, d, message). Я хочу шифровать и расшифровывать с помощью OpenSSL в Python. У меня есть ключи, которые мне не нужно генерировать. Я видел много вопросов о RSA, но все они создают ключи методом generate . Я не видел вопросов…
3
Вот моя реализация для python 3 и pycrypto
from Crypto.PublicKey import RSA
key = RSA.generate(4096)
f = open('/home/john/Desktop/my_rsa_public.pem', 'wb')
f.write(key.publickey().exportKey('PEM'))
f.close()
f = open('/home/john/Desktop/my_rsa_private.pem', 'wb')
f.write(key.exportKey('PEM'))
f.close()
f = open('/home/john/Desktop/my_rsa_public.pem', 'rb')
f1 = open('/home/john/Desktop/my_rsa_private.pem', 'rb')
key = RSA.importKey(f.read())
key1 = RSA.importKey(f1.read())
x = key.encrypt(b"dddddd",32)
print(x)
z = key1.decrypt(x)
print(z)
Поделиться
Anagnostou John
19 октября 2018 в 10:01
0
Вы можете использовать простой способ для genarate RSA . Использование библиотеки rsa
pip install rsa
Поделиться
AliReza Azizi
27 декабря 2019 в 06:23
0
Следите за использованием криптографии!!!
Это замечательная библиотека, но у нее есть проблема в python3.8, потому что из библиотеки time был удален атрибут clock(). Чтобы исправить это, просто измените источник в строке /usr/lib/python3.8/site-packages/Crypto/Random/_UserFriendlyRNG.py
77, изменив t = time.clock()
int t = time.perf_counter()
Поделиться
Alessandro
10 апреля 2020 в 12:14
Похожие вопросы:
Как реализовать шифрование и дешифрование RSA в Java
У меня работает генерация открытых и закрытых ключей. Мой следующий шаг-создать еще 2 метода-шифрование и дешифрование. Я просто не уверен в том, как реализовать шифрование и дешифрование. У меня…
RSA шифрование в .NET, дешифрование в python
Я пытаюсь зашифровать короткое сообщение с помощью алгоритма RSA в C# и расшифровать его с помощью скрипта python. Я хотел бы использовать классы .NET на стороне C# и pycrypto на стороне python. Мне…
Шифрование и расшифровка текста с помощью RSA в PHP
Существует ли какой-либо класс для PHP 5.3, который обеспечивает шифрование/дешифрование RSA без заполнения? У меня есть закрытый и открытый ключи, p,q и модуль.
RSA шифрование и дешифрование частичного шифротекста?
Я успешно построил и скомпилировал приложение на моем PC, которое будет генерировать пару ключей RSA (я использовал GPK для длинной арифметики). Затем я проверил шифрование/дешифрование на строке…
RSA шифрование и дешифрование на разных машинах
Я пытаюсь реализовать действительно простой алгоритм RSA в C++, и я не использовал функцию openSSL. У меня есть 3 функции: generateParameter , шифрование и дешифрование . Задачей каждой функции…
X.509 RSA Шифрование / Дешифрование iOS
Мне нужно реализовать шифрование / дешифрование с использованием пары открытых / закрытых ключей X.509 RSA. До сих пор у меня есть кое-что, что, как я думаю, будет работать для шифрования, но у меня…
RSA шифрование и дешифрование в Python с использованием OpenSSL
У меня есть открытый ключ, закрытый ключ и зашифрованное сообщение ( e, n, d, message). Я хочу шифровать и расшифровывать с помощью OpenSSL в Python. У меня есть ключи, которые мне не нужно…
RSA шифрование / дешифрование не возвращает исходное сообщение
новичок здесь, пробует какое-то шифрование RSA. Я написал код python, который большую часть времени возвращает правильное сообщение, но иногда шифрование и дешифрование не возвращают исходное…
Губчатый замок RSA шифрование/дешифрование с Android хранилищем ключей
Попытка использовать SpongyCastle для предоставления предпочтительного алгоритма шифрования RSA/ECB/OAEPwithSHA-512andMGF1Padding для задач асимметричного шифрования/дешифрования на всех. ..
DES шифрование и дешифрование с использованием 2048 бит java
Существует ли какой-либо способ шифрования и дешифрования с использованием DEC/ECB 2048 бит и можем ли мы сгенерировать 2048 битный ключ с помощью DES. Я обнаружил, что DES поддерживает 64 bit, AES…
python — Как зашифровать методом RSA сообщение своим ключом?
Если Алиса хочет послать Бобу сообщение, зашифрованное его открытым ключом, не подписывая сообщение, то нужен только публичный ключ Боба:
>>> # Generate keys on Bob's computer
>>> import nacl.encoding # $ pip install pynacl
>>> import nacl.public
>>> skbob = nacl.public.PrivateKey.generate()
>>> skbob.public_key.encode(encoder=nacl.encoding.Base64Encoder)
b'eVNxqEZ1/cbiu8G+aep6OR+ccf2kZLKqDYGhtZPLnRg='
Получив этот ключ, Алиса может зашифровать своё сообщение для Боба:
>>> # Encrypt message on Alice's computer
>>> import nacl. encoding
>>> import nacl.public
>>> pkbob = nacl.public.PublicKey(b'eVNxqEZ1/cbiu8G+aep6OR+ccf2kZLKqDYGhtZPLnRg=', encoder=nacl.encoding.Base64Encoder)
>>> sealed_box = nacl.public.SealedBox(pkbob)
>>> message = b'hello world'
>>> sealed_box.encrypt(message, encoder=nacl.encoding.Base64Encoder)
b'jhh9bnv5boORCrnEVzKYxh6tMr7iJ9npzLRSpUXGAXXUuFUZQS9Y7UCSBVuyfGvA9suZ4rMDbRfBy0c='
Получив зашифрованное сообщение, Бобу легко его расшифровать:
>>> # Decrypt message on Bob's computer
>>> encrypted = b'jhh9bnv5boORCrnEVzKYxh6tMr7iJ9npzLRSpUXGAXXUuFUZQS9Y7UCSBVuyfGvA9suZ4rMDbRfBy0c='
>>> unseal_box = nacl.public.SealedBox(skbob)
>>> unseal_box.decrypt(encrypted, encoder=nacl.encoding.Base64Encoder)
b'hello world'
Приведённый код реализован на Curve25519 примитивах на эллиптических кривых.
Обратите внимание: в коде явно не упоминается ни один криптографический примитив. Чем меньше движущихся частей, которые нужно понимать, тем меньше шансов сломать что-то ненароком. См. If You’re Typing the Letters A-E-S Into Your Code You’re Doing It Wrong.
PyNaCl
это Питон-обёртка для современной переносимой libsodium крипто-библиотеки.
RSA шифрование
Чтобы зашифровать сообщение именно RSA алгоритмом, используя публичный ключ из файла, можно M2Crypto
обёртку над OpenSSL использовать:
#!/usr/bin/env python
import base64
from M2Crypto import RSA # $ pip install m2crypto
# ssh-keygen -f ~/.ssh/id_rsa.pub -e -m PKCS8 >id_rsa.pub.pem
rsa = RSA.load_pub_key('id_rsa.pub.pem') # load public key
encrypted = rsa.public_encrypt(b'hello world', RSA.pkcs1_oaep_padding) # encrypt
print(base64.b64encode(encrypted).decode()) # print as base64
Обратите внимание: здесь используетcя требуемая для новых приложений RSAES-OAEP схема.
Чтобы расшифровать encrypted_base64
сообщение, используя частный ключ из файла:
#!/usr/bin/env python
import base64
import os
from M2Crypto import RSA # $ pip install m2crypto
rsa = RSA. load_key(os.path.expanduser('~/.ssh/id_rsa')) # load private key
encrypted = base64.b64decode(encrypted_base64) # get raw bytes
print(rsa.private_decrypt(encrypted, RSA.pkcs1_oaep_padding).decode()) # decrypt
# -> hello world
RSA шифрование на Python. | LinuxBlog.РФ
Что такое RSA ?
RSA это асимметричный алгоритм шифрования. Зашифровка и расшифровка сообщение происходит двумя разными ключами, так называемый Публичны ключ за зашифровки и приватный(секретный) ключ для расшифровки сообщений . Допустим Сережа хочет отправить сообщение Алисе. Он спрашивает у Алисы ее публичный ключ для зашифровки сообщения, а Алиса вторым(секретным) ключом его расшифрует.
RSA и Python.
Для реализации RSA в Питоне мы будем использовать модуль который так и называется RSA. Он поддерживает шифрование и расшифровку, подписание и проверку подписей в соответствии с PKCS#1 версия 1.5.
Первым делом нам надо сгенерировать пару ключей(публичный и приватный).
import rsa
(pubkey, privkey) = rsa.newkeys(512) # 512 bits длина ключа, рекомендуется не меньше 1024
Так же модуль поддерживает сохранение и загрузку ключей в формате PEM и DER.
pubkey_pem = pubkey.save_pkcs1() # (format='PEM')
privkey_pem = privkey.save_pkcs1()
pubkey = rsa.PublicKey.load_pkcs1(pubkey_tmp, 'PEM') #(keyfile:bytes, format='PEM')
Теперь зашифруем и расшифруем сообщение :
message = 'hello Alisa!'.encode('utf8')
crypto = rsa.encrypt(message, pubkey) # Зашифровка
message = rsa.decrypt(crypto, privkey) # Расшифровка
print(message.decode('utf8'))
Цифровая подпись.
Цифровая подпись (ЦП) позволяет подтвердить авторство электронного документа . Подпись связана как с автором, так и с самим документом с помощью криптографических методов, и не может быть подделана с помощью обычного копирования. Наш модуль RSA позволяет подписывать сообщения для подтверждения автора и целостности сообщения :
(pubkey, privkey) = rsa.newkeys(512)
message = 'Test message'
signature = rsa.sign(message, privkey, 'SHA-1') # Создание подписи rsa.sign(message, priv_key, hash_method),можно использовать ‘MD5’, ‘SHA-1’, ‘SHA-224’, 'SHA-256’, ‘SHA-384’ и ‘SHA-512’
Для проверки подписи используйте rsa.verify() функция. Эта функция возвращает значение True, если проверка прошла успешно:
>>> message = 'Test message'
>>> rsa.verify(message, signature, pubkey)
True
Если подпись не действительно выйдет исключение rsa.pkcs1.VerificationError
>>> message = 'Test message not true'
>>> rsa.verify(message, signature, pubkey)
Traceback (most recent call last):
File "", line 1, in
File "/home/sybren/workspace/python-rsa/rsa/pkcs1. py", line 289, in verify
raise VerificationError('Verification failed')
rsa.pkcs1.VerificationError: Verification failed
Проблема больших сообщений.
RSA может шифровать только сообщения, которые меньше, чем ключ. Пара байт теряются на случайном заполнении, а остальное доступно для само послание. Например, 512-битный ключ может кодировать 53-байт сообщения (512 бит = 64 байта, 11 байт используются для случайного заполнения и другая вещь.)
Но оф. руководство нам предлагает для шифрования больших сообщений воспользоваться блочным шифром, например AES. А его ключ передать зашифрованным с помощью алгоритма RSA :
import rsa.randnum
aes_key = rsa.randnum.read_random_bits(128)# Создаем случайный ключ 128 бит
encrypted_aes_key = rsa.encrypt(aes_key, public_rsa_key) # Зашифровываем ключ и передаем для расшифровки большого сообщения.
На этом все. Успехов )
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Создание ключей RSA — CoderLessons.com
В этой главе мы сосредоточимся на пошаговой реализации алгоритма RSA с использованием Python.
Генерация ключей RSA
Следующие шаги участвуют в создании ключей RSA —
Создайте два больших простых числа, а именно p и q . Произведение этих чисел будет называться n , где n = p * q
Генерация случайного числа, которое является относительно простым с (p-1) и (q-1). Пусть число будет называться e .
Рассчитать модульную обратную величину e. Вычисленный обратный будет называться d .
Создайте два больших простых числа, а именно p и q . Произведение этих чисел будет называться n , где n = p * q
Генерация случайного числа, которое является относительно простым с (p-1) и (q-1). Пусть число будет называться e .
Рассчитать модульную обратную величину e. Вычисленный обратный будет называться d .
Алгоритмы генерации ключей RSA
Нам нужны два основных алгоритма генерации ключей RSA с использованием модуля Python — модуль Cryptomath и модуль Рабина Миллера .
Модуль Криптомата
Исходный код модуля cryptomath, который следует всем основным реализациям алгоритма RSA, выглядит следующим образом:
def gcd(a, b): while a != 0: a, b = b % a, a return b def findModInverse(a, m): if gcd(a, m) != 1: return None u1, u2, u3 = 1, 0, a v1, v2, v3 = 0, 1, m while v3 != 0: q = u3 // v3 v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3 return u1 % m
Модуль РабинМиллер
Исходный код модуля RabinMiller, который следует всем основным реализациям алгоритма RSA, выглядит следующим образом:
import random def rabinMiller(num): s = num - 1 t = 0 while s % 2 == 0: s = s // 2 t += 1 for trials in range(5): a = random. randrange(2, num - 1) v = pow(a, s, num) if v != 1: i = 0 while v != (num - 1): if i == t - 1: return False else: i = i + 1 v = (v ** 2) % num return True def isPrime(num): if (num 7< 2): return False lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997] if num in lowPrimes: return True for prime in lowPrimes: if (num % prime == 0): return False return rabinMiller(num) def generateLargePrime(keysize = 1024): while True: num = random. randrange(2**(keysize-1), 2**(keysize)) if isPrime(num): return num
Полный код для генерации ключей RSA выглядит следующим образом:
import random, sys, os, rabinMiller, cryptomath def main(): makeKeyFiles('RSA_demo', 1024) def generateKey(keySize): # Step 1: Create two prime numbers, p and q. Calculate n = p * q. print('Generating p prime...') p = rabinMiller.generateLargePrime(keySize) print('Generating q prime...') q = rabinMiller.generateLargePrime(keySize) n = p * q # Step 2: Create a number e that is relatively prime to (p-1)*(q-1). print('Generating e that is relatively prime to (p-1)*(q-1)...') while True: e = random.randrange(2 ** (keySize - 1), 2 ** (keySize)) if cryptomath.gcd(e, (p - 1) * (q - 1)) == 1: break # Step 3: Calculate d, the mod inverse of e. print('Calculating d that is mod inverse of e...') d = cryptomath.findModInverse(e, (p - 1) * (q - 1)) publicKey = (n, e) privateKey = (n, d) print('Public key:', publicKey) print('Private key:', privateKey) return (publicKey, privateKey) def makeKeyFiles(name, keySize): # Creates two files 'x_pubkey. txt' and 'x_privkey.txt' (where x is the value in name) with the the n,e and d,e integers written in them, # delimited by a comma. if os.path.exists('%s_pubkey.txt' % (name)) or os.path.exists('%s_privkey.txt' % (name)): sys.exit('WARNING: The file %s_pubkey.txt or %s_privkey.txt already exists! Use a different name or delete these files and re-run this program.' % (name, name)) publicKey, privateKey = generateKey(keySize) print() print('The public key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1])))) print('Writing public key to file %s_pubkey.txt...' % (name)) fo = open('%s_pubkey.txt' % (name), 'w') fo.write('%s,%s,%s' % (keySize, publicKey[0], publicKey[1])) fo.close() print() print('The private key is a %s and a %s digit number.' % (len(str(publicKey[0])), len(str(publicKey[1])))) print('Writing private key to file %s_privkey.txt...' % (name)) fo = open('%s_privkey.txt' % (name), 'w') fo. write('%s,%s,%s' % (keySize, privateKey[0], privateKey[1])) fo.close() # If makeRsaKeys.py is run (instead of imported as a module) call # the main() function. if __name__ == '__main__': main()
Выход
Открытый ключ и закрытый ключ создаются и сохраняются в соответствующих файлах, как показано в следующем выводе.
Реализация Python метода шифрования RSA
Прежде всего, код файла генерации закрытого ключа открытого ключа находится здесь:https://blog.csdn.net/qq_41938259/article/details/86765012
Это оригинальный текст до шифрования: как Бог, как мой свидетель … как бог, как мой свидетель, они не собираются меня лизать. Я собираюсь пережить это, и когда все закончится, я никогда не буду голоден Снова. Нет, ни один из моих людей. Если мне придется лгать, красть, обманывать или убивать, как Бог, как мой свидетель, я никогда больше не буду голоден .—— Унесенные ветром
Сначала приведите примеры ввода / вывода:
Код и реализация приведены ниже, и я думаю, что комментарии очень подробны:
import sys
DEFAULT_BLOCK_SIZE = 128 # Размер блока по умолчанию составляет 128 байт
BYTE_SIZE = 256 # 1 байт по умолчанию имеет 256 различных значений
def main():
filename = 'encrypted_file. txt'
mode = input ('Input E - это шифрование, input D - это дешифрование:'). lower ()
if mode=='e':
try:
message=open(filename).read()
except IOError:
print («Не удалось открыть файл.»)
else:
pubKeyFilename='al_sweigart_pubkey.txt'
печать ( 'Шифрование ...')
encryptedText=encryptAndWriteToFile(filename,pubKeyFilename,message)
print ('Содержимое зашифрованного файла:')
print(encryptedText)
elif mode=='d':
privKeyFilename='al_sweigart_privkey.txt'
печать ( 'дешифрование ...')
try:
decryptedText=readFromFileAndDecrypt(filename,privKeyFilename)
except IOError:
print («Не удалось открыть файл.»)
else:
print ('Расшифровать содержимое имени файла:')
print(decryptedText)
#getBlocksFromText () функция принимает сообщение и возвращает представляющий его список, элементами которого являются блоки
def getBlocksFromText(message,blockSize=DEFAULT_BLOCK_SIZE):
messageBytes = message. encode ('ascii') # Преобразовать в число, соответствующее коду ASCII
blockInts=[]
#for цикл для создания больших целых чисел и, наконец, сохранения в blockInt
for blockStart in range(0,len(messageBytes),blockSize):
blockInt=0
for i in range(blockStart,min(blockStart+blockSize,len(messageBytes))):
blockInt+=messageBytes[i]*(BYTE_SIZE**(i%blockSize))
blockInts.append(blockInt)
# Возвращает список blockInts вместо больших чисел blockInt
return blockInts
# Преобразовать список блоков в исходную строку
def getTextFromBlocks(blockInts,messageLength,blockSize=DEFAULT_BLOCK_SIZE):
message=[]
for blockInt in blockInts:
blockMessage=[]
for i in range(blockSize-1,-1,-1):
if len(message)+i<messageLength:
asciiNumber=blockInt//(BYTE_SIZE**i)
blockInt=blockInt%(BYTE_SIZE**i)
blockMessage.insert(0,chr(asciiNumber))
message.extend(blockMessage)
return ''. e mod n операция
decryptedBlocks.append(pow(block,d,n))
return getTextFromBlocks(decryptedBlocks,messageLength,blockSize)
# Читать открытый ключ и закрытый ключ из файла ключей
#Format: размер ключа целое, n большое целое, e или d большое целое
#split () делится в соответствии с запятой и сохраняется в переменной содержимого в строковом формате
def readKeyFile(keyFilename):
fo=open(keyFilename)
content=fo.read()
fo.close()
keySize,n,EorD=content.split(',')
return(int(keySize),int(n),int(EorD))
# Функция принимает три параметра, а именно имя файла для записи зашифрованного сообщения, требуемое имя файла открытого ключа и зашифрованное сообщение ключа
def encryptAndWriteToFile(messageFilename,keyFilename,message,blockSize=DEFAULT_BLOCK_SIZE):
# Чтение открытых и закрытых ключей
keySize, n, e = readKeyFile(keyFilename)
# Подтвердите, что размер правильный
if keySize <blockSize * 8: # 8 бит на блок
sys.exit(
'ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Either decrease the block size or use different keys.' % (
blockSize * 8, keySize))
# Процесс шифрования
encryptedBlocks = encryptMessage(message, (n, e), blockSize)
# Конвертировать большие числа в строки
for i in range(len(encryptedBlocks)):
encryptedBlocks[i] = str(encryptedBlocks[i])
encryptedContent = ','.join(encryptedBlocks)
# Написать текстовый файл
encryptedContent = '%s_%s_%s' % (len(message), blockSize, encryptedContent)
fo = open(messageFilename, 'w')
fo.write(encryptedContent)
fo.close()
# И вернуть зашифрованный контент на экран
return encryptedContent
# Два параметра функции - файл зашифрованного текста и ключевая информация
def readFromFileAndDecrypt(messageFilename, keyFilename):
keySize, n, d = readKeyFile(keyFilename)
# Процесс дешифрования
fo = open(messageFilename)
content = fo. read()
messageLength, blockSize, encryptedMessage = content.split('_')
messageLength = int(messageLength)
blockSize = int(blockSize)
# Check that key size is greater than block size.
if keySize < blockSize * 8: # * 8 to convert bytes to bits
sys.exit(
'ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or greater than the key size. Did you specify the correct key file and encrypted file?' % (
blockSize * 8, keySize))
# Конвертировать зашифрованный текст в большие числа
encryptedBlocks = []
for block in encryptedMessage.split(','):
encryptedBlocks.append(int(block))
# Вернуть результат расшифровки
return decryptMessage(encryptedBlocks, messageLength, (n, d), blockSize)
if __name__ == '__main__':
main()
Python Crypto, Открытый/Закрытый Ключ Rsa, С Большим Файлом
RSA довольно медленный, поэтому он не подходит для шифрования/дешифрования больших блоков данных. Он обычно используется для шифрования/дешифрования ключей более быстрого симметричного шифра, например AES.
С первого взгляда ваши зашифрованные данные выглядят немного малыми, чтобы соответствовать вашим входным данным, но я не знаком с Crypto (я установил его только несколько дней назад), поэтому я не могу объяснить, что это такое сделанные с вашими данными.
Но этот код работает для меня:
#!/usr/bin/env python
from Crypto.PublicKey import RSA
from Crypto import Random
src_data = 'To be, or not to be - that is the question.'
print `src_data`
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
print 'Key generated'
pub_key = key.publickey()
print 'Public key', pub_key
enc_data = pub_key.encrypt(src_data, 32)[0]
print `enc_data`
dec_data = key.decrypt(enc_data)
print `dec_data`
типичный выход
'To be, or not to be - that is the question. '
Key generated
Public key <_RSAobj @0xb7114dcc n(1024),e>
',\x17\xb1\x8a\x98\xb0-z\x8c\xb8r\x17\xa2\xfe[\x10I\x97\x93\x9d[\x93\x19&\\\x16V\xc2\xa3\x99\x80\xa5\x08\xafT\xb5iA|\x89\xeeJ\x90%\xceXv\x9f\x9f\xcb\\P"i\x00D\xd4\x16\xee\xa9\xe49\x18[\xa5\x0f\xd3\xfb\x91\xd5\x98\x1bP\xbf\xa4\xa5Dz\x8b7\x13\x9dqk+\xf7A\xd3\x12\x1c\x06\xcep\xf2\xba\xc6\xee\xf8\xa2\xb4\x04v\xfb\xb7>\xb3U\x17\xban\xf7\xc0oM+Tq\xce\xe3D\x83\xb9\xa4\x90\xe6c,\x18'
'To be, or not to be - that is the question.'
FWIW, здесь немного измененная версия выше, которая работает как на Python 2, так и на Python 3, хотя будут незначительные различия в выходе двух версий.
В Python 3 мы не можем передавать строки на функции шифрования или дешифрования, мы должны передавать байты. Кроме того, Python 3 не поддерживает синтаксис backticks, который получает repr
объекта в Python 2.
Этот код вызывает методы .encode()
и bytes .decode()
для выполнения преобразований. Мы могли бы указать кодирующий кодек, например
src_data.encode('utf-8')
но это не обязательно, поскольку UTF-8 является кодеком по умолчанию.
from __future__ import print_function
from Crypto.PublicKey import RSA
from Crypto import Random
src_data = 'To be, or not to be - that is the question.'
print(repr(src_data))
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
pub_key = key.publickey()
print('Key generated')
print(key.exportKey().decode())
print(pub_key.exportKey().decode())
enc_data = pub_key.encrypt(src_data.encode(), 32)[0]
print('Encoded\n', repr(enc_data))
dec_data = key.decrypt(enc_data).decode()
print('Decoded\n', repr(dec_data))
Типичный вывод Python 3
'To be, or not to be - that is the question.'
Key generated
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDL/TzI4yHmlcC8qP3xWNieujmXR7CnEaZJrDh2Hyr/tGNa0aEE
jDIz+RlMntBbhOuiQMkMtCSB5X28h7HetiD4XkWTXmlIiKZQLZ074cO5mxF+HhF7
WIG30VONpX+Q4t/beqtaqbzyeIWvDdcCjUwOSQLrUKU5PX9LFzX+FnN1UwIDAQAB
AoGASRVZib+Wjb5pZy5EjQt/0J53s7ODnte78/k1jNS12xcN4aPpRG/WLLi6T7E2
hROCOIdtgJep3MAT5E/ZciledflaDwwmLo6+NsrhMppsNhpIHsvxWxmwxnH+bC2H
lpyeUmxku4xzqwYW4kuF3iaR45K2eUpXQyWTE9+pgvepgoECQQDT6Waiavstvs4W
btW2P4J+7O//NmTcvnyLTnhFTXklxTxnSun54HYOce8+TttsXWESTbzf91saN5SW
0vPyKK25AkEA9m3gbwFppiA65464jnDCP1AnrR15n3tbsLpaadYdRm07b+4BB0R2
M820cgber14JiGndOfv1uPl1Ooy0Ih5hawJBAJKRC/uqIrAxGDlLz2SN6KQBHL1X
0csbtOhlDaphOzl0gaKvncTGCuFSzDY8NGdu7oTKX6hIXSp05sCqhy8mE4ECQE49
xKx5/llIkmtC3UYcdxAzGuXUHfGM8SfDg0FnQhRCSkTXhGwSSJVaEpjBpaJ4cP5m
3l6yqOn6CkZ0thw679ECQCWNC5hVEtsAb0TcjGdTpw+xTFusiZciNyHTQ64Zq2cc
ehQrxTRDIEBA4wIgUwrTwdVXk10OtpcVZvLIVjqdC84=
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL/TzI4yHmlcC8qP3xWNieujmX
R7CnEaZJrDh2Hyr/tGNa0aEEjDIz+RlMntBbhOuiQMkMtCSB5X28h7HetiD4XkWT
XmlIiKZQLZ074cO5mxF+HhF7WIG30VONpX+Q4t/beqtaqbzyeIWvDdcCjUwOSQLr
UKU5PX9LFzX+FnN1UwIDAQAB
-----END PUBLIC KEY-----
Encoded
b'\x843\x9aJ\xe6\x91p\xd2\x9c\xd0r{37\xa2G\x13Q\xc7~\xbd5\xce\x9f\xd4\x16\xda\x11\x02. \xb7\xf1\xf3Q\x8c|\xb0R2B\x1b)e\xeaD\x8e\x11\x1b\xb0J:\xbal\xac\x86\xdcb}_\x16IX\xccd\x0c\xb5E?Im<\x04ORT\xc9\xc6K|;\xf3\xbcK\xfd\x89\x96ZF(\x0b\x82v\x19`\xc3\xa1N\x934*\x9c\xfcT\xf4i\x02g\x1fl\xec\xc1\x19z\x9f7\xa6}\xe2\xe3}\xaa|\x1e\x13z\xd9$\xea'
Decoded
'To be, or not to be - that is the question.'
Нам действительно не нужно использовать кодировку UTF-8. Поскольку src_data
является чистой 7-разрядной строкой ASCII, и мы ввели ее в script как литерал, мы могли бы поставить ее как литеральную строку байта:
src_data = b'To be, or not to be - that is the question.'
Шифрование и криптография в Python
В Python не так уж много инструментов стандартной библиотеки, которые работают с шифрованием. Однако, в нашем распоряжении есть библиотеки хешинга. Давайте рассмотрим этот вопрос в данной статье, но более детально сфокусируемся на двух сторонних пакетах: PyCrypto и cryptography. Мы научимся шифровать и расшифровывать строки при помощи двух этих библиотек.
Хеширование
Если вам нужно защитить хэши или алгоритм дайджеста сообщений, то для этого прекрасно подойдет модуль стандартной библиотеки Python hashlib. Он включает в себя безопасные алгоритмы хеширования FIPS, такие как SHA1, SHA224, SHA256, SHA384, а также SHA512 и MD5. Python также поддерживает функции хеширования adler32 и crc32, но они содержатся в модуле zlib. Одно из самых популярны применений хеширования это хранение хеша пароля, вместо самого пароля. Конечно, хеш должен быть хорошим, в противном случае он может быть расшифрован.
Другой популярный случай, в котором применяется хеширование – это хеширование файла, с последующей отправкой файла и его хеша по отдельности. Получатель файла может запустить хеш в файле, чтобы убедиться в том, что файл соответствует отправленному хешу. Если это так, значит никто не менял файл, когда он был отправлен. Давайте попробуем создать хеш md5. Но оказывается, чтобы использовать хеш md5, нужно передать его строке байта, вместо обычной. Так что мы попробовали сделать это, после чего вызвали метод дайджеста, чтобы получить наш хеш. Если вы претпочитаете хешированный дайджест, мы можем сделать и это:
import hashlib
hashlib.md5.update(b’Python rocks!’)
result = hashlib.md5.digest()
print(result)
# b’\x14\x82\xec\x1b#d\xf6N}\x16*+[\x16\xf4w’
import hashlib hashlib.md5.update(b’Python rocks!’) result = hashlib.md5.digest()
print(result) # b’\x14\x82\xec\x1b#d\xf6N}\x16*+[\x16\xf4w’ |
Давайте уделим время на то, чтобы разобраться с увиденным. Сначала мы импортировали модуль hashlib и создали экземпляр объекта md5 HASH. Далее, мы вписали небольшой текст в объект хеша и получили трассировку.
print( md5. hexdigest() )
# ‘1482ec1b2364f64e7d162a2b5b16f477’
print( md5.hexdigest() ) # ‘1482ec1b2364f64e7d162a2b5b16f477’ |
На самом деле существует метод быстрого создания хеша, мы рассмотрим его, когда создадим наш хеш sha512:
import hashlib
sha = hashlib.sha1(b’Hello Python’).hexdigest()
print(sha) # ‘422fbfbc67fe17c86642c5eaaa48f8b670cbed1b’
import hashlib sha = hashlib.sha1(b’Hello Python’).hexdigest()
print(sha) # ‘422fbfbc67fe17c86642c5eaaa48f8b670cbed1b’ |
Как вы видите, мы создали наш экземпляр хеша и вызвали его метод дайджеста одновременно. Далее, мы выводим наш хеш, чтобы на него посмотреть. Лично я использую хеш sha1, так как его хеш достаточно короткий и отлично ложится в страницу. Но в то же время он и не очень безопасный, так что вы вольны выбирать то, что вам удобно.
Вывод ключа
У Python весьма ограниченная поддержка вывода ключа, встроенная в стандартную библиотеку. Фактически, единственный метод, предлагаемый hashlib это pbkdf2_hmac, который является основанной на пароле функцией вывода ключа PKCS#5. Он использует HMAC в качестве своей псевдослучайной функцией. Вы можете использовать что-нибудь на подобии для хеширования вашего пароля, так как он поддерживает соль и итерации. Например, если вы собираетесь использовать SHA-256, вам может понадобиться соль минимум в 16 битов и 100.000 итераций. Являясь быстрой отсылкой, соль — это просто случайные данные, которые вы используете в качестве дополнения в вашем хеше, с целью усложнения расшифровки вашего пароля. В целом, она защищает ваш пароль от словарных атак и рассчитанных заранее радужных таблиц. Давайте посмотрим на пример:
import binascii
dk = hashlib.pbkdf2_hmac(hash_name=’sha256′,
password=b’bad_password34′,
salt=b’bad_salt’,
iterations=100000)
result = binascii.hexlify(dk)
print(result)
# b’6e97bad21f6200f9087036a71e7ca9fa01a59e1d697f7e0284cd7f9b897d7c02′
import binascii
dk = hashlib.pbkdf2_hmac(hash_name=’sha256′, password=b’bad_password34′, salt=b’bad_salt’, iterations=100000)
result = binascii.hexlify(dk)
print(result) # b’6e97bad21f6200f9087036a71e7ca9fa01a59e1d697f7e0284cd7f9b897d7c02′ |
Здесь мы создаем хеш SHA256 в пароле при помощи такой-себе соли со 100,000 итераций. Конечно, SHA в буквальном смысле не рекомендуется для создания ключей паролей. Вместо этого, вам лучше использовать что-то вроде scrypt. Еще одним полезным инструментом может быть сторонний пакет bcrypt. Он разработан специально для хеширования паролей.
PyCrypto
Пакет PyCrypto, наверное, самый известный сторонний пакет криптографии для Python. К сожалению, его доработка остановилась в 2012 году. Однако продолжается выпускаться под разные версии Python, вы можете получить PyCrypto для версии 3.5 включительно, если вы не брезгуете использовать двоичный код стороннего производства. К примеру, я нашел несколько бинарных колес Python 3.5 для PyCrypto на Github (https://github.com/sfbahr/PyCrypto-Wheels). К счастью, есть развилка проекта под названием PyCrytodome, которая является неплохой заменой PyCrypto. Для его установки на Linux вы можете использовать следующую команду:
Для Windows немного отличается.
pip install pycryptodomex
pip install pycryptodomex |
Если вы столкнетесь со сложностями, это, возможно, связанно с тем, что у вас нет необходимых установленных зависимостей, или необходим компилятор под Windows. Вы можете перейти на официальный сайт PyCryptodome для дополнительной информации о установке, или чтобы связаться с поддержкой. Также стоит отметить, что PyCryptodome имеет ряд преимуществ в сравнении с последней версией PyCrypto. Рекомендую потратить немного времени и посетить их сайт, для ознакомления с возможностями PyCryptodome.
Шифрование Строки
Теперь (после того, как вы ознакомились с информацией на сайте, я надеюсь), мы можем перейти к дальнейшим примерам. Для нашего следующего кода мы используем DES для шифровки строки:
from Crypto.Cipher import DES
key = b’abcdefgh’
def pad(text):
while len(text) % 8 != 0:
text += b’ ‘
return text
des = DES.new(key, DES.MODE_ECB)
text = b’Python rocks!’
padded_text = pad(text)
encrypted_text = des.encrypt(padded_text)
print(encrypted_text)
# b’>\xfc\x1f\x16x\x87\xb2\x93\x0e\xfcH\x02\xd59VQ’
from Crypto.Cipher import DES
key = b’abcdefgh’
def pad(text): while len(text) % 8 != 0: text += b’ ‘ return text
des = DES.new(key, DES.MODE_ECB) text = b’Python rocks!’ padded_text = pad(text)
encrypted_text = des.encrypt(padded_text) print(encrypted_text) # b’>\xfc\x1f\x16x\x87\xb2\x93\x0e\xfcH\x02\xd59VQ’ |
Этот код слегка запутанный, так что давайте уделим немного времени на его анализ. Во первых, обратите внимание на то, что размер ключа под шифровку DES — 8 байт, по этому мы установили нашу переменную ключа в строку размер букв строки. Шифруемая нами строка должна быть кратна 8 в ширину, так что мы создаем функцию под названием pad, которая может заполнить любую строку пробелами, пока она не станет кратна 8. Далее мы создаем экземпляр DES и текст, который нам нужно зашифровать. Мы также создаем заполненную версию текста. Прикола ради, мы попытаемся зашифровать начальный, незаполненный вариант строки, что приведет нас к ошибке ValueError. Таким образом Python ясно дает нам понять, что нам нужно использовать заполненную строку, так что мы передаем вторую версию. Как вы видите, мы получаем зашифрованную строку! Конечно, пример нельзя назвать полным, если мы не выясним, как расшифровать нашу строку:
data = des.decrypt(encrypted_text)
print(data) # Python rocks!
data = des.decrypt(encrypted_text) print(data) # Python rocks! |
К счастью, это очень легко сделать, так как все что нам нужно, это вызвать метод decrypt в нашем объекте des для получения расшифрованной байтовой строки. Наша следующая задача — научиться шифровать файлы и расшифровывать файлы с PyCrypto при помощи RSA. Но для начала, нам нужно создать ключи RSA.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Создание ключей RSA
Если вам нужно зашифровать ваши данные при помощи RSA, тогда вам также нужно получить доступ к паре ключа RSA public / private, или сгенерировать собственную. В данном примере мы генерируем собственную пару ключей. Так как это весьма легко, мы сделаем это в интерпретаторе Python:
from Crypto.PublicKey import RSA
code = ‘nooneknows’
key = RSA.generate(2048)
encrypted_key = key.exportKey(
passphrase=code,
pkcs=8,
protection=»scryptAndAES128-CBC»
)
with open(‘my_private_rsa_key.bin’, ‘wb’) as f:
f.write(encrypted_key)
with open(‘my_rsa_public.pem’, ‘wb’) as f:
f.write(key.publickey().exportKey())
from Crypto.PublicKey import RSA
code = ‘nooneknows’ key = RSA.generate(2048)
encrypted_key = key.exportKey( passphrase=code, pkcs=8, protection=»scryptAndAES128-CBC» )
with open(‘my_private_rsa_key.bin’, ‘wb’) as f: f.write(encrypted_key)
with open(‘my_rsa_public.pem’, ‘wb’) as f: f.write(key.publickey().exportKey()) |
Сначала мы импортируем RSA из Crypto.PublicKey. Затем, мы создаем примитивный код доступа. Далее, мы генерируем ключ RSA на 2048 битов. Теперь мы подходим к интересной части. Для генерации приватного ключа, нам нужно вызвать метод exportKey нашего ключа RSA, и передать ему наш код доступа, который будет использован стандартом PKCS, чья схема шифровки будет использована для защиты нашего приватного ключа. После этого мы записываем файл на диск. Далее, мы создаем наш приватный ключ через метод publickey нашего ключа RSA. Мы использовали короткий путь в этой части кода, связав вызов метода exportKey с методом publickey для записи файла на диск.
Шифровка файла
Теперь у нас в распоряжении есть и приватный и публичный ключи, так что мы можем зашифровать кое-какие данные и вписать их в файл. Вот достаточно простой пример:
from Crypto.PublicKey import RSA
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES, PKCS1_OAEP
with open(‘encrypted_data.bin’, ‘wb’) as out_file:
recipient_key = RSA.import_key(
open(‘my_rsa_public.pem’).read()
)
session_key = get_random_bytes(16)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
out_file.write(cipher_rsa.encrypt(session_key))
cipher_aes = AES.new(session_key, AES.MODE_EAX)
data = b’blah blah blah Python blah blah’
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
out_file.write(cipher_aes.nonce)
out_file.write(tag)
out_file.write(ciphertext)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from Crypto.PublicKey import RSA from Crypto.Random import get_random_bytes from Crypto.Cipher import AES, PKCS1_OAEP
with open(‘encrypted_data.bin’, ‘wb’) as out_file: recipient_key = RSA.import_key( open(‘my_rsa_public.pem’).read() )
session_key = get_random_bytes(16)
cipher_rsa = PKCS1_OAEP.new(recipient_key) out_file.write(cipher_rsa.encrypt(session_key))
cipher_aes = AES.new(session_key, AES.MODE_EAX) data = b’blah blah blah Python blah blah’ ciphertext, tag = cipher_aes.encrypt_and_digest(data)
out_file.write(cipher_aes.nonce) out_file.write(tag) out_file.write(ciphertext) |
Первые три строки покрывают наши импорты из PyCryptodome. Далее мы открываем файл для записи. Далее, мы импортируем наш публичный ключ в переменной и создаем 16-битный ключ сессии. Для этого примера мы будем использовать гибридный метод шифрования, так что мы используем PKCS#1 OAEP (Optimal asymmetric encryption padding). Это позволяет нам записывать данные произвольной длинны в файл. Далее, мы создаем наш шифр AES, создаем кое-какие данные и шифруем их. Это дает нам зашифрованный текст и MAC. Наконец, мы выписываем nonce, MAC (или тег), а также зашифрованный текст. К слову, nonce – это произвольное число, которое используется только в криптографических связях. Обычно это случайные или псевдослучайные числа. Для AES, оно должно быть минимум 16 байтов в ширину. Вы вольны попытаться открыть зашифрованный файл в своем текстовом редакторе. Вы увидите только какое-то безобразие. Теперь попробуем расшифровать наши данные:
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEP
code = ‘nooneknows’
with open(‘encrypted_data.bin’, ‘rb’) as fobj:
private_key = RSA.import_key(
open(‘my_rsa_key.pem’).read(),
passphrase=code
)
enc_session_key, nonce, tag, ciphertext = [
fobj.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1)
]
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
print(data)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | from Crypto.PublicKey import RSA from Crypto.Cipher import AES, PKCS1_OAEP
code = ‘nooneknows’
with open(‘encrypted_data.bin’, ‘rb’) as fobj: private_key = RSA.import_key( open(‘my_rsa_key.pem’).read(), passphrase=code )
enc_session_key, nonce, tag, ciphertext = [ fobj.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1) ]
cipher_rsa = PKCS1_OAEP.new(private_key) session_key = cipher_rsa.decrypt(enc_session_key)
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce) data = cipher_aes.decrypt_and_verify(ciphertext, tag)
print(data) |
Если вы разобрались с предыдущим примером, то этот код должен быть весьма простым для разбора. В данном случае, мы открываем наш зашифрованный файл для чтения в бинарном режиме. Далее, мы импортируем наш приватный ключ. Обратите внимание на то, что когда вы импортируете приватный ключ, вы должны передать ему код доступа. В противном случае возникнет ошибка. Далее мы считываем наш файл. Вы заметите, что сначала мы считываем приватный ключ, затем 16 байтов для nonce, за которыми следуют 16 байтов, которые являются тегом, и наконец, остальную часть файла, который и является нашими данными. Далее нам нужно расшифровать наш ключ сессии, пересоздать наш ключ AES и расшифровать данные. Вы можете использовать PyCryptodome в намного более широком ряде случаев. Однако, нам нужно идти дальше и посмотреть, что еще мы можем сделать для наших криптографических нужд в Python.
Пакет cryptography
Пакет cryptography нацелен на то, чтобы быть «криптографом для людей», равно как и библиотека requests является «HTTP для людей». Суть в том, что вам нужно разработать простые криптографические рецепты которые и безопасны, и простые в использовании. Если нужно, вы можете перейти к низкоуровневым криптографическим примитивам, для которых требуется лишь знать, что вы делаете, в противном случае вы создадите что-то явно бесполезное в контексте защиты. Если вы работаете в Python 3.5 Windows, вы можете установить этот пакет при помощи pip следующим образом:
Вы увидите, что cryptography установится совместно с несколькими зависимостями. Предположим, что с установкой все прошло чисто, и мы можем зашифровать какой-нибудь текст. Давайте используем для этого модуль Fernet.
Модуль Fernet реализует простую в использовании схему аутентификации, которая использует симметричный алгоритм шифрования, который гарантирует, что каждое зашифрованное в нем сообщение не может быть использовано или прочитано без определенного вами ключа. Модуль Fernet также поддерживает ключ ротации через MultiFernet. Давайте взглянем на простой пример:
from cryptography.fernet import Fernet
cipher_key = Fernet.generate_key()
print(cipher_key) # APM1JDVgT8WDGOWBgQv6EIhvxl4vDYvUnVdg-Vjdt0o=
from cryptography.fernet import Fernet
cipher_key = Fernet.generate_key() print(cipher_key) # APM1JDVgT8WDGOWBgQv6EIhvxl4vDYvUnVdg-Vjdt0o= |
from cryptography.fernet import Fernet
cipher = Fernet(cipher_key)
text = b’My super secret message’
encrypted_text = cipher.encrypt(text)
print(encrypted_text)
# (b’gAAAAABXOnV86aeUGADA6mTe9xEL92y_m0_TlC9vcqaF6NzHqRKkjEqh5d21PInEP3C9HuiUkS9f’
# b’6bdHsSlRiCNWbSkPuRd_62zfEv3eaZjJvLAm3omnya8=’)
from cryptography.fernet import Fernet
cipher = Fernet(cipher_key) text = b’My super secret message’ encrypted_text = cipher.encrypt(text)
print(encrypted_text)
# (b’gAAAAABXOnV86aeUGADA6mTe9xEL92y_m0_TlC9vcqaF6NzHqRKkjEqh5d21PInEP3C9HuiUkS9f’ # b’6bdHsSlRiCNWbSkPuRd_62zfEv3eaZjJvLAm3omnya8=’) |
decrypted_text = cipher.decrypt(encrypted_text)
print(decrypted_text) # ‘My super secret message’
decrypted_text = cipher.decrypt(encrypted_text) print(decrypted_text) # ‘My super secret message’ |
Для начала, нам нужно импортировать Fernet. Затем мы генерируем ключ. Мы выводим ключ, чтобы увидеть, как он выглядит. Как вы видите, это случайна строка байтов. Если хотите, вы можете попробовать запустить метод generate_key несколько раз. Результат каждый раз новый. Далее мы создаем экземпляр нашего шифра Fernet при помощи нашего ключа. Теперь у нас есть шифр, который мы можем использовать для шифрования и расшифровки нашего сообщения. Следующий шаг, это создание сообщения, достойного шифровки, с последующей его шифровкой при помощи метода encrypt. Я пошел вперед и вывел наш зашифрованный текст так, чтобы вы увидели что вы больше не можете его читать. Для расшифровки нашего супер-засекреченного сообщения, мы просто вызовем метод decrypt в нашем шифре и передадим зашифрованный текст. В результате мы получим текстовую байтовую строку нашего сообщения.
Подведем Итоги
В данной статье мы изрядно прошлись по поверхности вопроса : «Как, и что делать с пакетами PyCryptodome и cryptography?». Мы рассмотрели изрядное количество вариантов применения данных пакетов в шифровании и расшифровке строк и файлов. Убедитесь в том, что уделите время документации, перед тем как начать экспериментировать с изложенной в данной статье информацией.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: [email protected]
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
RSA · PyPI
Описание проекта
Python-RSA — это реализация RSA на чистом Python. Он поддерживает
шифрование и дешифрование, подпись и проверка подписей и ключей
генерация по PKCS # 1 версии 1.5. Его можно использовать как Python
библиотека, а также в командной строке. Код в основном был написан
Сибрен А. Стювель.
Документацию можно найти на домашней странице Python-RSA. Все изменения проверяйте в журнале изменений.
Загрузите и установите, используя:
pip install rsa
или загрузите его из индекса пакетов Python.
Исходный код поддерживается на GitHub и
под лицензией Apache License, версия 2.0
Безопасность
Из-за того, как Python хранит числа внутри, очень сложно (если не невозможно) обезопасить программу на чистом Python от временных атак. Эта библиотека не является исключением, поэтому используйте ее с осторожностью. См. Https: // securitypitfalls.wordpress.com/2018/08/03/constant-time-compare-in-python/ для получения дополнительной информации.
Основные изменения в 4.1
Версия 4.0 была последней версией, поддерживающей Python 2 и 3.4. Версия 4.1 совместима только с Python 3.5+.
Основные изменения в 4.0
Версия 3.4 была последней версией в диапазоне 3.x. Версия 4.0 удаляет следующие модули,
поскольку они небезопасны:
-
rsa._version133
-
rsa._version200
-
RSA.большой файл
-
rsa.varblock
Эти модули были помечены как устаревшие в версии 3.4.
Кроме того, в 4.0 функции ввода / вывода оптимизированы, чтобы всегда работать с байтами на всех
поддерживаемые версии Python.
Версия 4.0 отказывается от поддержки Python 2.6 и 3.3.
Скачать файлы
Загрузите файл для своей платформы. Если вы не уверены, что выбрать, узнайте больше об установке пакетов.
Имя файла, размер | Тип файла | Версия Python | Дата загрузки | Хеши |
---|---|---|---|---|
Имя файла, размер rsa-4.7.2-py3-none-any.whl (34.5 кБ) | Тип файла Колесо | Версия Python py3 | Дата загрузки | Хеши Вид |
Имя файла, размер РСА-4.7.2.tar.gz (39,7 кБ) | Тип файла Источник | Версия Python Никто | Дата загрузки | Хеши Вид |
Python RSA шифрование — qaru
Во-первых, <_RSAobj @ 0x24b6348 n <1024>, e, d, p, q, u, private>
не является допустимым ключом, не знаю, как вы его получили, но это строковое представление вашего ключа в виде Только объект Python
, фактическое содержимое ключа не представлено, также обратите внимание, что вы не можете перестроить объект ключа с этим строковым представлением .
Прежде чем выполнять RSA-шифрование с помощью ключа, необходимо импортировать ключ из какого-нибудь места, например, , файл , , генерируемый в памяти, и т.
Итак, что вам следует сделать, это:
ключ = RSA.importKey (externKey, кодовая фраза = None)
Где externKey
является строкой, поэтому вы можете загрузить строку ключа из файла ключа таким образом.
или :
ключ = RSA.generate (биты, randfunc = None, progress_func = None, e = 65537)
Где бит
— сила вашего ключа, e.г 2048.
В любом случае вам будет возвращен объект ключа RSA ( _RSAobj
), а затем вы сможете выполнить шифрование, как и остальная часть вашего кода.
[РЕДАКТИРОВАТЬ] Полный код
импорт Crypto
из Crypto.PublicKey импортировать RSA
# Быстрый способ сгенерировать новый ключ
private_key = RSA.generate (1024)
# Покажите на консоль реальное содержимое приватной части, будьте осторожны с этим!
печать (private_key.exportKey ())
# Получить публичную часть
public_key = private_key.publickey ()
# Показать реальное содержание публичной части на консоль
печать (public_key.exportKey ())
# Сохраните оба ключа в какой-нибудь файл для будущего использования при необходимости
с open ("rsa.pub", "w") как pub_file:
pub_file.write (public_key.exportKey ())
с open ("rsa.pvt", "w") как pvt_file:
pvt_file.write (private_key.exportKey ())
# Загрузите открытый ключ обратно из файла, и нам понадобится только открытый ключ для шифрования
с open ('rsa.pub', 'r') как pub_file:
pub_key = RSA.importKey (pub_file.read ())
# Зашифруйте что-нибудь с открытым ключом и распечатайте в консоли
encrypted = pub_key.encrypt ('hello world', None) # второй параметр None здесь бесполезен
печать (зашифрованный)
# Загрузите закрытый ключ обратно из файла, и нам понадобится закрытый ключ для расшифровки
с открытым ('rsa.pvt ',' r ') как pvt_file:
pvt_key = RSA.importKey (pvt_file.read ())
# Расшифровать текст закрытым ключом и распечатать в консоли
text = pvt_key.decrypt (зашифрованный)
печать (текст)
Как я могу зашифровать с помощью закрытого ключа RSA в Python?
Короткий ответ
- код, который вы используете, не позволяет сделать это по соображениям безопасности
- альтернативный код ниже
Длинный ответ
Мне была интересна ваша проблема, и я попытался ввести код
.
Через некоторое время я понял, что если вы запустите этот сниппет, вы увидите, что он работает правильно:
#! / Usr / bin / env питон
от Crypto.PublicKey импорт RSA
из Crypto.Cipher импорт PKCS1_OAEP
импорт base64
def generate_keys ():
длина_модуля = 1024
ключ = RSA.generate (длина_модуля)
#print (key.exportKey ())
pub_key = key.publickey ()
#print (pub_key.exportKey ())
ключ возврата, pub_key
def encrypt_private_key (a_message, private_key):
encryptor = PKCS1_OAEP.new (частный_ ключ)
encrypted_msg = encryptor.encrypt (a_message)
печать (encrypted_msg)
encoded_encrypted_msg = base64.b64encode (encrypted_msg)
печать (encoded_encrypted_msg)
вернуть encoded_encrypted_msg
def decrypt_public_key (encoded_encrypted_msg, public_key):
шифровальщик = PKCS1_OAEP.новый (public_key)
decoded_encrypted_msg = base64.b64decode (encoded_encrypted_msg)
печать (decoded_encrypted_msg)
decoded_decrypted_msg = encryptor.decrypt (decoded_encrypted_msg)
печать (decoded_decrypted_msg)
#return decoded_decrypted_msg
def main ():
частный, общедоступный = generate_keys ()
печать (частный)
message = b'Hello world '
encoded = encrypt_private_key (сообщение, общедоступное)
decrypt_public_key (закодированный, частный)
если __name __ == "__main__":
основной()
, но если вы теперь измените две последние строки [i.е. роль ключей] в:
encoded = encrypt_private_key (сообщение, личное)
decrypt_public_key (закодированный, общедоступный)
и перезапустите программу, вы получите TypeError: No private key
Позвольте мне процитировать этот отличный ответ:
«Как оказалось, PyCrypto только пытается помешать вам принять одно за другое здесь, OpenSSL или Ruby OpenSSL позволяют, например, делать оба: public_encrypt / public_decrypt и private_encrypt / private_decrypt
[…]
Необходимо позаботиться о дополнительных вещах, чтобы результат можно было использовать на практике. Вот почему в PyCrypto есть специальный пакет подписи — он эффективно выполняет то, что вы описали, но также дополнительно заботится о вещах, о которых я упомянул »
Адаптировав эту ссылку, я пришел к следующему коду, который должен решить ваш вопрос:
# вспомогательный класс RSA для pycrypto
# Copyright (c) Деннис Ли
# Дата 21 марта 2017
# Описание:
# Вспомогательный класс Python для выполнения шифрования RSA, дешифрования,
# подписание, проверка подписей и генерация ключей
# Пакеты зависимостей:
# пикрипто
# Документация:
# https: // www.dlitz.net/software/pycrypto/api/2.6/
из Crypto.PublicKey импортировать RSA
из Crypto.Cipher импорт PKCS1_OAEP
из Crypto.Signature import PKCS1_v1_5
из Crypto.Hash импорт SHA512, SHA384, SHA256, SHA, MD5
из Crypto import Random
из base64 импортировать b64encode, b64decode
импорт RSA
hash = "SHA-256"
def newkeys (размер ключа):
random_generator = Random.new (). читать
ключ = RSA.generate (размер ключа, random_generator)
закрытый, открытый = ключ, ключ.publickey ()
вернуть публичный, частный
def importKey (externKey):
вернуть RSA.importKey (externKey)
def getpublickey (priv_key):
вернуть priv_key.publickey ()
def encrypt (сообщение, pub_key):
Протокол шифрования #RSA согласно PKCS # 1 OAEP
cipher = PKCS1_OAEP.new (pub_key)
вернуть cipher.encrypt (сообщение)
def decrypt (зашифрованный текст, priv_key):
Протокол шифрования #RSA согласно PKCS # 1 OAEP
cipher = PKCS1_OAEP.new (Priv_key)
вернуть cipher.decrypt (зашифрованный текст)
def знак (сообщение, priv_key, hashAlg = "SHA-256"):
глобальный хеш
hash = hashAlg
подписывающий = PKCS1_v1_5.новый (priv_key)
если (hash == "SHA-512"):
дайджест = SHA512.new ()
elif (hash == "SHA-384"):
дайджест = SHA384.new ()
elif (hash == "SHA-256"):
дайджест = SHA256.new ()
elif (hash == "SHA-1"):
дайджест = SHA.new ()
еще:
дайджест = MD5.new ()
digest.update (сообщение)
вернуть signer.sign (дайджест)
def verify (сообщение, подпись, pub_key):
подписчик = PKCS1_v1_5.new (pub_key)
если (hash == "SHA-512"):
дайджест = SHA512.new ()
elif (hash == "SHA-384"):
дайджест = SHA384.новый()
elif (hash == "SHA-256"):
дайджест = SHA256.new ()
elif (hash == "SHA-1"):
дайджест = SHA.new ()
еще:
дайджест = MD5.new ()
digest.update (сообщение)
вернуть signer.verify (дайджест, подпись)
def main ():
msg1 = b "Привет, Тони, я Джарвис!"
msg2 = b "Привет, Тони, я Джарвис!"
keysize = 2048
(общедоступный, частный) = rsa.newkeys (размер ключа)
# https://docs.python.org/3/library/base64.html
# кодирует байтовый объект s
# возвращает байты
encrypted = b64encode (rsa.encrypt (msg1, частный))
# декодирует байтовый объект в кодировке Base64 или строку ASCII s
# возвращает декодированные байты
decrypted = rsa.decrypt (b64decode (зашифрованный), частный)
подпись = b64encode (rsa.sign (msg1, private, "SHA-512"))
verify = rsa.verify (msg1, b64decode (подпись), общедоступный)
#print (private.exportKey ('PEM'))
#print (public.exportKey ('PEM'))
print ("Зашифровано:" + encrypted.decode ('ascii'))
print ("Расшифровано: '% s'"% (расшифровано))
print ("Подпись:" + подпись.декодировать ('ascii'))
print ("Verify:% s"% verify)
rsa.verify (msg2, b64decode (подпись), общедоступный)
если __name __ == "__main__":
основной()
Заключительные ноты:
- последняя печать
ascii
, потому что, как указано здесь, «в случае base64, однако, все символы являются действительными символами ASCII» - в этом случае мы используем один и тот же ключ — частный — как для шифрования, так и для дешифрования, так что да: в конечном итоге мы будем симметричными, но ….
- , но — как указано здесь — «Открытый ключ — ПУБЛИЧНЫЙ — это то, чем вы с готовностью поделитесь и, следовательно, легко распространите. В этом случае нет никакой дополнительной ценности по сравнению с использованием симметричного шифра и общего ключа» плюс «концептуально» шифрование с помощью закрытого ключа более полезно для подписания сообщения, тогда как «дешифрование» с использованием открытого ключа используется для проверки сообщения «
- тот же самый последний принцип выражен в этом ответе — «Обычно […] мы говорим «подписать с помощью закрытого ключа и проверить с помощью открытого ключа»
RSA — Криптография 35.0.0.dev1 документация
Опасность
Это модуль «Опасные материалы». Вам следует использовать ТОЛЬКО , если вы
На 100% абсолютно уверены, что вы знаете, что делаете, потому что этот модуль
полный фугасов, драконов и динозавров с лазерными пушками.
RSA — это алгоритм с открытым ключом для шифрования и подписи сообщений.
Поколение
В отличие от симметричной криптографии, где ключ обычно представляет собой случайную серию
байтов ключи RSA имеют сложную внутреннюю структуру со специфическими
математические свойства.
-
cryptography.hazmat.primitives.asymmetric.rsa.
generate_private_key
( public_exponent , key_size , backend = None ) Изменено в версии 3.0: Ужесточены ограничения на
public_exponent
.Создает новый закрытый ключ RSA, используя предоставленный сервер
размер_ключа
описывает длину ключа в битах. Больше
ключи обеспечивают большую безопасность; в настоящее время рассматриваются1024
и ниже
ломкие, тогда как2048
или4096
являются разумными размерами ключей по умолчанию для
новые ключи.public_exponent
указывает, какое математическое свойство
ключевого поколения будет. Если у вас нет особой причины сделать
в противном случае вы всегда должны использовать 65537.>>> из cryptography.hazmat.primitives.asymmetric import rsa >>> private_key = rsa.generate_private_key ( ... public_exponent = 65537, ... key_size = 2048, ...)
Параметры: - public_exponent ( int ) — открытый показатель степени нового ключа.Либо 65537, либо 3 (для устаревших целей). Почти каждый должен
используйте 65537. - key_size ( int ) — длина модуля в битах. Для ключей
сгенерировано в 2015 году, настоятельно рекомендуется
не менее 2048 (см. стр. 41). Оно не должно быть меньше 512.
Некоторые серверные ВМ могут иметь дополнительные ограничения. - backend — дополнительный backend, который реализует
RSABackend
.
Возвращает: Экземпляр
RSAPrivateKey
.Повышает: cryptography.exceptions.UnsupportedAlgorithm — возникает, если
предоставленный бэкэнд
RSABackend
- public_exponent ( int ) — открытый показатель степени нового ключа.Либо 65537, либо 3 (для устаревших целей). Почти каждый должен
Загрузка ключа
Если у вас уже есть дисковый ключ в формате PEM (который распознается
отличительный ----- НАЧАЛО {формат} -----
и ----- КОНЕЦ {формат} -----
маркеры), можете загрузить:
>>> из криптографии.hazmat.primitives импортная сериализация >>> с open ("путь / к / key.pem", "rb") в качестве ключевого_файла: ... private_key = serialization.load_pem_private_key ( ... key_file.read (), ... пароль = Нет, ...)
Сериализованные ключи могут быть дополнительно зашифрованы на диске с помощью пароля. В этом
Например, мы загрузили незашифрованный ключ и поэтому не предоставили
пароль. Если ключ зашифрован, мы можем передать объект байтов в качестве
пароль
аргумент.
Также имеется поддержка для загрузки открытых ключей в формате SSH
.
Сериализация ключа
Если у вас есть закрытый ключ, который вы загрузили, вы можете использовать
private_bytes ()
для сериализации ключа.
>>> из cryptography.hazmat.primitives импортировать сериализацию >>> pem = private_key.private_bytes ( ... кодировка = сериализация.Encoding.PEM, ... format = serialization.PrivateFormat.PKCS8, ... encryption_algorithm = сериализация.BestAvailableEncryption (b'mypassword) ...) >>> pem.splitlines () [0] b '----- НАЧАТЬ ЗАПИСАННЫЙ ЧАСТНЫЙ КЛЮЧ -----'
Также возможно сериализовать без шифрования, используя
Нет шифрования
.
>>> pem = private_key.private_bytes ( ... кодировка = сериализация.Encoding.PEM, ... format = serialization.PrivateFormat.TraditionalOpenSSL, ... encryption_algorithm = сериализация.NoEncryption () ...) >>> pem.splitlines () [0] b '----- НАЧАТЬ ЧАСТНЫЙ КЛЮЧ RSA -----'
Для открытых ключей можно использовать
public_bytes ()
для сериализации ключа.
>>> из cryptography.hazmat.primitives импортировать сериализацию >>> public_key = private_key.public_key () >>> pem = public_key.public_bytes ( ... кодировка = сериализация.Encoding.PEM, ... формат = сериализация.PublicFormat.SubjectPublicKeyInfo ...) >>> pem.splitlines () [0] b '----- НАЧАТЬ ОБЩЕСТВЕННЫЙ КЛЮЧ -----'
Подпись
Для подписи сообщения можно использовать закрытый ключ. Это позволяет любому, кто имеет
ключ, чтобы убедиться, что сообщение было создано кем-то, кто обладает
соответствующий закрытый ключ.Для подписей RSA требуется определенная хеш-функция, и
заполнение, которое будет использоваться. Вот пример подписания сообщения
с использованием RSA с помощью
безопасная хеш-функция и заполнение:
>>> из cryptography.hazmat.primitives импортировать хеши >>> из cryptography.hazmat.primitives.asymmetric import padding >>> message = b "Сообщение, которое я хочу подписать" >>> подпись = private_key.sign ( ... сообщение, ... padding.PSS ( ... mgf = padding.MGF1 (хеши.SHA256 ()), ... salt_length = padding.PSS.MAX_LENGTH ...), ... хеши.SHA256 () ...)
Допустимые отступы для подписей:
PSS
и
Иркутск
. PSS
- рекомендуемый выбор для любых новых протоколов или приложений, PKCS1v15
следует использовать только для поддержки устаревших протоколов.
Если ваши данные слишком велики для передачи за один вызов, вы можете их хэшировать.
отдельно и передайте это значение, используя
Предварительно хешировано
.
>>> из криптографии.hazmat.primitives.symmetric import utils >>> selected_hash = хеши.SHA256 () >>> hasher = hashes.Hash (selected_hash). >>> hasher.update (b "данные &") >>> hasher.update (b "больше данных") >>> дайджест = hasher.finalize () >>> sig = private_key.sign ( ... переваривать, ... padding.PSS ( ... mgf = padding.MGF1 (хеши.SHA256 ()), ... длина_ соли = обивка.PSS.MAX_LENGTH ...), ... utils.Prehashed (selected_hash) ...)
Проверка
В предыдущем разделе описано, что делать, если у вас есть закрытый ключ и вы хотите
подписать что-нибудь.Если у вас есть открытый ключ, сообщение, подпись и
алгоритм подписи, который был использован, вы можете проверить, что закрытый ключ связан
с данным открытым ключом был использован для подписи этого конкретного сообщения. Вы можете получить
открытый ключ для использования при проверке с использованием
load_pem_public_key ()
,
load_der_public_key ()
,
public_key ()
, или же
public_key ()
.
>>> public_key = private_key.public_key () >>> public_key.verify ( ... подпись, ... сообщение, ... padding.PSS ( ... mgf = padding.MGF1 (хеши.SHA256 ()), ... длина_ соли = обивка.PSS.MAX_LENGTH ...), ... хеши.SHA256 () ...)
Если подпись не совпадает, verify ()
вызовет
InvalidSignature
исключение.
Если ваши данные слишком велики для передачи за один вызов, вы можете их хэшировать.
отдельно и передайте это значение, используя
Предварительно хешировано
.
>>> selected_hash = хеши.SHA256 () >>> hasher = хеши.Хеш (selected_hash) >>> hasher.update (b "данные &") >>> hasher.update (b "больше данных") >>> дайджест = hasher.finalize () >>> public_key.verify ( ... сиг, ... переваривать, ... padding.PSS ( ... mgf = padding.MGF1 (хеши.SHA256 ()), ... длина_ соли = обивка.PSS.MAX_LENGTH ...), ... utils.Prehashed (selected_hash) ...)
Шифрование
RSA шифрование интересно тем, что шифрование выполняется с использованием
открытый ключ , то есть любой может зашифровать данные.Затем данные расшифровываются.
используя закрытый ключ .
Как и подписи, RSA поддерживает шифрование с несколькими различными дополнениями.
параметры. Вот пример использования безопасного заполнения и хеш-функции:
>>> message = b "зашифрованные данные" >>> ciphertext = public_key.encrypt ( ... сообщение, ... padding.OAEP ( ... mgf = padding.MGF1 (алгоритм = hashes.SHA256 ()), ... алгоритм = хэши.SHA256 (), ... label = Нет ...) ...)
Допустимые поля для шифрования:
OAEP
и
Иркутск
. OAEP
- рекомендуемый выбор для любых новых протоколов или приложений, PKCS1v15
следует использовать только для поддержки устаревших протоколов.
Расшифровка
Если у вас есть зашифрованное сообщение, его можно расшифровать с помощью закрытого ключа:
>>> plaintext = private_key.decrypt ( ... зашифрованный текст, ... padding.OAEP ( ... mgf = padding.MGF1 (алгоритм = hashes.SHA256 ()), ... алгоритм = хэши.SHA256 (), ... label = Нет ...) ...) >>> plaintext == сообщение Правда
Прокладка
- class
cryptography.hazmat.primitives.asymmetric.padding.
Асимметричная набивка
-
название
-
- class
cryptography.hazmat.primitives.asymmetric.padding.
PSS
( MGF , длина_ соли ) Изменено в версии 0.4: Добавлен параметр
salt_length
.PSS (Схема вероятностной подписи) - это схема подписи, определенная в
RFC 3447 . Он сложнее PKCS1, но обладает доказательством безопасности.
Это рекомендуемый алгоритм заполнения для подписей RSA. Оно не может
использоваться с шифрованием RSA.Параметры: - mgf - Объект функции создания маски. На этот раз единственный
поддерживаемый MGF -MGF1
. - salt_length ( int ) - длина соли. Рекомендуется, чтобы это
установить значениеPSS.MAX_LENGTH
.
-
МАКС.ДЛИНА
Передайте этот атрибут в
salt_length
, чтобы получить максимальную длину соли
имеется в наличии.
- mgf - Объект функции создания маски. На этот раз единственный
- class
cryptography.hazmat.primitives.asymmetric.padding.
OAEP
( MGF , алгоритм , метка ) OAEP (Optimal Asymmetric Encryption Padding) - это схема заполнения, определенная в
RFC 3447 .Он обеспечивает вероятностное шифрование и доказал свою безопасность.
против нескольких типов атак. Это рекомендуемый алгоритм заполнения
для шифрования RSA. Его нельзя использовать с подписью RSA.Параметры: - mgf - Объект функции создания маски. На этот раз единственный
поддерживаемый MGF -MGF1
. - алгоритм - Экземпляр
Хэш-алгоритм
. - метка ( байта ) - метка, которую нужно применить.Это редко используемое поле и
обычно должно быть установлено значениеНет
илиb ""
, что эквивалентно.
- mgf - Объект функции создания маски. На этот раз единственный
- class
cryptography.hazmat.primitives.asymmetric.padding.
PKCS1v15
PKCS1 v1.5 (также известный как просто PKCS1) - это простая схема заполнения
разработан для использования с ключами RSA. Он определен в RFC 3447 . Эта прокладка
может использоваться для подписи и шифрования.Не рекомендуется использовать
PKCS1v15
для новых приложений,
OAEP
следует использовать для шифрования, аPSS
-
предпочтительнее для подписей.
-
cryptography.hazmat.primitives.asymmetric.padding.
calculate_max_pss_salt_length
( ключ , hash_algorithm ) Вычисляет длину соли, которую
PSS
будет использовать, если
PSS.MAX_LENGTH
используется.
Функции создания масок
- class
cryptography.hazmat.primitives.asymmetric.padding.
MGF1
(алгоритм , ) Изменено в версии 0.6: Удален устаревший параметр
salt_length
.MGF1 (функция генерации маски 1) используется в качестве функции генерации маски
в набивкеPSS
иOAEP
. Требуется хеш-алгоритм.
Номера
Эти классы содержат составляющие компоненты ключа RSA. Они полезны
только при более традиционной сериализации ключей
недоступен.
- класс
cryptography.hazmat.primitives.asymmetric.rsa.
РСАП PublicNumbers
( e , n ) Набор целых чисел, составляющих открытый ключ RSA.
-
n
Общественный модуль.
-
e
Общественный экспонент.
-
public_key
( backend = Нет )
-
- класс
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPrivateNumbers
( p , q , d , dmp1 , dmq1 , iqmp , public_numbers ) Набор целых чисел, составляющих закрытый ключ RSA.
Предупреждение
За исключением целых чисел, содержащихся в
RSAPublicNumbers
все атрибуты этого класса должны быть сохранены
секрет. Их обнаружение поставит под угрозу безопасность любого
криптографические операции, выполняемые с загруженным из них ключом.-
public_numbers
RSAPublicNumbers
, составляющий открытый ключ RSA.
связанный с этим закрытым ключом RSA.
-
п.
p
, одно из двух простых чисел, составляющихn
.
-
кв
q
, одно из двух простых чисел, составляющихn
.
-
д
Частный показатель.
-
dmp1
Коэффициент китайской теоремы об остатках, используемый для ускорения RSA
операции. Вычисляется как: d mod (p-1)
-
дмк1
Коэффициент китайской теоремы об остатках, используемый для ускорения RSA
операции.Вычисляется как: d mod (q-1)
-
iqmp
Коэффициент китайской теоремы об остатках, используемый для ускорения RSA
операции. Вычисляется как: q -1 mod p
-
private_key
( backend = нет )
-
Обработка частичных закрытых ключей RSA
Если вы пытаетесь загрузить закрытые ключи RSA самостоятельно, вы можете обнаружить, что не все
Доступны параметры, необходимые для RSAPrivateNumbers
.В частности
Значения китайской теоремы об остатках (CRT) dmp1
, dmq1
, iqmp
могут быть
отсутствует или присутствует в другой форме. Например, OpenPGP не включает
параметры iqmp
, dmp1
или dmq1
.
Для пользователей, которые хотят работать с такими клавишами, как
это без необходимости делать математику самостоятельно.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_crt_iqmp
( p , q ) Вычисляет параметр
iqmp
(также известный какqInv
) из RSA.
простые числаp
иq
.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_crt_dmp1
( private_exponent , p ) Вычисляет параметр
dmp1
из частного показателя RSA (d
) и
премьерр
.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_crt_dmq1
( private_exponent , q ) Вычисляет параметр
dmq1
из частного показателя RSA (d
) и
премьерq
.
-
cryptography.hazmat.primitives.asymmetric.rsa.
rsa_recover_prime_factors
( n , e , d ) Вычисляет простые множители
(p, q)
по модулю, общедоступной экспоненте,
и частный экспонент.Примечание
При восстановлении простых множителей этот алгоритм всегда будет возвращать
p
иq
, так чтоp> q
. Примечание: до 1.5 эта функция всегда
вернулp
иq
, так чтоp
.Это было изменено, потому что
библиотеки обычно требуютp> q
.
Ключевые интерфейсы
- класс
cryptography.hazmat.primitives.asymmetric.rsa.
RSAPrivateKey
Закрытый ключ RSA.
-
расшифровать
( зашифрованный текст , заполнение ) Расшифровать данные, зашифрованные открытым ключом.
Параметры: Возврат байтов: Расшифрованные данные.
-
public_key
() Объект открытого ключа RSA, соответствующий значениям закрытого ключа.
-
размер ключа
Битовая длина модуля.
-
знак
( данные , заполнение , алгоритм ) Изменено в версии 1.6:
Предварительно хешировано
теперь можно использовать как алгоритмПодпишите один блок данных, который впоследствии могут быть проверены другими с помощью
открытый ключ.Параметры: Байт возврата: Подпись.
-
частные_номера
() Создать
RSA Частные номера
объект.
-
private_bytes
( кодировка , формат , encryption_algorithm ) Разрешает сериализацию ключа в байты.Кодировка (
PEM
или
DER
),
формат (
Традиционный OpenSSL
,
OpenSSH
или же
PKCS8
)
и алгоритм шифрования (например,
BestAvailableEncryption
илиNoEncryption
)
выбраны для определения точной сериализации.Параметры: Возврат байтов: Серийный ключ.
-
- класс
криптография.hazmat.primitives.asymmetric.rsa.
RSAPrivateKeyWithSerialization
Псевдоним для
RSAPrivateKey
.
- класс
cryptography.hazmat.primitives.asymmetric.rsa.
RSAP PublicKey
Открытый ключ RSA.
-
зашифровать
( открытый текст , заполнение ) Зашифровать данные открытым ключом.
Параметры: Байт возврата: Зашифрованные данные.
Повышает: ValueError - данные не могут быть зашифрованы. Одна возможная причина
еслиданные
слишком велики; Ключи RSA могут шифровать только те данные, которые
меньше размера ключа.
-
размер ключа
Битовая длина модуля.
-
public_numbers
() Создать
РГАУ публичные номера
объект.
-
public_bytes
( кодировка , формат ) Разрешает сериализацию ключа в байты. Кодировка (
PEM
или
DER
) и
формат (
SubjectPublicKeyInfo
или же
PKCS1
)
выбраны для определения точной сериализации.Параметры: Возврат байтов: Серийный ключ.
-
проверить
( подпись , данные , заполнение , алгоритм ) Изменено в версии 1.6:
Предварительное хеширование
теперь можно использовать как алгоритмПроверить, что один блок данных был подписан закрытым ключом
связанный с этим открытым ключом.
-
restore_data_from_signature
( подпись , заполнение , алгоритм ) Восстанавливает подписанные данные из подписи. Данные обычно содержат
дайджест исходной строки сообщения. Набивка
алгоритм
параметры должны совпадать с теми, которые использовались при подписи
был создан для успешного восстановления.Алгоритм
Параметр
также может быть установлен наНет
для восстановления всех
данные, представленные в подписи, независимо от ее формата или
алгоритм хеширования, использованный для его создания.Для
PKCS1v15
padding, этот метод возвращает данные после удаления слоя заполнения.
Для стандартных подписей данные содержат полныйDigestInfo
состав. Для нестандартных подписей могут быть возвращены любые данные,
включая данные нулевой длины.Обычно вы должны использовать
проверить ()
функция для проверки подписи.Но за какую-то нестандартную подпись
форматы, которые могут потребоваться для явного восстановления и проверки подписанного
данные. Ниже приведены некоторые примеры:- Некоторые старые сертификаты отметок времени Thawte и Verisign без
DigestInfo
. - Подписанные хэши MD5 / SHA1 в TLS 1.1 или более ранней версии ( RFC 4346 , раздел 4.7).
- подписи IKE версии 1 без
DigestInfo
( RFC 2409 , раздел 5.1).
- Некоторые старые сертификаты отметок времени Thawte и Verisign без
-
- класс
криптография.hazmat.primitives.asymmetric.rsa.
RSAPublicKeyWithSerialization
Псевдоним для
RSAPublicKey
.
RSA шифрования / дешифрования - Примеры
Открытый ключ: (п = 0x9a11485bccb9569410a848fb1afdf2a81b17c1fa9f9eb546fd1deb873b49b693a4edf20eb8362c085cd5b28ba109dbad2bd257a013f57f745402e245b0cc2d553c7b2b8dbba57ebda7f84cfb32b7d9c254f03dbd0188e4b8e40c47b64c1bd2572834b936ffc3da9953657ef8bee80c49c2c12933c8a34804a00eb4c81248e01f, е = 0x10001)
----- BEGIN PUBLIC KEY -----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaEUhbzLlWlBCoSPsa / fKoGxfB
+ P + etUb9HeuHO0m2k6Tt8g64NiwIXNWyi6EJ260r0legE / В / dFQC4kWwzC1VPHsr
jbulfr2n + Ez7MrfZwlTwPb0BiOS45AxHtkwb0lcoNLk2 / 8PamVNlfvi + 6AxJwsEp
M8ijSASgDrTIEkjgHwIDAQAB ----- КОНЕЦ ОТКРЫТОГО кЛЮЧА -----
Закрытый ключ: (п = 0x9a11485bccb9569410a848fb1afdf2a81b17c1fa9f9eb546fd1deb873b49b693a4edf20eb8362c085cd5b28ba109dbad2bd257a013f57f745402e245b0cc2d553c7b2b8dbba57ebda7f84cfb32b7d9c254f03dbd0188e4b8e40c47b64c1bd2572834b936ffc3da9953657ef8bee80c49c2c12933c8a34804a00eb4c81248e01f, d = 0x318ab12be3cf0d4a1b7 921cead454fcc42ba070462639483394d6fb9529547827e9c8d23b294a8e01f8a1019da34e350f2307740e06a270bef1fe646e6ad213e31b528fdd5f5d03e633c07c44755ed622a629d79e822c095ebdf9cc80e517b5566dd3d3e5b16ec737987337a0e497fdba4b5ad97af41c1c3cdd87542a4637d81)
----- BEGIN RSA PRIVATE KEY -----
MIICXAIBAAKBgQCaEUhbzLlWlBCoSPsa / fKoGxfB + р + etUb9HeuHO0m2k6Tt8g64
NiwIXNWyi6EJ260r0legE / В / dFQC4kWwzC1VPHsrjbulfr2n + Ez7MrfZwlTwPb0B
iOS45AxHtkwb0lcoNLk2 / 8PamVNlfvi + 6AxJwsEpM8ijSASgDrTIEkjgHwIDAQAB
AoGAMYqxK + PPDUobeSHOrUVPzEK6BwRiY5SDOU1vuVKVR4J + nI0jspSo4B + KEBna
NONQ8jB3QOBqJwvvH + ZG5q0hPjG1KP3V9dA + YzwHxEdV7WIqYp156CLAlevfnMgO
UXtVZt09PlsW7HN5hzN6Dkl / 26S1rZevQcHDzdh2QqRjfYECQQDGDUIQXlOiAcGo
d5YqAGpWe0wzJ0UypeqZcqS9MVe9OkjjopCkkYntifdN / 1oG7S / 1KUMtLoGHqntb
c428zOO / AkEAxyV0cmuJbFdfM0x2XhZ + GE / 7putIx76RHDOjBpM6VQXpLEFj54kB
qGLAB7SXr7P4AFrEjfckJOp2YMI5BreboQJAb3EUZHt / WeDdJLutzpKPQ3x7oykM
ш fQkbxXYZvD16u96BkT6WO / gCb6hXs05zj32x1 / hgfHyRvGCGjKKZdtwpwJBAJ74
y0g7h + wwoxJ0S1k4Y6yeQikxUVwCSBxXLCCnjr0ohsaJPJMrz2L30YtVInFkHOlL
я / Q4AWZmtDDxWkx + bYECQG8e6bGoszuX5xjvhEBslIws9 + nMzMuYBR8HvhLo58B5
N8dk3nIsLs3UncKLiiWubMAciU5jUxZoqWpRXXwECKE =
----- END RSA PRIVATE KEY -----
Encrypted: b'99b331c4e1c8f3fa227aacd57c85f38b7b7461574701b427758ee4f94b1e07d791ab70b55d672ff55dbe133ac0bea16fc23ea84636365f605a9b645e0861ee11d68a7550be8eb35e85a4bde6d73b0b956d000866425511c7920cdc8a3786a4f1cb1986a875373975e158d74e11ad751594de593a35de765fe329c0d3dfbbfedc»
Расшифрованный : b'A сообщение для шифрования '
RSA - PyCryptodome 3.9.9 документация
RSA - наиболее распространенный и используемый алгоритм с открытым ключом. Его безопасность
основанный на сложности факторизации больших целых чисел. Алгоритм имеет
выдерживал атаки более 30 лет, поэтому считается
достаточно безопасно для новых разработок.
Алгоритм может использоваться как для обеспечения конфиденциальности (шифрование), так и для
аутентификация (цифровая подпись). Стоит отметить, что подписание и
расшифровка значительно медленнее, чем проверка и шифрование.
Криптографическая стойкость в первую очередь связана с длиной модуля RSA n .
В 2017 году считается, что достаточной длиной будет 2048 бит. Для дополнительной информации,
см. последний отчет ECRYPT.
Размер как зашифрованных текстов RSA, так и подписей RSA равен модулю RSA n (256
байтов, если n имеет длину 2048 бит).
Модуль Crypto.PublicKey.RSA
предоставляет средства для генерации новых ключей RSA,
реконструировать их из известных компонентов, экспортировать и импортировать.
В качестве примера, вот как вы генерируете новую пару ключей RSA, сохраняете ее в файле
позвонил mykey.pem
, а затем прочел его:
>>> из Crypto.PublicKey импорт RSA >>> >>> ключ = RSA.generate (2048) >>> f = open ('mykey.pem', 'wb') >>> f.write (key.export_key ('PEM')) >>> f.close () ... >>> f = open ('mykey.pem', 'r') >>> key = RSA.import_key (f.read ())
-
Crypto.PublicKey.RSA.
сгенерировать
( бит , randfunc = Нет , e = 65537 ) Создайте новую пару ключей RSA.
Алгоритм близко следует NIST FIPS 186-4 в его
разделы B.3.1 и B.3.3. Модуль - это произведение
два несильных вероятных простых числа.
Каждое простое число проходит соответствующее количество тестов Миллера-Рабина.
со случайными основаниями и одним тестом Лукаса.Параметры: - бит ( целое число ) - длина ключа или размер (в битах) модуля RSA.Он должен быть не менее 1024, но рекомендуется 2048.
Стандарт FIPS определяет только 1024, 2048 и 3072. - randfunc ( вызываемый ) - функция, которая возвращает случайные байты.
По умолчанию -Crypto.Random.get_random_bytes ()
. - e ( целое число ) - публичная экспонента RSA. Это должно быть нечетное положительное целое число.
Обычно это небольшое число с очень немногими
двоичное представление.
Стандарт FIPS требует, чтобы публичная экспонента была
не менее 65537 (по умолчанию).
Возвращает: объект ключа RSA (
RsaKey
, с закрытым ключом).- бит ( целое число ) - длина ключа или размер (в битах) модуля RSA.Он должен быть не менее 1024, но рекомендуется 2048.
-
Крипто.Публичный ключ.RSA.
конструкция
( rsa_components , consistency_check = True ) Создайте ключ RSA из кортежа допустимых компонентов RSA.
Модуль n должен быть произведением двух простых чисел.
Открытый показатель степени e должен быть нечетным и превышать 1.В случае закрытого ключа должны применяться следующие уравнения:
\ [\ begin {split} \ begin {align}
р * д & = п \\
e * d & \ Equiv 1 (\ text {mod lcm} [(p-1) (q-1)]) \\
п * и & \ эквив 1 (\ текст {мод} д)
\ end {align} \ end {split} \]Параметры: Вызывает: ValueError
- когда импортируемый ключ не проходит самые основные проверки действительности RSA.Возвращает: ключевой объект RSA (
RsaKey
).
-
Крипто.Публичный ключ.RSA.
import_key
( extern_key , пароль = Нет ) Импортируйте ключ RSA (открытый или закрытый).
Параметры: - extern_key ( строка или байтовая строка ) -
Ключ RSA для импорта.
Для открытого ключа RSA поддерживаются следующие форматы :
- Х.509 (двоичный формат или формат PEM)
- X.509
subjectPublicKeyInfo
DER SEQUENCE (двоичный или PEM
кодировка) - PKCS # 1
RSAPublicKey
DER SEQUENCE (двоичное или PEM-кодирование) - Строка OpenSSH (например, содержимое
~ / .ssh / id_ecdsa
, ASCII)
Для закрытого ключа RSA поддерживаются следующие форматы :
- PKCS # 1
RSAPrivateKey
DER SEQUENCE (двоичное кодирование или кодирование PEM) - PKCS # 8
PrivateKeyInfo
илиEncryptedPrivateKeyInfo
DER SEQUENCE (двоичное кодирование или кодирование PEM) - OpenSSH (текстовый формат, представленный в OpenSSH 6.5)
Подробнее о кодировке PEM см. RFC1421 / RFC1423.
- парольная фраза ( строка или байтовая строка ) - только для закрытых ключей, парольная фраза, которая шифрует ключ.
Возвращает: ключевой объект RSA (
RsaKey
).Вызывает: ValueError / IndexError / TypeError
- Когда данный ключ не может быть проанализирован (возможно, из-за передачи
фраза неверна).- extern_key ( строка или байтовая строка ) -
- класс
Crypto.PublicKey.RSA.
RsaKey
( ** kwargs ) Класс, определяющий фактический ключ RSA.
Не создавайте экземпляры напрямую.
Вместо этого используйтеgenerate ()
,construct ()
илиimport_key ()
.Переменные: - n ( целое число ) - модуль RSA
- e ( целое число ) - публичная экспонента RSA
- d ( целое число ) - частный показатель RSA
- p ( integer ) - Первый фактор модуля RSA
- q ( целое число ) - Второй коэффициент модуля RSA
- u - китайский остаток (\ (p ^ {- 1} \ text {mod} q \))
-
exportKey
(формат = 'PEM' , пароль = нет , pkcs = 1 , защита = нет , randfunc = нет ) Экспортируйте этот ключ RSA.
Параметры: - формат ( строка ) -
Формат, используемый для упаковки ключа:
- ’PEM’ . ( По умолчанию ) Кодировка текста в соответствии с RFC1421 / RFC1423.
- ’DER’ . Двоичное кодирование.
- ’OpenSSH’ . Текстовое кодирование, выполненное в соответствии со спецификацией OpenSSH.
Подходит только для открытых ключей (не для закрытых ключей).
- парольная фраза ( строка ) - ( Только для закрытых ключей ) Парольная фраза, используемая для защиты вывода.
- pkcs ( целое число ) -
( Только для закрытых ключей ) Структура ASN.1, используемая для
сериализация ключа. Обратите внимание, что даже в случае PEM
кодирования, существует внутренняя структура DER ASN.1.Если
pkcs = 1
( по умолчанию ), закрытый ключ закодирован в
простая структура PKCS # 1 (RSAPrivateKey
).При
pkcs = 8
закрытый ключ закодирован в структуре PKCS # 8
(PrivateKeyInfo
).Примечание
Этот параметр игнорируется для открытого ключа.
Для DER и PEM - ASN.1 DERSubjectPublicKeyInfo
структура всегда используется. - защита ( строка ) -
( Только для закрытых ключей )
Схема шифрования, используемая для защиты закрытого ключа.Если
Нет
(по умолчанию), поведение зависит от формата- Для ‘DER’ , PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC
схема используется.Выполняются следующие операции:- 16-байтовый тройной ключ DES получен из парольной фразы
используяCrypto.Protocol.KDF.PBKDF2 ()
с 8-байтовой солью,
и 1000 итерацийCrypto.Hash.HMAC
. - Закрытый ключ зашифрован с использованием CBC.
- Зашифрованный ключ закодирован в соответствии с PKCS # 8.
- 16-байтовый тройной ключ DES получен из парольной фразы
- Для «PEM» используется устаревшая схема шифрования PEM.
Он основан на MD5 для получения ключей и Triple DES для шифрования.
Указание значения для защиты
(то естьpkcs = 8
) и только если присутствует парольная фраза.Поддерживаемые схемы для PKCS # 8 перечислены в
Модуль Crypto.IO.PKCS8
(см. Параметрwrap_algo
). - Для ‘DER’ , PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC
- randfunc ( вызываемый ) - функция, которая предоставляет случайные байты. Используется только для кодирования PEM.
По умолчанию -Crypto.Random.get_random_bytes ()
.
Возвращает: закодированный ключ
Тип возврата: байтовая строка
Повышает: ValueError
- когда формат неизвестен или когда вы пытаетесь зашифровать частный
ключ с форматом DER и PKCS # 1.Предупреждение
Если вы не укажете парольную фразу, закрытый ключ будет
экспортируется в чистом виде!- формат ( строка ) -
-
export_key
(формат = 'PEM' , пароль = нет , pkcs = 1 , защита = нет , randfunc = нет ) Экспортируйте этот ключ RSA.
Параметры: - формат ( строка ) -
Формат, используемый для упаковки ключа:
- ’PEM’ . ( По умолчанию ) Кодировка текста в соответствии с RFC1421 / RFC1423.
- ’DER’ . Двоичное кодирование.
- ’OpenSSH’ . Текстовое кодирование, выполненное в соответствии со спецификацией OpenSSH.
Подходит только для открытых ключей (не для закрытых ключей).
- парольная фраза ( строка ) - ( Только для закрытых ключей ) Парольная фраза, используемая для защиты вывода.
- pkcs ( целое число ) -
( Только для закрытых ключей ) Структура ASN.1, используемая для
сериализация ключа. Обратите внимание, что даже в случае PEM
кодирования, существует внутренняя структура DER ASN.1.Если
pkcs = 1
( по умолчанию ), закрытый ключ закодирован в
простая структура PKCS # 1 (RSAPrivateKey
).При
pkcs = 8
закрытый ключ закодирован в структуре PKCS # 8
(PrivateKeyInfo
).Примечание
Этот параметр игнорируется для открытого ключа.
Для DER и PEM - ASN.1 DERSubjectPublicKeyInfo
структура всегда используется. - защита ( строка ) -
( Только для закрытых ключей )
Схема шифрования, используемая для защиты закрытого ключа.Если
Нет
(по умолчанию), поведение зависит от формата- Для ‘DER’ , PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC
схема используется.Выполняются следующие операции:- 16-байтовый тройной ключ DES получен из парольной фразы
используяCrypto.Protocol.KDF.PBKDF2 ()
с 8-байтовой солью,
и 1000 итерацийCrypto.Hash.HMAC
. - Закрытый ключ зашифрован с использованием CBC.
- Зашифрованный ключ закодирован в соответствии с PKCS # 8.
- 16-байтовый тройной ключ DES получен из парольной фразы
- Для «PEM» используется устаревшая схема шифрования PEM.
Он основан на MD5 для получения ключей и Triple DES для шифрования.
Указание значения для защиты
(то естьpkcs = 8
) и только если присутствует парольная фраза.Поддерживаемые схемы для PKCS # 8 перечислены в
Модуль Crypto.IO.PKCS8
(см. Параметрwrap_algo
). - Для ‘DER’ , PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC
- randfunc ( вызываемый ) - функция, которая предоставляет случайные байты. Используется только для кодирования PEM.
По умолчанию -Crypto.Random.get_random_bytes ()
.
Возвращает: закодированный ключ
Тип возврата: байтовая строка
Повышает: ValueError
- когда формат неизвестен или когда вы пытаетесь зашифровать частный
ключ с форматом DER и PKCS # 1.Предупреждение
Если вы не укажете парольную фразу, закрытый ключ будет
экспортируется в чистом виде!- формат ( строка ) -
-
has_private
() Является ли это закрытым ключом RSA
-
публичный ключ
() Соответствующий открытый ключ RSA.
-
size_in_bits
() Размер модуля RSA в битах
-
size_in_bytes
() Минимальное количество байтов, которое может содержать модуль RSA
-
Крипто.Публичный ключ.RSA.
oid
= '1.2.840.113549.1.1.1' Идентификатор объекта для алгоритма шифрования RSA. Этот OID часто указывает
общий ключ RSA, даже если такой ключ будет фактически использоваться для цифровых
подписи.
Программа Python для шифрования / дешифрования RSA
Приведенная ниже программа является реализацией известного алгоритма RSA. Чтобы написать эту программу, мне нужно было знать, как писать алгоритмы для Тотиента Эйлера, НОД, проверки простых чисел, обратного умножения, шифрования и дешифрования. От меня требовалось детально знать и понимать каждый шаг алгоритма. Я научился собирать вместе разные функции, преобразовывать их с математической точки зрения в точку зрения программиста и выдавать совершенно другой результат.Добавление кода из разных источников - очень полезная концепция в компьютерных науках, и она показывает, что я могу переработать существующие идеи и модели для создания новых. В основной программе 167 строк кода и 71 строка в тестовых выходных данных.
ГЛАВНАЯ ПРОГРАММА
'' ' ДОБРО ПОЖАЛОВАТЬ В RSA ENCRYPTOR. ЭТО ИНТЕРАКТИВНЫЙ ИНСТРУМЕНТ, ИСПОЛЬЗУЕМЫЙ ДЛЯ ШИФРОВАНИЯ ИЛИ РАСШИФРОВКИ СООБЩЕНИЯ С ИСПОЛЬЗОВАНИЕМ ИЗВЕСТНОГО АЛГОРИТМА RSA. ПРОГРАММИСТ: ANIRUDH GOTTIPARTHY '' ' импортная математика print ("RSA ENCRYPTOR / DECRYPTOR") Распечатать("*********************************************** ****** ") # Ввод простых чисел print ("ПОЖАЛУЙСТА, ВВЕДИТЕ ЗНАЧЕНИЯ 'p' И 'q' НИЖЕ:") p = int (input ("Введите простое число для p:")) q = int (input ("Введите простое число для q:")) Распечатать("*********************************************** ****** ") # Проверить, являются ли входные данные Prime '' ЭТА ФУНКЦИЯ И КОД НЕМЕДЛЕННО НИЖЕ ФУНКЦИИ ПРОВЕРЯЮТ ЛИ ВХОДЫ ПЕРВЫЕ ИЛИ НЕТ.'' ' def prime_check (a): если (a == 2): вернуть True elif ((a <2) или ((a% 2) == 0)): вернуть ложь элиф (а> 2): для i в диапазоне (2, a): если нет (a% i): вернуть ложь вернуть True check_p = prime_check (p) check_q = prime_check (q) while (((check_p == False) или (check_q == False))): p = int (input ("Введите простое число для p:")) q = int (input ("Введите простое число для q:")) check_p = prime_check (p) check_q = prime_check (q) #RSA Модуль '' 'РАСЧЕТ МОДУЛЯ RSA' n '.'' ' п = р * д print ("Модуль RSA (n) равен:", n) #Eulers Toitent '' 'РАСЧЕТ ЭЙЛЕРСА TOITENT' r '.' '' г = (р-1) * (д-1) print ("Eulers Toitent (r) is:", r) Распечатать("*********************************************** ****** ") #GCD '' 'РАСЧЕТ НОД ДЛЯ РАСЧЕТА' е '.' '' def egcd (e, r): в то время как (r! = 0): е, г = г, е% г вернуть е # Алгоритм Евклида def eugcd (e, r): для i в диапазоне (1, r): в то время как (e! = 0): a, b = r // e, r% e если (b! = 0): print ("% d =% d * (% d) +% d"% (r, a, e, b)) г = е е = б # Расширенный алгоритм Евклида def eea (a, b): если (a% b == 0): return (b, 0,1) еще: gcd, s, t = eea (b, a% b) s = s - ((a // b) * t) print ("% d =% d * (% d) + (% d) * (% d)"% (gcd, a, t, s, b)) возврат (gcd, t, s) #Multiplicative Inverse def mult_inv (e, r): gcd, s, _ = eea (e, r) если (НОД! = 1): return None еще: если (s <0): print ("s =% d.Поскольку% d меньше 0, s = s (modr), т.е. s =% d. "% (S, s, s% r)) elif (s> 0): print ("s =% d."% (s)) вернуть s% r #e Расчет стоимости '' 'НАХОДИТ НАИБОЛЬШЕ ВОЗМОЖНОЕ ЗНАЧЕНИЕ' e 'МЕЖДУ 1 и 1000, ЧТО ДЕЛАЕТ (e, r) COPRIME.' '' для i в диапазоне (1,1000): если (egcd (i, r) == 1): е = я print ("Значение e:", e) Распечатать("*********************************************** ****** ") #d, частный и открытый ключи '' 'РАСЧЕТ' d ', ЧАСТНОГО КЛЮЧА И ОБЩЕСТВЕННОГО КЛЮЧА.'' ' print ("АЛГОРИТМ ЕВКЛИДА:") eugcd (e, r) print («КОНЕЦ ШАГОВ ДЛЯ ДОСТИЖЕНИЯ АЛГОРИТМА ЕВКЛИДА.») Распечатать("*********************************************** ****** ") print ("РАСШИРЕННЫЙ АЛГОРИТМ ЕВКЛИДА:") d = mult_inv (e, r) print («КОНЕЦ ШАГОВ, ИСПОЛЬЗУЕМЫХ ДЛЯ ДОСТИЖЕНИЯ ЗНАЧЕНИЯ 'd'.») print ("Значение d:", d) Распечатать("*********************************************** ****** ") общественность = (е, п) частный = (d, n) print ("Закрытый ключ:", закрытый) print ("Открытый ключ:", общедоступный) Распечатать("*********************************************** ****** ") # Шифрование '' 'АЛГОРИТМ ШИФРОВАНИЯ.'' ' def encrypt (pub_key, n_text): e, n = pub_key х = [] т = 0 для я в n_text: если (i.isupper ()): m = ord (i) -65 c = (m ** e)% n x.append (c) elif (i.islower ()): m = ord (i) -97 c = (m ** e)% n x.append (c) elif (i.isspace ()): spc = 400 x.append (400) вернуть х # Расшифровка '' 'АЛГОРИТМ РАСШИФРОВКИ' '' def decrypt (priv_key, c_text): d, n = priv_key txt = c_text.расколоть(',') х = '' т = 0 для я в txt: if (i == '400'): х + = '' еще: m = (int (i) ** d)% n м + = 65 c = chr (м) х + = с вернуть х #Сообщение message = input ("Что бы вы хотели зашифровать или расшифровать? (Для дешифрования номера разделяйте символами ','):") print ("Ваше сообщение:", сообщение) # Выберите "Зашифровать" или "Расшифровать и распечатать" choose = input ("Введите" 1 "для шифрования и" 2 "для дешифрования.") если (выберите == '1'): enc_msg = encrypt (общедоступный, сообщение) print ("Ваше зашифрованное сообщение:", enc_msg) print («Спасибо за использование RSA Encryptor. До свидания!») elif (выберите == '2'): print ("Ваше расшифрованное сообщение:", расшифровать (личное, сообщение)) print («Спасибо за использование RSA Encryptor. До свидания!») еще: print ("Вы ввели неправильный вариант.") print («Спасибо за использование RSA Encryptor. До свидания!»)
В начало
ТЕСТОВЫЙ ВЫХОД:
Python 3.6.5 (v3.6.5: f59c0932b4, 28 марта 2018 г., 16:07:46) [MSC v.1900 32 бит (Intel)] на win32
Введите «авторские права», «кредиты» или «лицензия ()» для получения дополнительной информации.
>>>
ПЕРЕЗАПУСК: C: \ Users \ agott \ Desktop \ Penn State \ PSU Summer 2018 \ CMPSC360 \ Project \ Part 2 \ RSA Algorithm 3.0.py
RSA ШИФРОВАТЕЛЬ / ДЕКРИПТОР
************************************************ ***
ПОЖАЛУЙСТА, ВВЕДИТЕ ЗНАЧЕНИЯ 'p' И 'q' НИЖЕ:
Введите простое число для p: 3
Введите простое число для q: 5
************************************************ ***
Модуль RSA (n): 15
Эйлерс Тойтент (г) это: 8
************************************************ ***
Значение e: 999
************************************************ ***
АЛГОРИТМ ЕВКЛИДА:
8 = 0 * (999) + 8
999 = 124 * (8) + 7
8 = 1 * (7) + 1
КОНЕЦ ШАГОВ ДЛЯ ДОСТИЖЕНИЯ АЛГОРИТМА Евклида.************************************************ ***
РАСШИРЕННЫЙ АЛГОРИТМ ЕВКЛИДА:
1 = 8 * (1) + (-1) * (7)
1 = 999 * (- 1) + (125) * (8)
s = -1. Поскольку -1 меньше 0, s = s (modr), т.е. s = 7.
КОНЕЦ ШАГОВ, ИСПОЛЬЗУЕМЫХ ДЛЯ ДОСТИЖЕНИЯ ЗНАЧЕНИЯ 'd'.
Значение d: 7
************************************************ ***
Закрытый ключ: (7, 15)
Открытый ключ: (999, 15)
************************************************ ***
Что бы вы хотели зашифровать или расшифровать? (Для расшифровки номера разделяйте символами ','): ПРИВЕТ
Ваше сообщение: ПРИВЕТ
Введите «1» для шифрования и «2» для дешифрования.1
Ваше зашифрованное сообщение: [13, 4, 11, 11, 14]
Спасибо за использование RSA Encryptor. Прощай!
>>>
ПЕРЕЗАПУСК: C: \ Users \ agott \ Desktop \ Penn State \ PSU Summer 2018 \ CMPSC360 \ Project \ Part 2 \ RSA Algorithm 3.0.py
RSA ШИФРОВАТЕЛЬ / ДЕКРИПТОР
************************************************ ***
ПОЖАЛУЙСТА, ВВЕДИТЕ ЗНАЧЕНИЯ 'p' И 'q' НИЖЕ:
Введите простое число для p: 3
Введите простое число для q: 5
************************************************ ***
Модуль RSA (n): 15
Эйлерс Тойтент (г) это: 8
************************************************ ***
Значение e: 999
************************************************ ***
АЛГОРИТМ ЕВКЛИДА:
8 = 0 * (999) + 8
999 = 124 * (8) + 7
8 = 1 * (7) + 1
КОНЕЦ ШАГОВ ДЛЯ ДОСТИЖЕНИЯ АЛГОРИТМА Евклида.