mirror of https://github.com/jumpserver/jumpserver
perf: 优化加密 (#8206)
* perf: 优化加密 * perf: 优化加密 * perf: 优化加密传输 Co-authored-by: ibuler <ibuler@qq.com>pull/8217/head
parent
b44fa64994
commit
aff5b0035d
|
@ -5,7 +5,7 @@ from django.conf import settings
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from captcha.fields import CaptchaField, CaptchaTextInput
|
from captcha.fields import CaptchaField, CaptchaTextInput
|
||||||
|
|
||||||
from common.utils import get_logger, rsa_decrypt_by_session_pkey
|
from common.utils import get_logger, decrypt_password
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ logger = get_logger(__name__)
|
||||||
class EncryptedField(forms.CharField):
|
class EncryptedField(forms.CharField):
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
value = super().to_python(value)
|
value = super().to_python(value)
|
||||||
return rsa_decrypt_by_session_pkey(value)
|
return decrypt_password(value)
|
||||||
|
|
||||||
|
|
||||||
class UserLoginForm(forms.Form):
|
class UserLoginForm(forms.Form):
|
||||||
|
|
|
@ -56,6 +56,7 @@ def authenticate(request=None, **credentials):
|
||||||
|
|
||||||
for backend, backend_path in _get_backends(return_tuples=True):
|
for backend, backend_path in _get_backends(return_tuples=True):
|
||||||
# 检查用户名是否允许认证 (预先检查,不浪费认证时间)
|
# 检查用户名是否允许认证 (预先检查,不浪费认证时间)
|
||||||
|
logger.info('Try using auth backend: {}'.format(str(backend)))
|
||||||
if not backend.username_allow_authenticate(username):
|
if not backend.username_allow_authenticate(username):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -241,6 +241,8 @@
|
||||||
</body>
|
</body>
|
||||||
{% include '_foot_js.html' %}
|
{% include '_foot_js.html' %}
|
||||||
<script type="text/javascript" src="/static/js/plugins/jsencrypt/jsencrypt.min.js"></script>
|
<script type="text/javascript" src="/static/js/plugins/jsencrypt/jsencrypt.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/static/js/plugins/cryptojs/crypto-js.min.js"></script>
|
||||||
|
<script type="text/javascript" src="/static/js/plugins/buffer/buffer.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function doLogin() {
|
function doLogin() {
|
||||||
//公钥加密
|
//公钥加密
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from common.utils import rsa_decrypt_by_session_pkey
|
from common.utils import decrypt_password
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'ReadableHiddenField', 'EncryptedField'
|
'ReadableHiddenField', 'EncryptedField'
|
||||||
|
@ -29,4 +29,4 @@ class ReadableHiddenField(serializers.HiddenField):
|
||||||
class EncryptedField(serializers.CharField):
|
class EncryptedField(serializers.CharField):
|
||||||
def to_internal_value(self, value):
|
def to_internal_value(self, value):
|
||||||
value = super().to_internal_value(value)
|
value = super().to_internal_value(value)
|
||||||
return rsa_decrypt_by_session_pkey(value)
|
return decrypt_password(value)
|
||||||
|
|
|
@ -241,10 +241,21 @@ def rsa_decrypt_by_session_pkey(value):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
try:
|
try:
|
||||||
value= rsa_decrypt(value, private_key)
|
value = rsa_decrypt(value, private_key)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error('Decrypt field error: {}'.format(e))
|
logging.error('Decrypt field error: {}'.format(e))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def decrypt_password(value):
|
||||||
|
cipher = value.split(':')
|
||||||
|
if len(cipher) != 2:
|
||||||
|
return value
|
||||||
|
key_cipher, password_cipher = cipher
|
||||||
|
aes_key = rsa_decrypt_by_session_pkey(key_cipher)
|
||||||
|
aes = get_aes_crypto(aes_key, 'ECB')
|
||||||
|
password = aes.decrypt(password_cipher)
|
||||||
|
return password
|
||||||
|
|
||||||
|
|
||||||
crypto = Crypto()
|
crypto = Crypto()
|
||||||
|
|
|
@ -1502,18 +1502,89 @@ function getStatusIcon(status, mapping, title) {
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fillKey(key) {
|
||||||
|
let keySize = 128
|
||||||
|
// 如果超过 key 16 位, 最大取 32 位,需要更改填充
|
||||||
|
if (key.length > 16) {
|
||||||
|
key = key.slice(0, 32)
|
||||||
|
keySize = keySize * 2
|
||||||
|
}
|
||||||
|
const filledKeyLength = keySize / 8
|
||||||
|
if (key.length >= filledKeyLength) {
|
||||||
|
return key.slice(0, filledKeyLength)
|
||||||
|
}
|
||||||
|
const filledKey = Buffer.alloc(keySize / 8)
|
||||||
|
const keys = Buffer.from(key)
|
||||||
|
for (let i = 0; i < keys.length; i++) {
|
||||||
|
filledKey[i] = keys[i]
|
||||||
|
}
|
||||||
|
return filledKey
|
||||||
|
}
|
||||||
|
|
||||||
|
function aesEncrypt(text, originKey) {
|
||||||
|
const key = CryptoJS.enc.Utf8.parse(fillKey(originKey));
|
||||||
|
return CryptoJS.AES.encrypt(text, key, {
|
||||||
|
mode: CryptoJS.mode.ECB,
|
||||||
|
padding: CryptoJS.pad.ZeroPadding
|
||||||
|
}).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function rsaEncrypt(text, pubKey) {
|
||||||
|
if (!text) {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
const jsEncrypt = new JSEncrypt();
|
||||||
|
jsEncrypt.setPublicKey(pubKey);
|
||||||
|
return jsEncrypt.encrypt(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rsaDecrypt(cipher, pkey) {
|
||||||
|
const jsEncrypt = new JSEncrypt();
|
||||||
|
jsEncrypt.setPrivateKey(pkey);
|
||||||
|
return jsEncrypt.decrypt(cipher)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
window.rsaEncrypt = rsaEncrypt
|
||||||
|
window.rsaDecrypt = rsaDecrypt
|
||||||
|
|
||||||
function encryptPassword(password) {
|
function encryptPassword(password) {
|
||||||
if (!password) {
|
if (!password) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
var rsaPublicKeyText = getCookie('jms_public_key')
|
const aesKey = (Math.random() + 1).toString(36).substring(2)
|
||||||
|
// public key 是 base64 存储的
|
||||||
|
const rsaPublicKeyText = getCookie('jms_public_key')
|
||||||
.replaceAll('"', '')
|
.replaceAll('"', '')
|
||||||
var rsaPublicKey = atob(rsaPublicKeyText)
|
const rsaPublicKey = atob(rsaPublicKeyText)
|
||||||
var jsencrypt = new JSEncrypt(); //加密对象
|
const keyCipher = rsaEncrypt(aesKey, rsaPublicKey)
|
||||||
jsencrypt.setPublicKey(rsaPublicKey); // 设置密钥
|
const passwordCipher = aesEncrypt(password, aesKey)
|
||||||
var value = jsencrypt.encrypt(password); //加密
|
return `${keyCipher}:${passwordCipher}`
|
||||||
return value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function randomString(length) {
|
||||||
|
const characters ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
let result = '';
|
||||||
|
const charactersLength = characters.length;
|
||||||
|
for ( let i = 0; i < length; i++ ) {
|
||||||
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEncrypt() {
|
||||||
|
const radio = []
|
||||||
|
const len2 = []
|
||||||
|
for (let i=1;i<4096;i++) {
|
||||||
|
const password = randomString(i)
|
||||||
|
const cipher = encryptPassword(password)
|
||||||
|
len2.push([password.length, cipher.length])
|
||||||
|
radio.push(cipher.length/password.length)
|
||||||
|
}
|
||||||
|
return radio
|
||||||
|
}
|
||||||
|
|
||||||
window.encryptPassword = encryptPassword
|
window.encryptPassword = encryptPassword
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue