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 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__)
|
||||
|
||||
|
@ -13,7 +13,7 @@ logger = get_logger(__name__)
|
|||
class EncryptedField(forms.CharField):
|
||||
def to_python(self, value):
|
||||
value = super().to_python(value)
|
||||
return rsa_decrypt_by_session_pkey(value)
|
||||
return decrypt_password(value)
|
||||
|
||||
|
||||
class UserLoginForm(forms.Form):
|
||||
|
|
|
@ -56,6 +56,7 @@ def authenticate(request=None, **credentials):
|
|||
|
||||
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):
|
||||
continue
|
||||
|
||||
|
|
|
@ -241,6 +241,8 @@
|
|||
</body>
|
||||
{% 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/cryptojs/crypto-js.min.js"></script>
|
||||
<script type="text/javascript" src="/static/js/plugins/buffer/buffer.min.js"></script>
|
||||
<script>
|
||||
function doLogin() {
|
||||
//公钥加密
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
from rest_framework import serializers
|
||||
|
||||
from common.utils import rsa_decrypt_by_session_pkey
|
||||
from common.utils import decrypt_password
|
||||
|
||||
__all__ = [
|
||||
'ReadableHiddenField', 'EncryptedField'
|
||||
|
@ -29,4 +29,4 @@ class ReadableHiddenField(serializers.HiddenField):
|
|||
class EncryptedField(serializers.CharField):
|
||||
def to_internal_value(self, 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
|
||||
|
||||
try:
|
||||
value= rsa_decrypt(value, private_key)
|
||||
value = rsa_decrypt(value, private_key)
|
||||
except Exception as e:
|
||||
logging.error('Decrypt field error: {}'.format(e))
|
||||
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()
|
||||
|
|
|
@ -1502,18 +1502,89 @@ function getStatusIcon(status, mapping, title) {
|
|||
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) {
|
||||
if (!password) {
|
||||
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('"', '')
|
||||
var rsaPublicKey = atob(rsaPublicKeyText)
|
||||
var jsencrypt = new JSEncrypt(); //加密对象
|
||||
jsencrypt.setPublicKey(rsaPublicKey); // 设置密钥
|
||||
var value = jsencrypt.encrypt(password); //加密
|
||||
return value
|
||||
const rsaPublicKey = atob(rsaPublicKeyText)
|
||||
const keyCipher = rsaEncrypt(aesKey, rsaPublicKey)
|
||||
const passwordCipher = aesEncrypt(password, aesKey)
|
||||
return `${keyCipher}:${passwordCipher}`
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
|
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