1

クライアントに秘密のデータを送信したいので、暗号化したい。

クライアント側でjCryptionを使用しています。接続の開始時にハンドシェイクを使用します。手順は次のように行われます。

  1. クライアントはランダムな AES パスワードを生成します。
  2. クライアント リクエスト RSA publicKey フォーム サーバー
  3. サーバーが送信する
  4. クライアントは RSA 公開鍵を使用してパスワードを暗号化し、サーバーに送信します。
  5. 現在、両者はそのパスワードを使用して、相互に送信するデータを暗号化しています。

jCryptionはパスワードを16進形式で送信するため、RSAで暗号化されたパスワードを送信するステップ(ステップ4)に問題がありますが、 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

4

1 に答える 1

0

OK、このクエストは完了しましたが、最初に言いたいのは、後で行ったように、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 内の適切なデータを復号化し、それを使用して request オブジェクト内の 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 の URL を参照してください。

たとえば、管理者ログイン フォームを暗号化できます。login.html を django contrib admin から templates/admin/login.html にコピーし、この JavaScript コードをテンプレートに追加します。

タダ!これを使用しないでください。HTTPS を使用してください。

于 2015-12-29T11:22:59.823 に答える