{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import os\n", "from cryptography.hazmat import backends\n", "from cryptography.hazmat.primitives import hashes\n", "from cryptography.hazmat.primitives.asymmetric import utils\n", "from cryptography.hazmat.primitives.asymmetric import rsa\n", "from cryptography.hazmat.primitives import serialization\n", "from cryptography.hazmat.primitives.asymmetric import padding" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def int_to_bytes(x: int) -> bytes:\n", " return x.to_bytes((x.bit_length() + 7) // 8, 'big')" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Два открытых текста\n", "plain_text1 = b\"58\"\n", "plain_text2 = b\"4\"" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Генерация публичного ключа, public_exponent=3 (e), \n", "# TODO: попробуйте сгенерировать ключ длиной 256 битов. Объясните результат\n", "private_key = rsa.generate_private_key(public_exponent=3, key_size=512, backend=backends.default_backend())" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'-----BEGIN RSA PRIVATE KEY-----',\n", " b'MIIBOwIBAAJBAMu1Plu+bLzcuZSEfAIqsvdKQjNRY+QSIHsQsk71LH1R1rWpugcb',\n", " b'TB+qxFnWSSQxyv5JaYs3W+9nr3jvcHeKNlUCAQMCQQCHzimSfvMokyZjAv1WxyH6',\n", " b'MYF3i5ftYWr8tcw0o3L+NV6Z08rFnW1DHDT/b12Wt/vExpq+JMuBVJczNv9ToFtz',\n", " b'AiEA6Ml6uPqOBOZnbUzbqJUBH5geoh1/C7u9SvV/UUWWU4sCIQDgBXFQ5CEjVJkH',\n", " b'jdOULRyxvwDfUIEe8auBtp2gNINZnwIhAJsw/HtRtANERPOIknBjVhUQFGwTqgfS',\n", " b'fjH4/4uDuY0HAiEAlVj2Ne1rbOMQr7PiYsi9y9SrP4sAv0vHq88TwCMCO78CIQDD',\n", " b'8fZsG321RePUlc2ljRBieV+oAP2VSNu4QeQPhA4tNg==',\n", " b'-----END RSA PRIVATE KEY-----']" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Просмотр содержимого секретного ключа\n", "pem = private_key.private_bytes(\n", " encoding=serialization.Encoding.PEM,\n", " format=serialization.PrivateFormat.TraditionalOpenSSL,\n", " encryption_algorithm=serialization.NoEncryption())\n", "\n", "# Формат для записи в файл/для передачи по сети\n", "pem.splitlines()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# Секретное число, для которого e x d=1 mod ((p-1)(q-1))\n", "d = private_key.private_numbers().d" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[b'-----BEGIN PUBLIC KEY-----',\n", " b'MFowDQYJKoZIhvcNAQEBBQADSQAwRgJBAMu1Plu+bLzcuZSEfAIqsvdKQjNRY+QS',\n", " b'IHsQsk71LH1R1rWpugcbTB+qxFnWSSQxyv5JaYs3W+9nr3jvcHeKNlUCAQM=',\n", " b'-----END PUBLIC KEY-----']" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# просмотр содержимого открытого ключа\n", "public_key = private_key.public_key()\n", "pem = public_key.public_bytes(\n", " encoding=serialization.Encoding.PEM,\n", " format=serialization.PublicFormat.SubjectPublicKeyInfo)\n", "\n", "# Формат для записи в файл/для передачи по сети\n", "pem.splitlines()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "e = public_key.public_numbers().e" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "n = int(public_key.public_numbers().n)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10669052760492704969889175507802197153705895081930185893657373545838235340277562771266395178505206456909397291234845763674171653256429076791779811616503381\n" ] } ], "source": [ "print(n)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# Шифрование \n", "cipher_text1 = public_key.encrypt(plain_text1, padding.PKCS1v15())\n", "cipher_text2 = public_key.encrypt(plain_text2, padding.PKCS1v15())" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Cipher text1 = b'\\xb9\\ts\\xe8J\\xaa\\xcc/\\x0e|\\x9b\\x00`\\xab\\xe2kR\\x92\\xb7\\xa2\\x8f]C p\\x1a\\xfaqV)\\xa1m+\\x9a\\xae\\x99\\x1b0\\xd1\\xcd\\xa3;\\r|CU\\x06c\\xdc\\x11u\\x91\\xedC\\xc8\\x81t\\x83\\xf3?\\x1bI\\xde\\x96' 64\n", "Cipher text2 = b'\\x8a\\x90\\xa7[\\xea\\xde\\t\\xa4\\x99\\x9f\\xda\\x14\\xd5@x\\xec\\x03\\xe9\\x89\\x80\\xff\\xba\\x81\\x99\\xa2\\x11c7\\x1a\\x80\\x90\\x08\\xb3\\x81fi8\\t@ %\\xda\\xb4Z6\\x16\\x00\\xa3\\xea$\\xb9`X\\x92r~\\xe2\\x15\\xff\\xe3Nl\\xb6D' 64\n" ] } ], "source": [ "print(\"Cipher text1 = \", cipher_text1, len(cipher_text1))\n", "print(\"Cipher text2 = \", cipher_text2, len(cipher_text2))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# Расшифрование\n", "plain_text1 = private_key.decrypt(cipher_text1, padding.PKCS1v15())" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "b'58'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "plain_text1" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9691170111023022721564242860485637769769359078705157301955035945214579461290810277996451464058492530723777893831180468675682572818866644029400818930802326\n", "7257240725642937563206833412652178138599554586539650911269768134247934322094801380450846368625992444622025900827483661152188110918137198461902608650778180\n" ] } ], "source": [ "# Преобразовать шифрограммы в большие числа\n", "int_cipher_text1 = int.from_bytes(cipher_text1, byteorder='big')\n", "int_cipher_text2 = int.from_bytes(cipher_text2, byteorder='big')\n", "int_n = int(public_key.public_numbers().n)\n", "print(int_cipher_text1)\n", "print(int_cipher_text2)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "# перемножить шифрограммы\n", "mult_cipher_texts = (int_cipher_text1 * int_cipher_text2) % int_n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "ename": "ValueError", "evalue": "Decryption failed.", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# TODO: объясните, почему данные не расшифровываются\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mmult_plain_texts\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mprivate_key\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdecrypt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mint_to_bytes\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmult_cipher_texts\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpadding\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mPKCS1v15\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;32m~\\Anaconda31\\lib\\site-packages\\cryptography\\hazmat\\backends\\openssl\\rsa.py\u001b[0m in \u001b[0;36mdecrypt\u001b[1;34m(self, ciphertext, padding)\u001b[0m\n\u001b[0;32m 357\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Ciphertext length must be equal to key size.\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 358\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 359\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_enc_dec_rsa\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_backend\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mciphertext\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpadding\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 360\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 361\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mpublic_key\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m~\\Anaconda31\\lib\\site-packages\\cryptography\\hazmat\\backends\\openssl\\rsa.py\u001b[0m in \u001b[0;36m_enc_dec_rsa\u001b[1;34m(backend, key, data, padding)\u001b[0m\n\u001b[0;32m 66\u001b[0m )\n\u001b[0;32m 67\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 68\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0m_enc_dec_rsa_pkey_ctx\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbackend\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpadding_enum\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpadding\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 69\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 70\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m~\\Anaconda31\\lib\\site-packages\\cryptography\\hazmat\\backends\\openssl\\rsa.py\u001b[0m in \u001b[0;36m_enc_dec_rsa_pkey_ctx\u001b[1;34m(backend, key, data, padding_enum, padding)\u001b[0m\n\u001b[0;32m 120\u001b[0m \u001b[0mres\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcrypt\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpkey_ctx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbuf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moutlen\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 121\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mres\u001b[0m \u001b[1;33m<=\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 122\u001b[1;33m \u001b[0m_handle_rsa_enc_dec_error\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbackend\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 123\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 124\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mbackend\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_ffi\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mbuffer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mbuf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m:\u001b[0m\u001b[0moutlen\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m~\\Anaconda31\\lib\\site-packages\\cryptography\\hazmat\\backends\\openssl\\rsa.py\u001b[0m in \u001b[0;36m_handle_rsa_enc_dec_error\u001b[1;34m(backend, key)\u001b[0m\n\u001b[0;32m 151\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 152\u001b[0m \u001b[0mbackend\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mopenssl_assert\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merrors\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mreason\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mdecoding_errors\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 153\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Decryption failed.\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 154\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 155\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mValueError\u001b[0m: Decryption failed." ] } ], "source": [ "# TODO: объясните, почему данные не расшифровываются\n", "mult_plain_texts = private_key.decrypt(int_to_bytes(mult_cipher_texts), padding.PKCS1v15())" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "# \"Чистый\" RSA (без padding)\n", "m1=58\n", "m2=8\n", "e=5\n", "n=289301\n", "d=57641" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "c1 = pow(m1,e) % n\n", "c2 = pow(m2,e) % n" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "464 == 464\n" ] } ], "source": [ "# Проверка гомоморфизма для умножения\n", "mult_c1c2 = (c1*c2) % n\n", "print(pow(mult_c1c2,d)% n,'==',m1*m2)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "259859 == 66\n" ] } ], "source": [ "# Проверка гомоморфизма для сложения\n", "sum_c1c2 = (c1+c2) % n\n", "print(pow(sum_c1c2,d)% n,'==',m1+m2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }