簡體   English   中英

如何讓django和python-rsa(或其他python庫)的jCryption工作

[英]How to get jCryption work with django and python-rsa (or another python library)

我想向客戶端發送一些秘密數據,所以我想對其加密。

我在客戶端使用jCryption 它在連接開始時使用握手,過程如下:

  1. 客戶端生成隨機AES密碼。
  2. 客戶端請求RSA publicKey表單服務器
  3. 服務器發送
  4. 客戶端使用RSA公鑰對密碼進行加密並將其發送到服務器。
  5. 現在,兩者都使用該密碼來加密彼此發送的數據。

我的問題是在發送使用RSA加密的密碼的步驟(第4步),因為jCryption以十六進制格式發送密碼,但是python-rsa期望二進制整數,

如何將jCryption輸出轉換為python-rsa可以處理的格式,或者是否有另一個庫可以做到?

RSA密文如下所示:

TO \\ xa75 [\\ x9a \\ x07s4 \\ x86 \\ xbc \\ xae \\ xe3 \\ xd5s)1 \\ x0cd5 \\ xdfY \\ xf7 \\ xeds9 \\ xf3〜\\ n \\ x9fA $ \\ xa9 \\ xfb; \\ x04 \\ x1e \\ x18 \\ xf4 \\ xea \\ x7f \\ x91 \\ xd9 \\ xb7 [\\ xd3 \\ x138 \\ xb6b \\ x9c \\ xb6 \\ x1b \\ xe7 \\ x11 \\ x9aB \\ x1d @`y \\ x9c0 \\ xe8 \\ xb6!\\ x8b〜lg \\ xabO \\ xbeny \\ xf7Xu \\ x89YW \\ xb0 \\ xda @ \\ x10 \\ x0c \\ xe7 \\ x85 \\ x9bX \\ x8f \\ x02e \\ xdalf | \\ xa6 \\ x0e \\ x8e \\ x8e \\ x9d \\ xd8 = \\ x9bQLO7 \\ x0fd \\ x19 /] t?\\ xf1 \\ x96 \\ x1b \\ xb9 \\ x8bv \\ xb4 \\ xb4rS \\ x1c \\ xb9

從jCryption發送的數據如下所示:

11a6ebb863c379255df711aba86ad3986d6ecc33402a1596e6036b8d33f41932909a3e8c10cc4e0d2ece5f369808020ac7241a4285c80e6e483a1f6b43d933149961f50b72a808c769d39215ce08c33cfdb543b68bb0cf644f32dccf7eb90547290d47b96758449df3e7d4ec 2b50aef21ff4735c79f74bf5214ff356e4338ff2b292110ad537d160e41e34b350c7bc857601a943f915285e62f308fb6bd61d275321b68fbf27a52fbffc27b9ad15810795ccdea6d9776246b84b00503c2711d49a3f101af6f2c822d697a71aeca684e20328071ce84da907

好的,我已經完成了此任務,但首先我想說的是,為我獲取https以后的LetsEncrypt免費證書要容易得多

對於此解決方案,您需要安裝openssl。

讓我們為我們的ajax編寫視圖

獲取公鑰。 如果我們在項目目錄中沒有一個,則生成一對。

    def public_key(req):
        if not os.path.isfile(os.path.join(settings.BASE_DIR, 'form_key.pem')) or not os.path.isfile(os.path.join( settings.BASE_DIR,'form_key_pub.pem')):
            check_call(['openssl', 'genrsa', '-out', os.path.join(settings.BASE_DIR,'form_key.pem'), '4096'])
            check_call(['openssl', 'rsa', '-pubout', '-in', os.path.join(settings.BASE_DIR,'form_key.pem'), '-out', os.path.join(settings.BASE_DIR,'form_key_pub.pem')])
        f = open(os.path.join(settings.BASE_DIR,'form_key_pub.pem'))
        key = f.read()
        f.close()
        return JsonResponse({"publickey": key})

好的,握手。 為了CSRF保護此視圖,我們需要修補jCryption javascript庫中沒有的內容。 我在這里將AES密鑰保存在會話存儲中。

    @csrf_exempt
    def handshake(req):
        if req.method == 'POST':
            encb64key = req.POST['key']
            encb64key = re.sub(r'[^a-zA-Z0-9/=+]', '', encb64key)
            enckey = b64decode(encb64key)
            openssl = Popen(['openssl', 'rsautl', '-decrypt', '-inkey', os.path.join(settings.BASE_DIR,'form_key.pem')], stdin = PIPE, stdout=PIPE, stderr=PIPE)
            key, stderr = openssl.communicate(enckey)
            print stderr
            key = re.sub(r'[^a-zA-Z0-9]', '', key)
            req.session['form_key'] = key 
            openssl = Popen(['openssl', 'enc', '-aes-256-cbc', '-pass', 'pass:'+key, '-a', '-e'], stdin = PIPE, stdout = PIPE, stderr = PIPE)
            enckey , stderr = openssl.communicate(key)
            print stderr
            enckey = re.sub('[^a-zA-Z0-9/+=]', '' , enckey)
            return JsonResponse({'challenge': enckey})
        raise Http404() 

讓我們為urls.py中的視圖選擇URL

    url('^pubkey', public_key, name = 'publickey'),
    url('^handshake', handshake, name = 'handshake'),

而最棘手的部分。 我們自己的中間件。 您需要將其添加到settings.py中的MIDDLEWARE_CLASSES。 如果將其放置在myapp的views.py文件中,則類似於“ myapp.views.JCryptionMiddleware”。

訣竅是我們僅使用“ jCryption”屬性發送錯誤的POST數據。 中間件在該attr中解密適當的數據,並使用它重寫請求對象中的POST數據。 在Django文檔中閱讀有關中間件的信息。

    class JCryptionMiddleware(object):
        def process_view(self, request, callback, callback_args, callback_kwargs):
            jcryptedb64 = request.POST.get('jCryption', '')
            if jcryptedb64:
                try:
                    jcrypted = b64decode(jcryptedb64)
                    p = Popen(['openssl', 'enc', '-aes-256-cbc', '-pass', 'pass:'+request.session['form_key'], '-d'], stdin = PIPE, stdout = PIPE, stderr = PIPE)
                    qstr, stderr = p.communicate(jcrypted)
                    print stderr
                    wasmutable = request.POST._mutable
                    request.POST._mutable = True
                    request.POST.__init__(qstr)
                    request.POST._mutable = wasmutable
                except Exception as e:
                    print e
            return None

以及頁面中帶有表單模板的客戶端代碼。

    <script src="{{ STATIC_URL }}js/jquery.min.js"></script>
    <script src="{{ STATIC_URL }}js/jcryption.js"></script>
    <script>
    $(function() {
        $('form').jCryption({"getKeysURL": "/pubkey", "handshakeURL": "/handshake"});
    });
    </script>

請參閱我們的urls.py中的網址。

例如,您可以加密您的管理員登錄表單。 將login.html從django contrib admin復制到templates / admin / login.html並將此javascript代碼添加到模板中。

da! 不要使用此,請使用HTTPS。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM