lr11

parent 674acf08
# Лабораторная работа 11
## Описание
Написано на python и fastapi, запускается из docker, есть страница для загрузки
ключа и зашифрованного файла.
Также есть скрипт для шифрования файла и отправки запросов на созданый сервер
для расшифровки.
## Запуск
В директории ./code
Билдим контейнер
```shell
$ docker build -t decrypt-api .
```
Запускаем:
```shell
$ docker run -p 8000:8000 decrypt-api
```
(Для получения адреса можно использовать ![play with docker](https://labs.play-with-docker.com/)
## Демонстрация работы
"Фронтэнд" выглядит так:
<img src="./imgs/page.png" alt="drawing" width="1000"/>
Запуск скрипта ./test/test.sh:
```shell
$ ./test.sh
curl -X GET http://localhost:8000/login
{"login":1148905}
curl -X POST \
http://0.0.0.0:8000/decipher \
-F "private_key=@./private_key.pem" \
-F "encrypted_content=@./encrypted_content.bin"
{"decrypted_content":"Hello, World!"}
```
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
from fastapi import FastAPI, File, Form, UploadFile
from fastapi.responses import HTMLResponse
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
import base64
import uvicorn
import ssl
app = FastAPI()
@app.get("/login")
async def login():
return {"login": 1148905}
@app.post("/decipher")
async def decipher(
private_key: bytes = File(description="Private key in PEM format"),
encrypted_content: bytes = File(description="Encrypted content")
):
try:
private_key_loaded = serialization.load_pem_private_key(
private_key,
password=None,
backend=default_backend()
)
decrypted_data = private_key_loaded.decrypt(
encrypted_content,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return {"decrypted_content": decrypted_data.decode()}
except Exception as e:
return {"error": str(e)}, 400
@app.get("/upload", response_class=HTMLResponse)
async def get_upload_page():
return """
<!DOCTYPE html>
<html>
<head>
<title>File Decryption</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 20px auto; padding: 20px; }
.container { background-color: #f5f5f5; padding: 20px; border-radius: 8px; }
.success { color: green; }
.error { color: red; }
.file-input { margin: 10px 0; }
button { padding: 10px 20px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
button:hover { background-color: #0056b3; }
</style>
</head>
<body>
<div class="container">
<h2>File Decryption</h2>
<form id="decipherForm" enctype="multipart/form-data">
<div class="file-input">
<label for="privateKey">Private Key (.pem):</label><br>
<input type="file" id="privateKey" name="private_key" required>
</div>
<div class="file-input">
<label for="encryptedContent">Encrypted Content:</label><br>
<input type="file" id="encryptedContent" name="encrypted_content" required>
</div>
<button type="submit">Decrypt</button>
</form>
<div id="result"></div>
</div>
<script>
document.getElementById('decipherForm').addEventListener('submit', async (e) => {
e.preventDefault();
const resultDiv = document.getElementById('result');
resultDiv.innerHTML = 'Decrypting...';
try {
const formData = new FormData(e.target);
const response = await fetch('/decipher', {
method: 'POST',
body: formData
});
const data = await response.json();
if ('error' in data) {
resultDiv.innerHTML = `<div class="error">Error: ${data.error}</div>`;
} else {
resultDiv.innerHTML = `<div class="success">Decrypted content: ${data.decrypted_content}</div>`;
}
} catch (error) {
resultDiv.innerHTML = `<div class="error">Error: ${error.message}</div>`;
}
});
</script>
</body>
</html>
"""
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
anyio==4.9.0
cffi==1.17.1
click==8.2.1
cryptography==38.0.3
fastapi==0.92.0
h11==0.16.0
idna==3.10
pycparser==2.22
pydantic==1.10.22
python-multipart==0.0.20
sniffio==1.3.1
starlette==0.25.0
typing-extensions==4.14.0
uvicorn==0.18.2
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import base64
def generate_private_key():
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048
)
private_pem = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
)
with open('private_key.pem', 'wb') as f:
f.write(private_pem)
return key
def encrypt_content(content: str, private_key):
public_key = private_key.public_key()
encrypted = public_key.encrypt(
content.encode(),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
with open('encrypted_content.bin', 'wb') as f:
f.write(encrypted)
return encrypted
if __name__ == "__main__":
private_key = generate_private_key()
content_to_encrypt = input("Enter string to encrypt:")
encrypted_data = encrypt_content(content_to_encrypt, private_key)
print(f"Private key saved to: private_key.pem")
print(f"Encrypted content saved to: encrypted_content.bin")
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAsHt7Cn5TInUQqzFZLXa6qYynhbR4ixWmCIyvWCPj7oRVshGg
wNhPbztMk+ayiX3iXa0kTreWak8XMEaPpjK9CPWKwW8NFPXUgZqtLKP0TCnnAXbB
lSr6XL0EcUJSDRq492L0b8q9m56q7+OYGWfXGUCgzkd/dBnwgl9cD75ZjmyINL7u
Kzfe7OAZk8l23ARyZYq2rkb7D+DruBXa0Nr/5oX4VnT0wio2KaU5j1D7QdoVi5cu
c0QwOD/9JuG2z+2SjYGc2LNqzZSrYwasUB8EWjITV6FGLRThntK+szdIItUwAOAg
XEXCet6Mn1/ReYfXU0CR7qGfTU7TzQB1KapV0wIDAQABAoIBABdnzlH+SPZJQkms
r3VjyVkSf2aFyyA0Yc3BIsF0w8DuqhLbWvoty0h8O9QNr4tOjQamyimVGDdx1Sh2
OIzug7rmyF05ENTBJErVVww+6PfE7Y8jJIStANaVzDtdHqwAPvGy8lTKivT9nmas
ROVxq8mnPuxnTRRPxbb0q1f8gxIWmEEc00rkHv6Kj/GeEx++UQJvKHDk3H/+QKBr
EYAJD2ltDFXKPZezGBFbPHq1muvfDs8m/SL5/N1XoSxIHN+N0jvvuxmf6zQMu9n8
khdK1qp4bDcLEwcB3xHMUZ9TwFcbLwdMTBSFQVZWTNn5TBxq3sAkIFegjmBjgGMA
lwLJabECgYEAxikLOe5qeW+Wtv/EMhgPaFSvG0GutBvklIxg9jwkb2u7yHNJxkgY
3gKotd/pG/Ito6obTyMNps7v2zOQDBYnFo3kbD/6t4ahD5e82misDuihgBYwYfQW
DQg0hu1+GIbTIQJR4KZ/0i9fCnM3wUK/nRwWNEWCCEPP+OsAYLk8NusCgYEA4/6c
yYBgSM/HgqNQ87wC61BdTeuyib+BwaUfd8bREbUQkX3AzcrluwY0m8edMas3ODHg
1JVdvnoTv2HM7NvNmUXIeb+jicIq0TETuK0iGa6UeOuYW2sl3SZAVlD1bZz79S3M
nsgQUp9pdj7danVF8Jdau+E8PQJaC3TYqS2WcrkCgYB5IhHoweN4hEw/Za4LaUXR
4yJ/qPEgzIQ4gm+rVix3qAXMjR0mBmCdJkb3lv6qxKo9h/jVsXng5FMfTi/aE5il
YuuleJ7MnZHLNFiPsrirDG3dHLNKzajFIqTpbjhMye46GW7vwxgT5j1U6AXHMARu
CANSxMKuRrXVVeKPPeyfLQKBgGyqeggAS+PoRGsbdAX3YlzNnOr6n8nPoQSusuTf
ud36sr7ldPOg9QXC22g0J9P4iwUZoNMxrdCPVsIs1wM9cCzRec+ta0DJbqbuATxQ
KKSc9N79S0ynMRDKnneFdrSb0er1vUUgjccTe6yEIfwPkRouyWwq2g8qA8jaFDnu
JHrhAoGAOvnRdhPgoYjfGwLt1NmG/G0B18Ikh98D5pYfpEblTL1vjjSGKXYry5w9
510s2k6EfSv/5g+IkxXQS9gZ9+0Eb5h/oqyV8St9Un00hB5PEWUX5qK9UL+cKKNS
bo9tU5+6eJ7yOwpsggU/UIz9Sa/bQc0/XBAn7YRj9Qy6tc4WhKc=
-----END RSA PRIVATE KEY-----
#!/bin/bash
echo "curl -X GET http://localhost:8000/login"
curl -X GET http://localhost:8000/login
echo '
curl -X POST \
http://0.0.0.0:8000/decipher \
-F "private_key=@./private_key.pem" \
-F "encrypted_content=@./encrypted_content.bin"
'
curl -X POST \
http://0.0.0.0:8000/decipher \
-F "private_key=@./private_key.pem" \
-F "encrypted_content=@./encrypted_content.bin"
printf "\n"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment