系列文章目录





文章目录

  • 系列文章目录
  • 前言
  • 一、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>

前后端加解密成功

js封装rsa加密算法 js rsa加密算法_Data


参考文献

1.https://www.jianshu.com/p/ff2b538a77e2 2.http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 3.