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:bytesformat='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.

Скачать файлы

Загрузите файл для своей платформы. Если вы не уверены, что выбрать, узнайте больше об установке пакетов.

Файлы для rsa, версия 4.7.2
Имя файла, размер Тип файла Версия 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__":
    основной()
  

Заключительные ноты:

  • последняя печать s имеет 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

Загрузка ключа

Если у вас уже есть дисковый ключ в формате 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 , чтобы получить максимальную длину соли
имеется в наличии.

class cryptography.hazmat.primitives.asymmetric.padding. OAEP ( MGF , алгоритм , метка )

OAEP (Optimal Asymmetric Encryption Padding) - это схема заполнения, определенная в
RFC 3447 .Он обеспечивает вероятностное шифрование и доказал свою безопасность.
против нескольких типов атак. Это рекомендуемый алгоритм заполнения
для шифрования RSA. Его нельзя использовать с подписью RSA.

Параметры:
  • mgf - Объект функции создания маски. На этот раз единственный
    поддерживаемый MGF - MGF1 .
  • алгоритм - Экземпляр
    Хэш-алгоритм .
  • метка ( байта ) - метка, которую нужно применить.Это редко используемое поле и
    обычно должно быть установлено значение Нет или b "" , что эквивалентно.
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).
класс криптография.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. конструкция ( 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 - Когда данный ключ не может быть проанализирован (возможно, из-за передачи
фраза неверна).
класс 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 DER SubjectPublicKeyInfo
    структура всегда используется.

  • защита ( строка ) -

    ( Только для закрытых ключей )
    Схема шифрования, используемая для защиты закрытого ключа.

    Если Нет (по умолчанию), поведение зависит от формата :

    • Для ‘DER’ , PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC
      схема используется.Выполняются следующие операции:

      1. 16-байтовый тройной ключ DES получен из парольной фразы
        используя Crypto.Protocol.KDF.PBKDF2 () с 8-байтовой солью,
        и 1000 итераций Crypto.Hash.HMAC .
      2. Закрытый ключ зашифрован с использованием CBC.
      3. Зашифрованный ключ закодирован в соответствии с PKCS # 8.
    • Для «PEM» используется устаревшая схема шифрования PEM.
      Он основан на MD5 для получения ключей и Triple DES для шифрования.

    Указание значения для защиты имеет смысл только для PKCS # 8
    (то есть pkcs = 8 ) и только если присутствует парольная фраза.

    Поддерживаемые схемы для PKCS # 8 перечислены в
    Модуль Crypto.IO.PKCS8 (см. Параметр wrap_algo ).

  • 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 DER SubjectPublicKeyInfo
    структура всегда используется.

  • защита ( строка ) -

    ( Только для закрытых ключей )
    Схема шифрования, используемая для защиты закрытого ключа.

    Если Нет (по умолчанию), поведение зависит от формата :

    • Для ‘DER’ , PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC
      схема используется.Выполняются следующие операции:

      1. 16-байтовый тройной ключ DES получен из парольной фразы
        используя Crypto.Protocol.KDF.PBKDF2 () с 8-байтовой солью,
        и 1000 итераций Crypto.Hash.HMAC .
      2. Закрытый ключ зашифрован с использованием CBC.
      3. Зашифрованный ключ закодирован в соответствии с PKCS # 8.
    • Для «PEM» используется устаревшая схема шифрования PEM.
      Он основан на MD5 для получения ключей и Triple DES для шифрования.

    Указание значения для защиты имеет смысл только для PKCS # 8
    (то есть pkcs = 8 ) и только если присутствует парольная фраза.

    Поддерживаемые схемы для PKCS # 8 перечислены в
    Модуль Crypto.IO.PKCS8 (см. Параметр wrap_algo ).

  • 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
КОНЕЦ ШАГОВ ДЛЯ ДОСТИЖЕНИЯ АЛГОРИТМА Евклида.

Добавить комментарий

Ваш адрес email не будет опубликован.