烧瓶和JavaScript的RSA加密

发布于 2025-02-02 02:45:39 字数 6597 浏览 3 评论 0原文

我正在尝试使用RSA公共密钥两次加密数据,我在Python中遇到以下错误,

Traceback (most recent call last):
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "app.py", line 39, in register_user
    first_encrypted = client_key_decrypter.decrypt(data['cipher'])
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/Crypto/Cipher/PKCS1_OAEP.py", line 167, in decrypt
    raise ValueError("Ciphertext with incorrect length.")
ValueError: Ciphertext with incorrect length.

我要做的是

在烧瓶中生成公共和私钥,

生成客户端公共和私人密钥用于使用独特 每个呼叫,

使用JSencrypt加密数据客户端,

使用PyCryptodome解密数据服务器端,

这是我的app.py

from flask import Flask
from flask import render_template
from flask import request
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
from base64 import *

application = Flask(__name__, static_url_path='/static')
random_generator = Random.new().read
key = RSA.generate(2048, random_generator) #generate public and private keys

@application.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

@application.route("/register")
def register():
    crypto_key = key.publickey().export_key()
    client_random_generator = Random.new().read
    client_key = RSA.generate(4096, client_random_generator) #generate for client-side encryption
    print(client_key)
    return render_template('register.html', 
        serverCrypto = crypto_key.decode("utf-8"),
        clientCrypto = client_key.publickey().export_key().decode("utf-8"), 
        randomName1 = client_key.export_key().decode("utf-8"), 
        randomName2 = None, 
        randomName3 = None)

@application.route("/users", methods=['POST'])
def register_user():
    error = None
    if request.method == "POST":
        data = request.get_json()
        print(data)
        client_key = RSA.importKey(data['clientPrivateKey'])
        client_key_decrypter = PKCS1_OAEP.new(client_key)
        first_encrypted = client_key_decrypter.decrypt(data['cipher'])
        server_key = PKCS1_OAEP.new(key.export_key())
        second_encrypted = server_key.decrypt(first_encrypted)
        print(second_encrypted)
    return render_template('login.html', error=error)

@application.route("/crypto", methods=['POST'])
def get_crypto():
    if request.method == "POST":
        return None

if __name__ == "__main__":
    application.run(ssl_context=('cert.pem', 'key.pem'))

my html代码

<!DOCTYPE html>
<html>
<head>
    <title>Demo!</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/2.3.1/jsencrypt.min.js"></script>
    <script type="text/javascript" src="/static/js/register.js"></script>
    <style type="text/css">
            input { margin-right: 100% }
        </style>
</head>
<body>
<h2>Register</h2>
<form id="register">
    <label>Username: <input name="username" type="text"
                            id="username">
    </label>
    <label>Password: <input name="password" type="password"
                            id="password">
    </label>
    <input type="hidden" name="serverCrypto" id="serverCrypto" value="{{ serverCrypto }}"/>
    <input type="hidden" name="clientCrypto" id="clientCrypto" value="{{ clientCrypto }}"/>
    <input type="hidden" name="randomName1" id="randomName1" value="{{ randomName1 }}"/>
    <input type="hidden" name="randomName2" id="randomName2" value="{{ randomName2 }}"/>
    <input type="hidden" name="randomName3" id="randomName3" value="{{ randomName3 }}"/>
    <button type="register">Register</button>
</form>
</body>
</html>

和我的javascript代码

const apiUrl = 'https://localhost:5000';


function register(username, password, serverCrypto, clientCrypto, randomName1) {
    let data = {"username": username, "passwword": password}

    const encrypt = new JSEncrypt();
    encrypt.setPublicKey(serverCrypto);
    var encrypted = encrypt.encrypt(JSON.stringify(data));
    console.log(encrypted); // shows up as false
    encrypt.setPublicKey(clientCrypto);
    encrypted = encrypt.encrypt(encrypted);
    console.log(encrypted);
    dataToSend = {"cipher": encrypted, "clientPrivateKey": randomName1};

    fetch(apiUrl + '/users', {
        method: 'POST',
        body: JSON.stringify(dataToSend),
        headers: {
            'Content-Type': 'application/json',
        }
    })
    .then(res => {
       if (res.ok) {
         res.json().then(json => {
            console.log(json);
         });
       }
    })
    .catch(error => console.error('Error logging in: ', error));
}

window.addEventListener('load', function(e) {
    document.getElementById('register')
        .addEventListener('submit', processRegisterSubmit);
});

function processRegisterSubmit(e) {
    e.preventDefault();

    let username = document.getElementById('username').value;
    let password = document.getElementById('password').value;
    let serverCrypto = document.getElementById('serverCrypto').value;
    let clientCrypto = document.getElementById('clientCrypto').value;
    let randomName1 = document.getElementById('randomName1').value;
    let randomName2 = document.getElementById('randomName2').value;
    let randomName3 = document.getElementById('randomName3').value;
    

    register(username, password, serverCrypto, clientCrypto, randomName1);
    return false;
}

I'm trying to encrypt the data twice with rsa public keys, I'm getting the following error in python,

Traceback (most recent call last):
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "app.py", line 39, in register_user
    first_encrypted = client_key_decrypter.decrypt(data['cipher'])
  File "/Users/pbhat1/Documents/dev/registrationdemo/venv/lib/python3.8/site-packages/Crypto/Cipher/PKCS1_OAEP.py", line 167, in decrypt
    raise ValueError("Ciphertext with incorrect length.")
ValueError: Ciphertext with incorrect length.

What I'm trying to do is

generate the public and private keys in flask,

generate the client public and private keys to use unique to
each call,

encrypt the data client side using jsencrypt,

decrypt the data server side using pycryptodome

here's my code in app.py

from flask import Flask
from flask import render_template
from flask import request
import Crypto
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto import Random
from base64 import *

application = Flask(__name__, static_url_path='/static')
random_generator = Random.new().read
key = RSA.generate(2048, random_generator) #generate public and private keys

@application.route("/")
def hello():
    return "<h1 style='color:blue'>Hello There!</h1>"

@application.route("/register")
def register():
    crypto_key = key.publickey().export_key()
    client_random_generator = Random.new().read
    client_key = RSA.generate(4096, client_random_generator) #generate for client-side encryption
    print(client_key)
    return render_template('register.html', 
        serverCrypto = crypto_key.decode("utf-8"),
        clientCrypto = client_key.publickey().export_key().decode("utf-8"), 
        randomName1 = client_key.export_key().decode("utf-8"), 
        randomName2 = None, 
        randomName3 = None)

@application.route("/users", methods=['POST'])
def register_user():
    error = None
    if request.method == "POST":
        data = request.get_json()
        print(data)
        client_key = RSA.importKey(data['clientPrivateKey'])
        client_key_decrypter = PKCS1_OAEP.new(client_key)
        first_encrypted = client_key_decrypter.decrypt(data['cipher'])
        server_key = PKCS1_OAEP.new(key.export_key())
        second_encrypted = server_key.decrypt(first_encrypted)
        print(second_encrypted)
    return render_template('login.html', error=error)

@application.route("/crypto", methods=['POST'])
def get_crypto():
    if request.method == "POST":
        return None

if __name__ == "__main__":
    application.run(ssl_context=('cert.pem', 'key.pem'))

my html code

<!DOCTYPE html>
<html>
<head>
    <title>Demo!</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/2.3.1/jsencrypt.min.js"></script>
    <script type="text/javascript" src="/static/js/register.js"></script>
    <style type="text/css">
            input { margin-right: 100% }
        </style>
</head>
<body>
<h2>Register</h2>
<form id="register">
    <label>Username: <input name="username" type="text"
                            id="username">
    </label>
    <label>Password: <input name="password" type="password"
                            id="password">
    </label>
    <input type="hidden" name="serverCrypto" id="serverCrypto" value="{{ serverCrypto }}"/>
    <input type="hidden" name="clientCrypto" id="clientCrypto" value="{{ clientCrypto }}"/>
    <input type="hidden" name="randomName1" id="randomName1" value="{{ randomName1 }}"/>
    <input type="hidden" name="randomName2" id="randomName2" value="{{ randomName2 }}"/>
    <input type="hidden" name="randomName3" id="randomName3" value="{{ randomName3 }}"/>
    <button type="register">Register</button>
</form>
</body>
</html>

and my javascript code

const apiUrl = 'https://localhost:5000';


function register(username, password, serverCrypto, clientCrypto, randomName1) {
    let data = {"username": username, "passwword": password}

    const encrypt = new JSEncrypt();
    encrypt.setPublicKey(serverCrypto);
    var encrypted = encrypt.encrypt(JSON.stringify(data));
    console.log(encrypted); // shows up as false
    encrypt.setPublicKey(clientCrypto);
    encrypted = encrypt.encrypt(encrypted);
    console.log(encrypted);
    dataToSend = {"cipher": encrypted, "clientPrivateKey": randomName1};

    fetch(apiUrl + '/users', {
        method: 'POST',
        body: JSON.stringify(dataToSend),
        headers: {
            'Content-Type': 'application/json',
        }
    })
    .then(res => {
       if (res.ok) {
         res.json().then(json => {
            console.log(json);
         });
       }
    })
    .catch(error => console.error('Error logging in: ', error));
}

window.addEventListener('load', function(e) {
    document.getElementById('register')
        .addEventListener('submit', processRegisterSubmit);
});

function processRegisterSubmit(e) {
    e.preventDefault();

    let username = document.getElementById('username').value;
    let password = document.getElementById('password').value;
    let serverCrypto = document.getElementById('serverCrypto').value;
    let clientCrypto = document.getElementById('clientCrypto').value;
    let randomName1 = document.getElementById('randomName1').value;
    let randomName2 = document.getElementById('randomName2').value;
    let randomName3 = document.getElementById('randomName3').value;
    

    register(username, password, serverCrypto, clientCrypto, randomName1);
    return false;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文