系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、RSA加密算法原理
- 二、使用步骤
- 1.引入库[rsa加密算法库]
- 2.使用rsa库生成rsa加密算法公私钥
- 3.后端控制器文件
- 三.前端怎么使用RSA加密算法
- 3.1 引入库jsencrpt.js
- 参考文献
前言
RSA是目前使用最广泛的公钥密码体制之一。它是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法的安全性基于RSA问题的困难性,也就是基于大整数因子分解的困难性上。但是RSA问题不会比因子分解问题更加困难,也就是说,在没有解决因子分解问题的情况下可能解决RSA问题,因此RSA算法并不是完全基于大整数因子分解的困难性上的。
一、RSA加密算法原理
1976年以前,所有的加密方法都是同一种模式:
(1)甲方选择某一种加密规则,对信息进行加密;
(2)乙方使用同一种规则,对信息进行解密。
由于加密和解密使用同样规则(简称"密钥"),这被称为"对称加密算法"(Symmetric-key algorithm)。
这种加密模式有一个最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递密钥,就成了最头疼的问题。
1976年,两位美国计算机学家Whitfield Diffie 和 Martin Hellman,提出了一种崭新构思,可以在不直接传递密钥的情况下,完成解密。这被称为"Diffie-Hellman密钥交换算法"。这个算法启发了其他科学家。人们认识到,加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递密钥。
这种新的加密模式被称为"非对称加密算法"。
(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。
如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。
这种算法非常可靠,密钥越长,它就越难根据已经披露的文献,目前被的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。
二、使用步骤
1.引入库[rsa加密算法库]
windows安装
pip install pycryptodomex
linux下安装:
pip install pycryptodome
2.使用rsa库生成rsa加密算法公私钥
def create_rsa_key(password="123456"):
"""
创建RSA密钥
步骤说明:
1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
2、生成 1024/2048 位的 RSA 密钥
3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
4、将私钥写入磁盘的文件。
5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
"""
key = RSA.generate(1024)
encrypted_key = key.exportKey(passphrase=password, pkcs=8,
protection="scryptAndAES128-CBC")
with open("./cert/rsa_private_key.pem", "wb") as f:
f.write(encrypted_key)
with open("./cert/rsa_public_key.pem", "wb") as f:
f.write(key.publickey().exportKey())
return
3.后端控制器文件
# 导入Falsk
import os
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_v1_5
import base64
from flask import Flask, render_template, session,request
from urllib import parse
app = Flask(__name__, static_folder='./static', template_folder='./templates') # 配置资源路径
rsa_public_file = './cert/rsa_public_key.pem'
rsa_private_file = './cert/rsa_private_key.pem'
# 设置session Key
app.config['SECRET_KEY'] = os.urandom(24)
@app.route('/login/index')
def login():
rsa_pubkey = getCertContent(rsa_public_file)
rsa_privkey = getCertContent(rsa_private_file)
session['rsa_pubkey'] = rsa_pubkey
session['rsa_privkey'] = rsa_privkey
return render_template('login/login.html',rsa_pubkey=rsa_pubkey,rsa_privkey=rsa_privkey)
@app.route('/login/hanleLogin', methods=['POST'])
def hanleLogin():
print('login......')
result = request.form
usr = result['usr']
password = result['password']
print(usr,password)
data = decrypt_data(password)
print(data)
return data
def create_rsa_key(password="123456"):
"""
创建RSA密钥
步骤说明:
1、从 Crypto.PublicKey 包中导入 RSA,创建一个密码
2、生成 1024/2048 位的 RSA 密钥
3、调用 RSA 密钥实例的 exportKey 方法,传入密码、使用的 PKCS 标准以及加密方案这三个参数。
4、将私钥写入磁盘的文件。
5、使用方法链调用 publickey 和 exportKey 方法生成公钥,写入磁盘上的文件。
"""
key = RSA.generate(1024)
encrypted_key = key.exportKey(passphrase=password, pkcs=8,
protection="scryptAndAES128-CBC")
with open("./cert/rsa_private_key.pem", "wb") as f:
f.write(encrypted_key)
with open("./cert/rsa_public_key.pem", "wb") as f:
f.write(key.publickey().exportKey())
return
def decrypt_data(inputdata, code="123456"):
# URLDecode
data = parse.unquote(inputdata)
# base64decode
data = base64.b64decode(data)
private_key = RSA.import_key(
open('./cert/rsa_private_key.pem').read(),
passphrase=code
)
# 使用 PKCS1_v1_5,不要用 PKCS1_OAEP
# 使用 PKCS1_OAEP 的话,前端 jsencrypt.js 加密的数据解密不了
cipher_rsa = PKCS1_v1_5.new(private_key)
# 当解密失败,会返回 sentinel
sentinel = None
ret = cipher_rsa.decrypt(data, sentinel)
return ret
def getCertContent(filePath):
with open(filePath,'r') as reader:
return reader.read()
if __name__ == '__main__':
# flask 应用提供了一个简易服务器,用于测试
app.run(host='127.0.0.1', port=5000, debug=True)
三.前端怎么使用RSA加密算法
3.1 引入库jsencrpt.js
<script type='text/javascript' src='https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.1.0/jsencrypt.js'></script>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel="stylesheet" type="text/css" href = "{{ url_for('static', filename = 'css/login.css') }}"/>
</head>
<body>
<div class="box">
<h1>登录</h1>
<form method="post" action="/login/hanleLogin" id="form">
<input type="hidden" id="rsa_pubkey" value="{{rsa_pubkey}}"/>
<div>
<input type="text" name="user" placeholder="请输入用户名" id="usr"/>
</div>
<div>
<input type="password" name="password" placeholder="请输入密码" id ='password'/>
</div>
<input type="submit" value="登录" onclick="return false" id="loginBtn"/>
</form>
</div>
</body>
</html>
<!--引入jsencrypt.js-->
<!--<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.1.0/jsencrypt.js"></script>-->
<script src=""></script>
<!--引入axios-->
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
function encrypt(publicKey,text) {
let encryptor = new JSEncrypt()
encryptor.setPublicKey(publicKey)
console.log(encryptor);
return encryptor.encrypt(text)
}
$('#loginBtn').click(function(){
var usr = $('#usr').val();
var password = $('#password').val();
var publicKey = $('#rsa_pubkey').val();
enCryPassword = encrypt(publicKey,password);
var formData = new FormData();
formData.append('usr',usr)
formData.append('password',enCryPassword);
console.log(formData);
$.ajax({
url:'/login/hanleLogin',
type:'post',
data:formData,
processData: false,
contentType: false,
success:function(result){
console.log(result);
},
error:function(err){
console.log(err);
}
});
});
</script>
前后端加解密成功
参考文献
1.https://www.jianshu.com/p/ff2b538a77e2 2.http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 3.