RSA 공개키, 개인키 생성 방법
# 리눅스 SSH 에서 RSA 공개키, 개인키 생성방법
mkdir -p /home/rsa/key/
cd /home/rsa/key/
# Private Key 생성
openssl genrsa -out rsa_pri.pem 1024
# Public Key 생성
openssl rsa -pubout -in rsa_pri.pem -out rsa_pub.pem
|
rsa_key.php
Javascript 에서 RSA 암호화를 하고, PHP에서 복호화 시 아래 주석처리한 $key 부분을 주석처리 안해도 잘 동작된다.
그런데 Python 에서는 동작이 잘 안되더라. Python 에서도 동작되도록 Key 변수를 약간 수정했다.
<?php
function get_publickey() {
// 경로 : 절대경로로 설정 필요
$rsakeyfile = '/home/rsa/key/rsa_pub.pem';
$fp = fopen($rsakeyfile,"r");
$key = "";
while(!feof($fp)) {
$key .= fgets($fp,4096);
}
fclose($fp);
$key = preg_replace('/\r\n|\r|\n/','\n',$key);
//$key = str_replace('-----BEGIN PUBLIC KEY-----','',$key);
//$key = str_replace('-----END PUBLIC KEY-----','',$key);
return $key;
}
function get_privatekey() {
// 경로 : 절대경로로 설정 필요
$rsakeyfile = '/home/rsa/key/rsa_pri.pem';
$fp = fopen($rsakeyfile,"r");
$key = "";
while(!feof($fp)) {
$key .= fgets($fp,4096);
}
fclose($fp);
$key = preg_replace('/\r\n|\r|\n/','\n',$key);
//$key = str_replace('-----BEGIN RSA PRIVATE KEY-----','',$key);
//$key = str_replace('-----END RSA PRIVATE KEY-----','',$key);
return $key;
}
?>
|
login.html
pubkey는 예시로 일부만 발췌한 것이라 이 코드를 그대로 복사하면 동작되는게 아니다.
위에서 PHP코드로 발췌한 공개키를 복사하여 붙여녛기 해야 동작한다.
{% extends 'base.html' %}
{% load static %}
{% load bootstrap4 %}
{% block content %}
<form method="POST" id="post-form">
{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="btn btn-primary">로그인</button>
<a href="{% url 'home' %}">
<button type="button" class="btn btn-warning">취소</button>
</a>
</form>
<script type="text/javascript" src="{% static 'js/jsencrypt.min.js' %}"></script>
<script>
$(document).on('submit', '#post-form', function (e) {
e.preventDefault();
var plainpw = $("input[name=password]").val();
var pubkey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCQAB\n-----END PUBLIC KEY-----";
var crypt = new JSEncrypt();
crypt.setPrivateKey(pubkey);
var password = crypt.encrypt(plainpw);
$.ajax({
type: 'POST',
url: '{% url 'login' %}',
data: {
username: $("input[name=username]").val(),
password: password,
csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
action: 'post'
},
success: function (json) {
console.log(json);
if (json.data == 1) {
window.location.href = '/';
alert(json.message);
} else if (json.data == 0) {
alert(json.message);
}
},
error: function (xhr, errmsg, err) {
alert('에러가 발생했습니다.');
console.log(xhr.status + ": " + xhr.responseText);
}
});
});
</script>
{% endblock content %}
|
Javascript 에서 암호화한 비밀번호를 views.py 파일에서 복호화한다.
# accounts/views.py
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.views.decorators.csrf import csrf_exempt
from .forms import SignUpForm, LoginForm
from .RSACipher import *
def login_view(request):
context = {}
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
# 유효성 검사, 내부적으로 form.clean()을 실행한다.
username = form.cleaned_data.get("username")
enc_password = form.cleaned_data.get("password")
password = RSACipher().decrypt(enc_password)
try:
user = User.objects.get(username=username)
if check_password(password, user.password):
access = authenticate(username=username, password=password)
login(request, access)
context['data'] = '1'
context['message'] = '로그인 되었습니다.'
else:
context['data'] = '0'
context['message'] = '입력 정보를 확인하세요.'
# context['message'] = '비밀번호가 다릅니다.'
return JsonResponse(context)
except User.DoesNotExist: # 대문자 User 임에 주의
# 가입된 회원인지 미가입된 회원인지 알 수 없는 메시지 출력이 중요
context['data'] = '0'
context['message'] = '입력 정보를 확인하세요.'
return JsonResponse(context)
else:
context['form'] = form
else:
form = LoginForm()
context['form'] = form
return render(request, "accounts/login.html", context)
def logout_view(request):
logout(request)
return redirect("home")
|
라이브러리 설치
pip install pycryptodomex (for window)
pip install pycryptodome (for linux)
RSACipher 클래스는 아래 게시글을 참조하여 직접 구현하면 될 것이다.
https://stackoverflow.com/questions/30056762/rsa-encryption-and-decryption-in-python
https://pycryptodome.readthedocs.io/en/latest/src/cipher/pkcs1_v1_5.html
Custom User Model 기반으로 jQuery ajax 처리하는 전체 코드는 https://github.com/jsk005/PythonDjango/tree/main/customUserModel2 를 참조하면 도움될 것이다.
이 코드에서 RSACipher 클래스의 함수 코드 일부를 삭제했으나, 공부해서 충분히 해결할 수 있을 것으로 본다.
'파이썬 > Django' 카테고리의 다른 글
Django REST Framework 입문 (0) | 2022.03.06 |
---|---|
Django 사용자 인증 성공후 Redirection 처리 (0) | 2022.02.05 |
Django default Form-based Login, Register (0) | 2022.01.31 |
Django Custom User Model - 회원가입, 로그인 (2) | 2022.01.29 |
Django, squash migrations (0) | 2022.01.26 |