浅訴肆唸﹏ 2024-07-20 23:46 采纳率: 100%
浏览 21
已结题

前端使用jsencrypt.js加密后,Python中使用cryptography.py模块解密报Ciphertext length must be equal to key size.

问题:后端将cryptography.py模块生成的公钥base64编码后传到前端,前端使用jsencrypt.js进行加密。加密后将密文传回后端,后端解密报错Ciphertext length must be equal to key size.

Traceback (most recent call last):
  File "D:\Python3.12\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python3.12\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Python3.12\Lib\site-packages\django\views\decorators\csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\xxx\xxx\django_demo\login\views.py", line 85, in register
    a = encryption.decryption_from_rsa(request.session.get('private_key'), username)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\xxx\xxx\django_demo\utils\encryption.py", line 44, in decryption_from_rsa
    decrypted_data = private_key.decrypt(
                     ^^^^^^^^^^^^^^^^^^^^
ValueError: Ciphertext length must be equal to key size.

疑问:将生成的私钥、前端base64解码后的公钥使用在线加密/解密平台进行解密是可以正常解密的,为什么使用cryptography.py进行解密就会报错???

img

相关Python代码
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding, rsa

def get_key() -> dict:
    """ 获取公钥和私钥 """
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048, backend=default_backend())
    public_key = private_key.public_key()
    private_key_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption()
    ).decode()
    public_key_pem = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    ).decode()
    return {'private_key': private_key_pem, 'public_key': public_key_pem}

def decryption_from_rsa(private_key, encrypted_data) -> dict:
    """ 数据解密 """
    private_key = serialization.load_pem_private_key(private_key.encode(), password=None, backend=default_backend())
    decrypted_data = private_key.decrypt(
        encrypted_data,
        padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)
    )
    return {'decrypted_data': decrypted_data}
Django中views部分代码
from urllib.parse import unquote

def get_public(request):
    """ 前端获取公钥的方法 """
    encrypt_keys = encryption.get_key()
    request.session.set_expiry(300)
    request.session['private_key'] = encrypt_keys.get('private_key')
    public_key = base64.b64encode(encrypt_keys.get('public_key').encode('utf-8'))
    return HttpResponse(public_key)

def register(request):
    """ 获取前端上传密文并解密 """
    password = encryption.decryption_from_rsa(request.session.get('private_key'), unquote(base64.b64decode(request.POST.get('password'))).encode())
    return HttpResponse(password)
HTML中的JS代码
    function registerSubmit(){
        $.ajax({
            url: "/getPublic/",
            type: "GET",
            success: function (res) {
                let password = hex_md5($('#password').val())
                let encrypt = new JSEncrypt();
                let public_key = decodeURIComponent(window.atob(res));
                encrypt.setPublicKey(public_key);
                password = window.btoa(encodeURIComponent(encrypt.encrypt(password)));
                $.ajax({
                    url: "/register/",
                    type: "POST",
                    async: false,
                    data: { "password": password},
                    success: function(res){
                        console.log(res);
                    }
                });
            }
        });
    }
HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="{% static "/js/jquery-3.5.1.min.js" %}"></script>
    <script src="{% static "/plugins/jsencrypt/bin/jsencrypt.min.js" %}"></script>
    <script src="{% static "/js/md5.js" %}"></script>
    <title>Title</title>
</head>
<body>
    密码:<label for="password"><input type="password" id="password" name="password"></label>
    <button type="button" id="submit" onclick="registerSubmit()">注册</button>
</body>
</html>
  • 写回答

6条回答 默认 最新

  • 浅訴肆唸﹏ 2024-09-09 15:50
    关注

    已更换为pycryptodemo模块,详见【Python之RSA加密 解密 签名 验证 - CSDN App】http://t.csdnimg.cn/rcBOU

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 9月17日
  • 已采纳回答 9月9日
  • 修改了问题 7月20日
  • 修改了问题 7月20日
  • 展开全部

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?