精华内容
下载资源
问答
  • rsa和aes混合加密
    2020-09-03 21:17:41

    基于RSA和AES混合加密实现的加解密小工具

    闲来无事,用python的tkinter开发了一个基于RSA和AES混合加密的小小工具。总结一下使用到的知识点。

    首先是核心的加解密部分。
    采用混合加密的原因,提到这个,就得先聊下RSA和AES各自的优缺点。
    RSA

    • 优点
      安全,基于大数因式分解。而目前已破解的最高位数为1024 bit,采用2048将会很安全。且仅涉及到一次密钥传输,及将公钥随加密工具传输给使用者,私钥保留于本地,公钥即使被别人获取也没有影响。

    • 缺点

      1. 加解密速度慢。由于都是大数计算,RSA最快的情况也比AES慢100倍。(快速幂取模运算,中国剩余定理CRT之后再写总结
      2. 一次性只能加解密小于公共模数N的数据。例如我们采用utf8编码的汉字,一个字按3 bytes也就是24 bit算,一个2048 bit的RSA key最多只能加密2048/24差不多80字。如果要加密更长的数据,就要分组加密,无疑又放大了加解密速度慢这个缺点。

    AES

    • 优点

      1. 加解密速度快。
      2. 分组长度和密钥长度设计灵活。
      3. 数据长度不限。
    • 缺点
      由于是对称加密算法,加密解密使用同一把密钥,所以密钥传输过程中存在密钥被人获取的安全隐患。

    所以一般采用RSA和对称加密算法结合的方式来弥补两种算法的缺点,即在保证密钥传输过程安全性的前提下,实现既快又多地加密数据。具体实现过程是:

    加密时:

    1. 随机生成一个会话密钥,或者叫过程密钥
    2. 用此会话密钥加密数据
    3. 用RSA公钥加密会话密钥
    4. 将加密的会话密钥与数据的密文拼装起来发送出去,也可以选择生成校验码一起拼装发送,以防止数据传输过程中被人篡改。

    解密时:

    1. 用RSA私钥解密会话密钥
    2. 使用会话密钥解密数据,如果有带校验码,此过程需要进行校验。

    上代码
    mycipher.py

    from Cryptodome.Cipher import AES, PKCS1_OAEP
    from Cryptodome.Random import get_random_bytes
    from Cryptodome.PublicKey import RSA
    
    AES_KEY_SIZE = 16
    BLOCK_SIZE = 16
    
    def generateRSAkey():
    	'''
    	生成长度为2048 bit的RSA公私钥,分别存放于两个文件中
    	'''
        key = RSA.generate(2048)
        private_key = key.export_key()
        file_out = open("private.pem", "wb")
        file_out.write(private_key)
        file_out.close()
    
        public_key = key.publickey().export_key()
        file_out = open("public.pem", "wb")
        file_out.write(public_key)
        file_out.close()
    
    
    class mycipher():
        def __init__(self, rsakey):
        	'''
        	根据参数来创建RSA加解密对象,加密时传参公钥,解密时传参私钥
        	'''
            self.rsakey = RSA.importKey(open(rsakey).read())
            self.cipher_rsa = PKCS1_OAEP.new(self.rsakey)
    
        def encrypt(self, data):
            if isinstance(data, str):
                data = data.encode('utf-8')
            #随机生成一把会话密钥
            sessionkey = get_random_bytes(AES_KEY_SIZE)
            #用RSA公钥加密会话密钥
            encsessionkey = self.cipher_rsa.encrypt(sessionkey)
            cipher_aes = AES.new(sessionkey, AES.MODE_EAX)
            #采用AES EAX模式加密并生成校验tag
            ciphertext, tag = cipher_aes.encrypt_and_digest(data)
            #拼装密文会话密钥+nonce+tag+数据密文,此处nonce可以理解为IV
            return encsessionkey + cipher_aes.nonce + tag + ciphertext
    
        def decrypt(self, data):
            if isinstance(data, str):
                data = bytes.fromhex(data)
            pos = 0
            encsessionkey = data[pos:self.rsakey.size_in_bytes()]
            pos += self.rsakey.size_in_bytes()
            nonce = data[pos:pos + AES_KEY_SIZE]
            pos += AES_KEY_SIZE
            tag = data[pos:pos + 16]
            pos += 16
            ciphertext = data[pos:]
            sessionkey = self.cipher_rsa.decrypt(encsessionkey)
            cipher_aes = AES.new(sessionkey, AES.MODE_EAX, nonce)
            plaintext = cipher_aes.decrypt_and_verify(ciphertext, tag)
            plaintext = plaintext.decode('utf-8')
            return plaintext
    

    接下去是图形界面部分,随便写的一个很丑的界面,需要总结记录的不多,直接上代码。

    window.py

    from tkinter import *
    import tkinter.font as tkFont
    
    
    class window():
        win = None
    
        def __init__(self, title='useless tool'):
            self.win = Tk()
            self.win.title(title)
    
        def createtext(self, text=None, state=NORMAL):
            state = DISABLED if state == 0 else NORMAL
            Label(self.win, text=text).pack(anchor='w')
            #Enable虽然是输入框,但是只支持单行,不美观,而Text控件可支持多行输入。
            e = Text(self.win, width=100, height=20, state=state)
            e.pack()
            return e
    
        def createbutton(self, text='Button', command=None):
            f = tkFont.Font(size=30)
            b = Button(self.win, text=text, command=command, width=20, height=2, font=f, background='#E6E6FA')
            b.pack()
            return b
    
        def show(self):
            self.win.mainloop()
    
    

    加密工具
    此工具随RSA公钥文件public.pem一起发送给使用者。

    encrypt.py

    from window import window
    from mycipher import mycipher
    
    
    def encrypt():
        mc = mycipher('public.pem')
        plaintext = plainbox.get('0.0', 'end')[:-1]
        if len(plaintext) > 0:
            ciphertext = mc.encrypt(plaintext)
            cipherbox.delete('0.0', 'end')
            cipherbox.insert('0.0', ciphertext.hex())
    
    
    if __name__ == '__main__':
        a = window()
        plainbox = a.createtext('请输入要加密的内容')
        cipherbox = a.createtext('这是你的密文', state=1)
        b = a.createbutton('加密', command=encrypt)
        a.show()
    
    

    解密工具

    自己留着。

    from window import window
    from mycipher import mycipher
    
    
    def decrypt():
        mc = mycipher('private.pem')
        plaintext = mc.decrypt(cipherbox.get('0.0', 'end')[:-1])
        plainbox.delete('0.0', 'end')
        plainbox.insert('0.0', plaintext)
    
    
    if __name__ == '__main__':
        a = window()
        cipherbox = a.createtext('请输入要解密的内容')
        plainbox = a.createtext('这是你的明文', state=1)
        b = a.createbutton('解密', command=decrypt)
        a.show()
    
    
    更多相关内容
  • RSA和AES混合加密demo

    2017-11-29 18:20:10
    RSA和AES混合加密demo
  • RSA+AES混合加密-JavaWeb

    千次阅读 2021-05-06 11:36:11
    RSA+AES混合加密时,AES用于给传输的数据加密,然后通过RSAAES的秘钥加密,所以接收到数据后,就需要先解密得到AES的秘钥,然后通过AES秘钥再去解密得到数据。 下面简单说下demo中加密解密的

    一、前言

    RSA与AES加密的详细介绍这里就不写了,网上很多博客,这里就只是简单说明一下:

    • AES:属于对称加密,通过一个公共的秘钥,实现加密解密;
    • RSA:非对称加密,需要生成一个公钥、一个私钥,这两个秘钥使用时,一个用来加密时,那么就需要另一个秘钥进行解密,公钥一般提供给客户端。

    二、整体构思

    RSA+AES的混合加密时,AES用于给传输的数据加密,然后通过RSA给AES的秘钥加密,所以接收到数据后,就需要先解密得到AES的秘钥,然后通过AES秘钥再去解密得到数据。
    下面简单说下demo中加密解密的实现过程:

    1. 前后端各自生成自己的RSA公私密钥(这就必须确保双方的RSA算法要匹配,不然双方就无法正常解密)
    2. 当访问项目首页时,前端生成RSA秘钥,并存放在window对象中的localStorage
    3. 页面发起请求获取服务端的RSA公钥,服务端收到请求后生成RSA公司秘钥,并将秘钥放入session,所以每次建立会话连接时都是不一样的秘钥,然后将公钥返回给前端页面
    4. 页面接收到服务端的RSA公钥后,存入window对象,然后用服务端RSA公钥加密前端的RSA公钥发送给服务端
    5. 服务端收到前端发过来的请求后,通过自己的私钥解密数据,从而得到前端的公钥,并存入session。

    这里面提到的存储秘钥的方式只是在demo中作为演示使用,可以采用更合理、更安全的方式是实现!

    这样,前后端都拥有的对方RSA的公钥,后面在同一个会话中具体的请求数据时,每次各自都会生成新的AES秘钥(AES的算法也需要前后端能匹配上),RSA的秘钥则在响应位置去取就可以了。
    在这里插入图片描述
    在这里插入图片描述

    三、主要代码

    1、服务端

    两个加密解密工具类,里面部分有使用第三方jar(hutool-all.jar)。

    • AESUtil
    package com.lr.demo.util;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.UnsupportedEncodingException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Arrays;
    
    public class AESUtil {
        private static final String KEY_ALGORITHM = "AES";
        private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法
    
        public static String getKey(int len){
            if(len % 16 != 0){
                System.out.println("长度要为16的整数倍");
                return null;
            }
    
            char[] chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
            char[] uuid = new char[len];
    
            if (len > 0) {
                for (int i = 0; i < len; i++) {
                    int x = (int) (Math.random() * (len - 0 + 1) + 0);
                    uuid[i] = chars[x % chars.length];
                }
            }
    
            return new String(uuid);
        }
    
    
        public static String byteToHexString(byte[] bytes){
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < bytes.length; i++) {
                String strHex=Integer.toHexString(bytes[i]);
                if(strHex.length() > 3){
                    sb.append(strHex.substring(6));
                } else {
                    if(strHex.length() < 2){
                        sb.append("0" + strHex);
                    } else {
                        sb.append(strHex);
                    }
                }
            }
            return  sb.toString();
        }
    
        /**
         * AES 加密操作
         *
         * @param content 待加密内容
         * @param key 加密密码
         * @return 返回Base64转码后的加密数据
         */
        public static String encrypt(String content, String key) {
            try {
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
    
                byte[] byteContent = content.getBytes("utf-8");
    
                cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));// 初始化为加密模式的密码器
    
                byte[] result = cipher.doFinal(byteContent);// 加密
    
                return org.apache.commons.codec.binary.Base64.encodeBase64String(result);//通过Base64转码返回
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * AES 解密操作
         *
         * @param content
         * @param key
         * @return
         */
        public static String decrypt(String content, String key) {
    
            try {
                //实例化
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
    
                //使用密钥初始化,设置为解密模式
                cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
    
                //执行操作
                byte[] result = cipher.doFinal(org.apache.commons.codec.binary.Base64.decodeBase64(content));
    
                return new String(result, "utf-8");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        private static SecretKeySpec getSecretKey(final String key) throws UnsupportedEncodingException {
            //返回生成指定算法密钥生成器的 KeyGenerator 对象
            KeyGenerator kg = null;
    
            try {
                kg = KeyGenerator.getInstance(KEY_ALGORITHM);
    
                //AES 要求密钥长度为 128
                kg.init(128, new SecureRandom(key.getBytes()));
    
                //生成一个密钥
                SecretKey secretKey = kg.generateKey();
    
                return new SecretKeySpec(Arrays.copyOf(key.getBytes("utf-8"), 16), KEY_ALGORITHM);// 转换为AES专用密钥
            } catch (NoSuchAlgorithmException ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
    }
    
    
    • RSAUtil
    package com.lr.demo.util;
    
    import cn.hutool.crypto.SecureUtil;
    import cn.hutool.crypto.asymmetric.KeyType;
    import cn.hutool.crypto.asymmetric.RSA;
    import org.springframework.util.Base64Utils;
    
    import java.io.UnsupportedEncodingException;
    import java.security.Key;
    import java.security.KeyPair;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.util.HashMap;
    import java.util.Map;
    
    public class RSAUtil {
    
        public static final String PB_KEY = "pb_key";
        public static final String PR_KEY = "pr_key";
    
        public static final String CLI_PB_KEY = "cli_pb_key";
    
        /**
         * 获取公私秘钥对
         * @return
         */
        public static Map<String, Key> getRSAKey(){
            KeyPair pair = SecureUtil.generateKeyPair("RSA");
            PrivateKey privateKey = pair.getPrivate();
            PublicKey publicKey = pair.getPublic();
    
            Map<String, Key> keys = new HashMap<>();
            keys.put(PR_KEY,privateKey);
            keys.put(PB_KEY,publicKey);
    
            return keys;
        }
    
        /**
         * 公钥加密
         * @param pbKey
         * @param content
         * @return
         */
        public static String encByPbKey(String pbKey,String content){
            try {
                byte[] bytes = Base64Utils.decode(pbKey.getBytes("UTF-8"));
                RSA rsa = new RSA(null,bytes);
                byte[] enc = rsa.encrypt(content.getBytes("UTF-8"), KeyType.PublicKey);
                String s = new String(Base64Utils.encode(enc));
                return s;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 公钥加密
         * @param pbKey
         * @param content
         * @return
         */
        public static String encByPbKey(PublicKey pbKey,String content){
            try {
                RSA rsa = new RSA(null,pbKey);
                byte[] enc = rsa.encrypt(content.getBytes("UTF-8"), KeyType.PublicKey);
                String s = new String(Base64Utils.encode(enc));
                return s;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 私钥解密
         * @param prKey
         * @param content
         * @return
         */
        public static String dencByPrKey(String prKey,String content){
            try {
                byte[] bytes = Base64Utils.decode(prKey.getBytes("UTF-8"));
                RSA rsa = new RSA(bytes,null);
                byte[] denc = rsa.decrypt(Base64Utils.decode(content.getBytes("UTF-8")), KeyType.PrivateKey);
                String s = new String(Base64Utils.encode(denc));
                return s;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 私钥解密
         * @param prKey
         * @param content
         * @return
         */
        public static String dencByPrKey(PrivateKey prKey,String content){
            try {
                RSA rsa = new RSA(prKey,null);
                byte[] denc = rsa.decrypt(Base64Utils.decode(content.getBytes("UTF-8")), KeyType.PrivateKey);
                String s = new String(denc);
                return s;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    
    

    l两个Controller,一个是初始化是秘钥交换的,一个用于测试

    package com.lr.demo.controller;
    
    import com.lr.demo.commons.Result;
    import com.lr.demo.util.RSAUtil;
    import org.springframework.util.Base64Utils;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpSession;
    import java.security.Key;
    import java.security.PrivateKey;
    import java.util.List;
    import java.util.Map;
    
    @RestController
    @RequestMapping("secret")
    public class SecretController {
    
        /**
         * 返回服务端的RSA公钥
         * @param session
         * @return
         */
        @RequestMapping("getKey")
        public Result getKey(HttpSession session){
            Map<String, Key> rsaKey = (Map<String, Key>) session.getAttribute("keys");
            if(rsaKey == null){
                rsaKey = RSAUtil.getRSAKey();
                session.setAttribute("keys",rsaKey);
            }
    
            byte[] encode = Base64Utils.encode(rsaKey.get(RSAUtil.PB_KEY).getEncoded());
            return Result.success(new String(encode));
    
        }
    
        /**
         * 分段解密发送过来的客户端RSA公钥
         * @param map
         * @param session
         * @return
         */
        @RequestMapping("acceptKey")
        public Result acceptKey(@RequestBody Map<String,Object> map, HttpSession session){
    
            List<String> clientKeys = (List<String>) map.get("clientKey");
            System.out.println("clientKey:" + clientKeys);
            Map<String, Key> rsaKey = (Map<String, Key>) session.getAttribute("keys");
    
            String cli_key = "";
            if(clientKeys != null){
                for (String item : clientKeys) {
                    cli_key += RSAUtil.dencByPrKey((PrivateKey) rsaKey.get(RSAUtil.PR_KEY), item);
                }
            }
            session.setAttribute(RSAUtil.CLI_PB_KEY,cli_key);
            System.out.println("解密后客户端公钥:" + cli_key);
            return Result.success();
        }
    
    }
    
    
    package com.lr.demo.controller;
    
    
    import com.alibaba.fastjson.JSON;
    import com.lr.demo.commons.Constant;
    import com.lr.demo.commons.Result;
    import com.lr.demo.util.AESUtil;
    import com.lr.demo.util.RSAUtil;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.security.Key;
    import java.security.PrivateKey;
    import java.util.HashMap;
    import java.util.Map;
    
    @RestController
    @RequestMapping("sys")
    public class SystemController {
    
        @RequestMapping("login")
        public Result login(@RequestBody String data, HttpServletRequest request,HttpServletResponse response){
            String plaintext = dencrypt(request, data);
            return Result.success(encrypt("登录成功啦",response));
        }
    
    
        private String dencrypt(HttpServletRequest request,String data){
            // 从session中获取服务端RSA的私钥
            HttpSession session = request.getSession();
            Map<String, Key> rsaKey = (Map<String, Key>) session.getAttribute("keys");
    
            HashMap<String,String> hashMap = JSON.parseObject(data, HashMap.class);
            // 获取客户端发送的加密数据
            String enc_data = hashMap.get(Constant.ENCRYPT_DATA);
            System.out.println("获取请求数据---->:" + enc_data);
            // 获取发送过来的AES秘钥
            String enc_aes_key = request.getHeader(Constant.ENCRYPT_AES_KEY);
            // 解密AES秘钥
            String aes_key = RSAUtil.dencByPrKey((PrivateKey) rsaKey.get(RSAUtil.PR_KEY), enc_aes_key);
            // AES解密
            String plaintext = AESUtil.decrypt(enc_data, aes_key);
    
            System.out.println("解密数据---->:" + plaintext);
            return plaintext;
        }
    
        public Map<String, String> encrypt(String data, HttpServletResponse response){
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            HttpSession session = request.getSession();
            String cliKey = (String) session.getAttribute(RSAUtil.CLI_PB_KEY); // 获取客户端RSA公钥
            String aesKey = AESUtil.getKey(16); // 获取AES秘钥
            // RSA加密AES秘钥
            String encrypt_aes_key = RSAUtil.encByPbKey(cliKey, aesKey);
            // AES加密返回数据
            String encrypt_data = AESUtil.encrypt(data, aesKey);
            // 添加响应头(AES秘钥)
            response.addHeader(Constant.ENCRYPT_AES_KEY, encrypt_aes_key);
            Map<String,String> map = new HashMap<>();
            map.put(Constant.ENCRYPT_DATA,encrypt_data);
            return map;
        }
    }
    
    

    2、前端

    前端涉及的文件较多,这里就只展示下页面,其余详细代码可以下载源码后查看。

    • aes_v1.0.js:AES加解密
    • rsa.js、crypto-js.js:RSA加解密
    • demo.js:封装的函数

    index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
        <script src="static/js/aes_v1.0.js"></script> 
        <script src="static/js/rsa.js"></script>
        <script src="static/js/crypto-js.js"></script>
        <script src="static/js/demo.js"></script>
        <script src="static/js/jquery-3.5.1.js"></script>
      </head>
      <body>
    
      <form action="<%=request.getContextPath()%>/sys/login" id="loginForm">
          <input type="text" name="username" value="">
          <input type="password" name="password" value="">
          <input type="button" value="登录" id="loginBtn">
      </form>
    
      <script>
          // 首页加载时,秘钥生成和交换
          getRsaKeys(f)
      </script>
      
      <script>
    
          function getFormJson(formJqueryObj) {
              var o = {};
              var a = formJqueryObj.serializeArray();
              $.each(a, function () {
                  if (o[this.name]) {
                      if (!o[this.name].push) {
                          o[this.name] = [o[this.name]];
                      }
                      o[this.name].push(this.value || '');
                  } else {
                      o[this.name] = this.value || '';
                  }
              });
              return o;
          }
    
    
          $('#loginBtn').click(function () {
              var json = getFormJson($('#loginForm'))
              // demo.js封装的函数
              request(json,'<%=request.getContextPath()%>/sys/login',function (res) {
                  console.log(res)
              })
          })
      </script>
      </body>
    </html>
    
    

    四、测试

    启动项目,打开首页:
    在这里插入图片描述
    服务端日志:
    在这里插入图片描述

    当交换完秘钥后,进行登录测试:
    在这里插入图片描述
    服务端就收时的日志输出:
    在这里插入图片描述
    响应后页面的输出:
    在这里插入图片描述
    在这里插入图片描述
    以上就是一个简单的demo,源码点击下载

    展开全文
  • RSA加密这是一种非对称加密算法,密钥分为公钥和私钥。通常私钥长度有512bit,1024bit,2048bit,4096bit,长度越长,越安全,但是生成密钥越慢,加...AES加密这是一种对称加密算法,加密和解密公用同一密钥。密钥...

    RSA加密

    这是一种非对称加密算法,密钥分为公钥和私钥。通常私钥长度有512bit,1024bit,2048bit,4096bit,长度越长,越安全,但是生成密钥越慢,加解密也越耗时。一般公钥用来加密数据,私钥用来解密数据,并且为防止有人冒充发送密文,私钥又可以负责签名,公钥负责验证。公钥可以分发给其他系统,但是私钥一般保存在唯一的系统中。

    AES加密

    这是一种对称加密算法,加密和解密公用同一密钥。密钥最长只有256个bit,执行速度快,易于硬件实现。通常发送方使用密钥加密数据后会使用口令对密钥进行加密,然后把密文和加密后的密钥一同发送给接收方,接收方接收到数据后首先使用口令对密钥进行解密,在使用密钥对密文进行解密。

    以上两种加密方式都有各自的特点,在互联网领域有着广泛的应用,我们需要根据不同的场景使用不同的加密解密方案。

    一般需要加密传输的时候存在以下两种场景:

    客户端发送加密数据,服务端解密后返回明文:

    例如用户在客户端提交个人信息时,客户端把个人信息加密后发送给服务端,服务端再返回code或者提交成功的提示

    客户端发送加密数据,服务端解密后同样返回密文

    例如用户登录时,客户端发送加密后的账号密码,服务端解密后生成对应的token,并且对token进行加密,客户端收到返回的token再对其进行解密

    如何在python实现RSA?

    可以直接用python的rsa库

    import rsa

    (pubkey, privkey) = rsa.newkeys(1024)

    print('公钥:\n%s' % pubkey)

    print('私钥:\n%s' % privkey)

    message = 'hello'

    encrypt_text = rsa.encrypt(message.encode(), pubkey)

    print('加密后的密文:\n%s' % encrypt_text)

    decrypt_text = rsa.decrypt(encrypt_text, privkey)

    print('解密后的明文:\n%s' % decrypt_text)

    运行结果

    但是这只是简单的实现,中间省去了很多细节,这就导致我们以后跨语言加密解密的时候可能会出问题。比如java在实现RSA加密解密的时候有很多参数需要设置,如果java和python之间的参数不能保持一致,则会导致用java加密的密文用python解密不了,或者用python加密的密文用java解密不了。所以还是推荐使用可以设置更多参数的第三方RSA库。python的第三方RSA库有crypto、pycrypto和pycryptodome。crypto不推荐使用,已经停止维护了。可以使用pycrypto,不过我的电脑安装pycrypto会报错。

    错误信息

    提示我安装Microsoft Visual C++ 14.0,所以我直接用的pycryptodome,其实都差不多。

    Config配置类

    class Config:

    PUBLIC_KEY = '''

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDv/LnAoDkyewwjwqwgi9VSg51F

    +tUJ8cGwL6Rqdf5ZXrRCHI1KLjOxdFbzB81YjS76cOzezQRz2vuYDo7OvLfYSjFI

    fmukUxN+EliKkg0TwswylVroLBW9OKN70Zd62dc+gfkA3Vu8cDoRKzz6BKpo4yDo

    0D3FOsbNEj80opjmtQIDAQAB

    '''

    PRIVATE_KEY = '''

    MIICXAIBAAKBgQDv/LnAoDkyewwjwqwgi9VSg51F+tUJ8cGwL6Rqdf5ZXrRCHI1K

    LjOxdFbzB81YjS76cOzezQRz2vuYDo7OvLfYSjFIfmukUxN+EliKkg0TwswylVro

    LBW9OKN70Zd62dc+gfkA3Vu8cDoRKzz6BKpo4yDo0D3FOsbNEj80opjmtQIDAQAB

    AoGADuZtDgWkp3q2TT4X+8lSzFW5nQ+uzHhDI1JB7g43ZYsYvAYTy6hEs17ayyoP

    2NCjOw9p1Yd7IEpXVqCIw1M6QsfGdshy1NStsGpDHQYBBd8XiT8cWUaT/nmq5dEs

    i0wOITMZePLgI5/5pD4M6DIEJKskM+Rzlo47AiyRchL6pqECQQD+XAZNCl6R5wjI

    DrqW4v6Vw8mhdaPnQhPexmhHa1f9D7sA32A2H2N8M3dUDOwuG+DJhPkjVaQtFvT8

    mjDjSZTdAkEA8Yj4hncF/WnLTDSXmiWfpNwYwjfpjOj8e4/5rWHF1jWZMgl0l1AS

    Otna2dIbXp64dqsInITJTIDSQpbxuhrvuQJBAN9Ee6toLLa5KzYf55zGR13Ca9wz

    3NkDYVmsop/+E0/oXOdZK6SWTMcajeXTKgUXJ2r8M4vWgrOpcQXBeqQnVGkCQDYX

    e7j5bOD80Wemm5EM/fy4wd61ENvazbiKXNske17msAFRtsewSfTeFzIS6Mg++Yax

    9QLAhihY7T22ejo4kBkCQBdg2yKHQrmG+njGfLsdQG9MARFlnOfohoBFQTYdtrmf

    5JRNfwtPiis2YaoM2gP7z2qaunYbibDV5SYmtdD8GK0=

    '''

    RSA工具类

    import base64

    from Crypto.Cipher import PKCS1_OAEP

    from Crypto.Hash import SHA256

    from Crypto.PublicKey import RSA

    from Crypto.Signature import PKCS1_v1_5

    from app.config import Config

    class RSACipher():

    '''

    RSA加密、解密、签名、验签工具类

    '''

    def encrypt(self, key, text):

    '''

    加密方法

    :param key: 公钥

    :param text: 需要加密的明文

    :return: 加密后的密文

    '''

    public_key = RSA.importKey(base64.b64decode(key))

    cipher = PKCS1_OAEP.new(public_key, hashAlgo=SHA256)

    return base64.b64encode(cipher.encrypt(text.encode())).decode()

    def decrypt(self, key, text):

    '''

    解密方法

    :param key: 私钥

    :param text: 加密后的密文

    :return: 解密后的明文

    '''

    private_key = RSA.importKey(base64.b64decode(key))

    cipher = PKCS1_OAEP.new(private_key, hashAlgo=SHA256)

    return cipher.decrypt(base64.b64decode(text)).decode()

    def sign(self, key, text):

    '''

    签名方法

    :param key: 私钥

    :param text: 需要签名的文本

    :return: 签名信息

    '''

    private_key = RSA.importKey(base64.b64decode(key))

    hash_value = SHA256.new(bytes(text, encoding="utf-8"))

    signer = PKCS1_v1_5.new(private_key)

    signature = signer.sign(hash_value)

    return base64.b64encode(signature).decode()

    def verify(self, key, text, signature):

    '''

    验签方法

    :param key: 公钥

    :param text: 需要验签的文本

    :param signature: 签名信息

    :return: 验签结果

    '''

    public_key = RSA.importKey(base64.b64decode(key))

    hash_value = SHA256.new(bytes(text, encoding="utf-8"))

    verifier = PKCS1_v1_5.new(public_key)

    return verifier.verify(hash_value, base64.b64decode(signature))

    if __name__ == '__main__':

    text = 'hello'

    cipher = RSACipher()

    # 加密

    encrypt_text = cipher.encrypt(Config.PUBLIC_KEY, text)

    print('加密后:\n%s' % encrypt_text)

    # 签名

    signature = cipher.sign(Config.PRIVATE_KEY, text)

    print('签名:\n%s' % signature)

    # 解密

    decrypt_text = cipher.decrypt(Config.PRIVATE_KEY, encrypt_text)

    print('解密后:\n%s' % decrypt_text)

    # 验签

    result = cipher.verify(Config.PUBLIC_KEY, decrypt_text, signature)

    print('验签:\n%s' % result)

    运行结果:

    加密后:

    f/Ju3QYLvlhGd+EKxlH/MZQX9g2XQ8nkTq5zWP7sCnoQUmPZPAb1H8//j+2B9Uz7HdiUtys2wtk1eWsD7/TSsWz5XDWA/LFXcN0r4AdJnaI1HvLZ8625Ahh3YYia8DmW7j7IvhNDJIES1otlPKgfRb7srDr+p7x/YzrZTFp66PM=

    签名:

    N5CAgMhhNzTNeyjY8bCSxPOcrUL48ZIDz4LpJGuncAsDwn/sFYr2Tba57DZF2XoXXCLt+3A46Wk7O+758XmxIDmOlOzdIqBtq6X9Ya9W/1f8mR2igc1xTvfNGt5Eb5xLjmATEk6grFx0bzMd4SJg0p5ayEH4fyCrXMlCKarEsCs=

    解密后:

    hello

    验签:

    True

    签名有什么用?

    下面我们模拟两个场景

    第一个场景:客户端发送加密数据给服务端

    客户端使用公钥对数据进行加密

    客户端发送密文给服务器端

    服务端使用私钥进行解密

    第二个场景:服务端发送数据给客户端

    服务端使用私钥对数据进行签名

    服务器端发送签名和数据给客户端

    客户端使用公钥进行验签,如果验签出来的内容和数据一致,则证明消息是服务端回复的

    在第一个场景中,即使客户端发送的加密消息被截获,也不会造成泄密,因为只有服务端用私钥才能解密,而第二个场景中即使签名和数据都被截获,也没有危险性,因为只有服务端的私钥才能进行签名,所以即使知道消息内容也无法伪造带签名的回复给客户端,防止了消息的纂改。

    虽然上面的场景中防止了泄密和纂改的问题,但是仍然存在安全隐患。在第一个场景中虽然解决了泄密的问题,但是可以通过公钥加密假信息发送给服务端。而第二个场景中,虽然解决了纂改的问题但是造成了数据的泄露。所以我们可以改进一下验证的方式,客户端和服务端同时生成一套公钥私钥,并且把客户端的公钥和服务端的私钥进行交换。

    综合上面两个场景:客户端发送加密数据给服务端

    客户端使用服务端公钥进行加密,并且使用客户端私钥进行签名

    客户端发送密文和签名给服务端

    服务端使用服务端私钥进行解密,并使用客户端公钥进行验签,证明消息来自客户端

    服务端返回数据同理

    下面贴上改进后的代码:

    Config配置类

    class Config:

    CLIENT_PUBLIC_KEY = '''

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDv/LnAoDkyewwjwqwgi9VSg51F

    +tUJ8cGwL6Rqdf5ZXrRCHI1KLjOxdFbzB81YjS76cOzezQRz2vuYDo7OvLfYSjFI

    fmukUxN+EliKkg0TwswylVroLBW9OKN70Zd62dc+gfkA3Vu8cDoRKzz6BKpo4yDo

    0D3FOsbNEj80opjmtQIDAQAB

    '''

    CLIENT_PRIVATE_KEY = '''

    MIICXAIBAAKBgQDv/LnAoDkyewwjwqwgi9VSg51F+tUJ8cGwL6Rqdf5ZXrRCHI1K

    LjOxdFbzB81YjS76cOzezQRz2vuYDo7OvLfYSjFIfmukUxN+EliKkg0TwswylVro

    LBW9OKN70Zd62dc+gfkA3Vu8cDoRKzz6BKpo4yDo0D3FOsbNEj80opjmtQIDAQAB

    AoGADuZtDgWkp3q2TT4X+8lSzFW5nQ+uzHhDI1JB7g43ZYsYvAYTy6hEs17ayyoP

    2NCjOw9p1Yd7IEpXVqCIw1M6QsfGdshy1NStsGpDHQYBBd8XiT8cWUaT/nmq5dEs

    i0wOITMZePLgI5/5pD4M6DIEJKskM+Rzlo47AiyRchL6pqECQQD+XAZNCl6R5wjI

    DrqW4v6Vw8mhdaPnQhPexmhHa1f9D7sA32A2H2N8M3dUDOwuG+DJhPkjVaQtFvT8

    mjDjSZTdAkEA8Yj4hncF/WnLTDSXmiWfpNwYwjfpjOj8e4/5rWHF1jWZMgl0l1AS

    Otna2dIbXp64dqsInITJTIDSQpbxuhrvuQJBAN9Ee6toLLa5KzYf55zGR13Ca9wz

    3NkDYVmsop/+E0/oXOdZK6SWTMcajeXTKgUXJ2r8M4vWgrOpcQXBeqQnVGkCQDYX

    e7j5bOD80Wemm5EM/fy4wd61ENvazbiKXNske17msAFRtsewSfTeFzIS6Mg++Yax

    9QLAhihY7T22ejo4kBkCQBdg2yKHQrmG+njGfLsdQG9MARFlnOfohoBFQTYdtrmf

    5JRNfwtPiis2YaoM2gP7z2qaunYbibDV5SYmtdD8GK0=

    '''

    SERVER_PUBLIC_KEY = '''

    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDxpMZQCTykdwUcUzyHgd6Q79de

    4/F26bhIpOVCDpWNxlLQFdbGneTTQ1AJz/wwfNMgEPMnJvV3ZLrbqH9uV5W+8NG0

    UDaXyZYo8fXhfD7Aeret6/CgH1iZamzR4DfADCvT+V81cjeGIhJ1JSYfxGIsC4mM

    35TZ5p530ayOJ1KPHwIDAQAB

    '''

    SERVER_PRIVATE_KEY = '''

    MIICXQIBAAKBgQDxpMZQCTykdwUcUzyHgd6Q79de4/F26bhIpOVCDpWNxlLQFdbG

    neTTQ1AJz/wwfNMgEPMnJvV3ZLrbqH9uV5W+8NG0UDaXyZYo8fXhfD7Aeret6/Cg

    H1iZamzR4DfADCvT+V81cjeGIhJ1JSYfxGIsC4mM35TZ5p530ayOJ1KPHwIDAQAB

    AoGBAL8E8ZvNYXnleE3G4t9/41ARuOATMws8gOg0KeMJImI7t7U0vl6t7HixCnFn

    T8WIt2Du5Tg7DOo/35LK5Ul1xTHtYmQBdxTbg1WT89s3RWEvL4epHZQxzCQFJ1Pz

    zjDFifPNDEA7ZME7sx/E2qPDinAD+JHNELhtNMDq5rhPuYGRAkEA/W6mZCbDfrY9

    /qcbOe2s8ugeoDqoJueP7owfrut11KzvUn+e2rIBeDn1BZbWlYY5VDEq1nIKen+B

    0su4QUiiaQJBAPQXjC+YgyBzoEyMLPiA+eRC28zuwP2LXGJ1FNPZpCgnaJzF215H

    vhISwKX+b1/WZq3qBHyQnbE5zBHEIn5I5EcCQQC6X9k15dv3H4bP84xuOX/q0xFS

    vFBU7A5JW/sg5EAvO0502S21nxq9k8HBboA4ThFy/QWH1y4lkAelQfQq7oOhAkBh

    Jk4hU249KEgQr2nmrk7HTuT0t8IQJ7tpZHgZqXHwmV7FpuocqCk6QER0zMO/PTI4

    3f9TJKvescZK++lOoexZAkB0XNnpYA4fOMKhyKbcGvpqKLFb3e2ks5LbjgeAkETt

    dKipEh1RbiPrJeOwOChsx/51/cnVJrabE50AJV8AXM3e

    '''

    RSA工具类

    import base64

    from Crypto.Cipher import PKCS1_OAEP

    from Crypto.Hash import SHA256

    from Crypto.PublicKey import RSA

    from Crypto.Signature import PKCS1_v1_5

    from app.config import Config

    class RSACipher():

    """

    RSA加密、解密、签名、验签工具类

    """

    def encrypt(self, key, raw):

    """

    加密方法

    :param key: 公钥

    :param raw: 需要加密的明文 bytes

    :return: base64编码的密文 bytes

    """

    public_key = RSA.importKey(base64.b64decode(key))

    cipher = PKCS1_OAEP.new(public_key, hashAlgo=SHA256)

    return base64.b64encode(cipher.encrypt(raw))

    def decrypt(self, key, enc):

    """

    解密方法

    :param key: 私钥

    :param enc: base64编码的密文 bytes

    :return: 解密后的明文 bytes

    """

    private_key = RSA.importKey(base64.b64decode(key))

    cipher = PKCS1_OAEP.new(private_key, hashAlgo=SHA256)

    return cipher.decrypt(base64.b64decode(enc))

    def sign(self, key, text):

    """

    签名方法

    :param key: 私钥

    :param text: 需要签名的文本 bytes

    :return: base64编码的签名信息 bytes

    """

    private_key = RSA.importKey(base64.b64decode(key))

    hash_value = SHA256.new(text)

    signer = PKCS1_v1_5.new(private_key)

    signature = signer.sign(hash_value)

    return base64.b64encode(signature)

    def verify(self, key, text, signature):

    """

    验签方法

    :param key: 公钥

    :param text: 需要验签的文本 bytes

    :param signature: base64编码的签名信息 bytes

    :return: 验签结果 bool

    """

    public_key = RSA.importKey(base64.b64decode(key))

    hash_value = SHA256.new(text)

    verifier = PKCS1_v1_5.new(public_key)

    return verifier.verify(hash_value, base64.b64decode(signature))

    if __name__ == '__main__':

    # 客户端代码

    text = b'hello server!'

    cipher = RSACipher()

    # 使用服务端公钥加密

    encrypt_text = cipher.encrypt(Config.SERVER_PUBLIC_KEY, text)

    print('加密后:\n%s' % encrypt_text)

    # 使用客户端私钥签名

    signature = cipher.sign(Config.CLIENT_PRIVATE_KEY, encrypt_text)

    print('签名:\n%s' % signature)

    # 服务端代码

    # 使用客户端公钥验签

    result = cipher.verify(Config.CLIENT_PUBLIC_KEY, encrypt_text, signature)

    print('验签:\n%s' % result)

    # 使用服务端私钥解密

    decrypt_text = cipher.decrypt(Config.SERVER_PRIVATE_KEY, encrypt_text)

    print('解密后:\n%s' % decrypt_text)

    运行结果:

    加密后:

    b'miG43R3Xz5hyUntwfvToY96rhqgvsXzZGW6+VErgTdgs2Ew/wDlBlhjgpJQt3b13Rnq0m3sMydw7jly7/yRGW/eWaeOhuJRUQ6y1pGbvt3jIgnJvsj3XwT+S1Zah5Po87c51rQ7UamVmUvh4qFCZLzYdgXGfLLeknOTzVd+WIJo='

    签名:

    b'sG4qoMTccZOlrSzn6y16qGAVNtdBdnbduHPbNbEmCo+7Pe2AUg4VRK9VjG67Hqitwoa5AmHWe2M4DyolhEuuSYwrriYnSR2y6flBv0yb0G0CqJ4VODYVDlRrKTLLnTBnHoBeKNhqruir5JJ5cB9oE8XnE5rGI1yCPPhtBRjUXMM='

    验签:

    True

    解密后:

    b'hello server!'

    如何在python中实现AES加密?

    AES工具类

    import base64

    from Crypto.Cipher import AES

    from Crypto.Random import get_random_bytes

    class AESCipher:

    """

    AES加密、解密工具类

    """

    def __init__(self, key):

    self.key = key

    # 这里直接用key充当iv

    self.iv = key

    def encrypt(self, raw):

    """

    加密方法

    :param raw: 需要加密的密文 str

    :return: base64编码的密文 str

    """

    cipher = AES.new(self.key, AES.MODE_CBC, self.iv)

    return base64.b64encode(cipher.encrypt(self.__pad(raw).encode())).decode()

    def decrypt(self, enc):

    """

    解密方法

    :param enc: base64编码的密文 str

    :return: 解密后的明文 str

    """

    cipher = AES.new(self.key, AES.MODE_CBC, self.iv)

    return self.__unpad(cipher.decrypt(base64.b64decode(enc)).decode())

    def __pad(self, text):

    # 填充方法,加密内容必须为16字节的倍数

    text_length = len(text)

    amount_to_pad = AES.block_size - (text_length % AES.block_size)

    if amount_to_pad == 0:

    amount_to_pad = AES.block_size

    pad = chr(amount_to_pad)

    return text + pad * amount_to_pad

    def __unpad(self, text):

    # 截取填充的字符

    pad = ord(text[-1])

    return text[:-pad]

    if __name__ == '__main__':

    # 随机生成16位aes密钥

    cipher = AESCipher(get_random_bytes(16))

    text = "hello"

    encrypt = cipher.encrypt(text)

    print('加密后:\n%s' % encrypt)

    decrypt = cipher.decrypt(encrypt)

    print('解密后:\n%s' % decrypt)

    运行结果:

    加密后:

    2IVIT2hWtZo1WQ2xMd0LUg==

    解密后:

    hello server!

    RSA+AES混合使用

    客户端发送加密信息给服务端流程

    客户端使用服务端公钥对数据进行加密

    客户端使用客户端私钥对密文进行签名

    客户端发送密文和签名给服务端

    服务端使用客户端公钥对签名进行验签

    服务端使用服务端私钥对密文进行解密

    代码模拟客户端向服务端发送加密信息:

    from Crypto.Random import get_random_bytes

    from app.AESCipher import AESCipher

    from app.RSACipher import RSACipher

    from app.config import Config

    # 客户端代码

    text = 'hello server!'

    # 随机生成aes的密钥

    aes_key = get_random_bytes(16)

    print('随机生成的aes密钥:\n%s' % aes_key)

    aes_cipher = AESCipher(aes_key)

    rsa_cipher = RSACipher()

    # 使用aes密钥对数据进行加密

    encrypt_text = aes_cipher.encrypt(text)

    print('经过aes加密后的数据:\n%s' % encrypt_text)

    # 使用客户端私钥对aes密钥签名

    signature = rsa_cipher.sign(Config.CLIENT_PRIVATE_KEY, aes_key)

    print('签名:\n%s' % signature)

    # 使用服务端公钥加密aes密钥

    encrypt_key = rsa_cipher.encrypt(Config.SERVER_PUBLIC_KEY, aes_key)

    print('加密后的aes密钥:\n%s' % encrypt_key)

    # 客户端发送密文、签名和加密后的aes密钥

    print('\n************************分割线************************\n')

    # 接收到客户端发送过来的signature encrypt_key encrypt_text

    # 服务端代码

    # 使用服务端私钥对加密后的aes密钥解密

    aes_key = rsa_cipher.decrypt(Config.SERVER_PRIVATE_KEY, encrypt_key)

    print('解密后的aes密钥:\n%s' % aes_key)

    # 使用客户端公钥验签

    result = rsa_cipher.verify(Config.CLIENT_PUBLIC_KEY, aes_key, signature)

    print('验签结果:\n%s' % result)

    # 使用aes私钥解密密文

    aes_cipher = AESCipher(aes_key)

    decrypt_text = aes_cipher.decrypt(encrypt_text)

    print('经过aes解密后的数据:\n%s' % decrypt_text)

    运行结果:

    随机生成的aes密钥:

    b't\xb6\x8da\x8f2fa\xdc\x05\xc0\xff\x97\x84\xa2\xa9'

    经过aes加密后的数据:

    9TbA3VDRrLV9cz/ky/dUAQ==

    签名:

    b'o5sdTd+0vBUNV2zRslIvUppRIDpb4HYfMhEAQEogih5nQmLvTy6h/1hIoUS240KasoiewUAfV+V9VABkNszIzWKh1B0HKpItwpzLDmbTd3iqE2BlIx3C3b+ak1Y14YTdI626RqhrCZQMAvlxerWWYu+sMCBCTfNt+WkKNiUUJvM='

    加密后的aes密钥:

    b'Ybpxv9jtLhKLiUiIBTR7aRmOivvbh9KTIqjM9rMIqn4PezRftBqDa8HU4vn2y/2PEsPUY8tLbCkGC1E07d93ZrNrEX9PbU0zYTeWpRpJwfF0yWB41RonyWxQIO4cETOtqEitnRs4DRehqgVufU1SeEx45Wwy7wCGBOnudoo4bpA='

    ************************分割线************************

    解密后的aes密钥:

    b't\xb6\x8da\x8f2fa\xdc\x05\xc0\xff\x97\x84\xa2\xa9'

    验签结果:

    True

    经过aes解密后的数据:

    hello server!

    展开全文
  • 混合加密JS是用于JavaScript的混合(RSA + AES加密和解密工具包。 Hybrid Crypto JS结合了RSAAES加密算法,可以有效地加密和解密大型邮件。 该跨平台库基于 。 Hybrid Crypto JS可以在浏览器,Node.js或React ...
  • 它虽然解决了“在不安全的信道上安全地传递密钥”这一问题,但缺点在于运算量太大,造成加/解速度太慢,所以在具体的工程应用上是混合使用了对称和和非对称加密算法,比如SSL/TLS协议是混合使用了RSA和AES算法。...

    RSA属于非对称加密算法,它虽然解决了“在不安全的信道上安全地传递密钥”这一问题,但缺点在于运算量太大,造成加/解速度太慢,所以在具体的工程应用上是混合使用了对称和和非对称加密算法,比如SSL/TLS协议是混合使用了RSA和AES算法。具体的过程是,用RSA算法加密对称密码再传递给对方,然后双方使用对称加密算法通信;另外,RSA还起到CA认证的作用(其实就是验证由CA的私钥签名的,对方的公钥)。

    由此可见,RSA的作用已经由“加密数据”减弱为“验证CA证书”和“共享对称密钥”,如果第二个作用由DH算法代替,那么,RSA就仅用于验证CA证书了。

    为了理解用RSA共享对称密钥的过程,本文用手动的方法来逐步实现。

    A用户要把数据加密传输给B用户,步骤如下:

    1、B生成公钥/私钥对,并把其中的公钥导出,通过公开信道传递给A;

    2、A生成对称密码;

    3、A用对称加密算法对文件进行AES加密;

    4、A用B的公钥加密对称密码(形成数字信封);

    5、A将数字信封和密文通过网络等渠道传送B;

    6、B用自己的私钥解密对称密码;

    7、B用解密后的对称密码解密密文;

    具体的操作步骤:

    1、B生成RSA密钥对文件key.pri,然后从中提取公钥key.pub并通过公开信道传递给A:

    cdbaf925d9342dd838c100d61f467645.pngopenssl genrsa -out key.pri 4096

    openssl rsa -in key.pri -pubout -out key.pub

    2、A生成32字节的随机密码文件passwd.bin:

    97945e82aa639cdc9ada2c6cfcf95785.pngopenssl rand -out passwd.bin 32

    3、准备待加密文件test.txt,用上面的随机密码,以AES算法加密明文test.txt,输出的密文是test.enc,key派生函数是pbkdf2:

    6d6f8ab93d98ae511b748baba9ccd152.pngopenssl enc -pbkdf2 -aes-256-cbc -in test.txt -out test.enc -pass file:passwd.bin

    del test.txt

    4、A用B发过来的公钥key.pub加密随机密码文件passwd.bin,形成数字信封passwd.enc:

    7fe5040375ef880ba1676e73f8b71ef4.png

    openssl rsautl -encrypt -in passwd.bin -inkey key.pub -pubin -out passwd.enc

    del passwd.bin

    5、A通过公开信道,将密文test.enc和passwd.enc发送给B:

    7536a0d2d0a52aa1d5c4b7b5d60f6022.png

    6、B首先用自己的私钥解密数字信封,得到对称密码文件passwd.bin:

    d36340f9babff7b62e545b279b479f6a.pngopenssl rsautl -decrypt -in passwd.enc -out passwd.bin -inkey key.pri

    7、B再用对称密码解密消息,得到明文test.txt,算法和秘钥派生函数与加密时用到的参数一样:

    a8668e40af39be05b8cd8138cd0cda84.png

    openssl enc -d -aes-256-cbc -pbkdf2 -in test.enc -out test.txt -pass file:passwd.bin

    非对称加密工具可以使用可以使用gpg4win

    展开全文
  • rsaaes混合加密java实现
  • 现在大部分的客户端和服务端都是用不同编程语言开发的,例如java编写android客户端,python编写服务端。因为语言的不同,RSA和AES在加密和解密的实现细节上可能会存在出入,...对java和python实现RSA+AES混合加密解...
  • vue中使用RSA和AES混合加密数据

    千次阅读 2019-08-12 11:07:50
    4.使用AES对数据加密 参数为 data key加密 5.发送后台数据格式为{“key”:“加密后的key”,“data”:“加密后的data”} 1、获取16位随机数key function randomString(len){ len = len || 32; //给len赋值为函数...
  • Hybrid Encryption I(RSA和AES算法混合加密方案破解)

    千次阅读 热门讨论 2021-03-13 12:40:53
    然而,数据加密是非常昂贵的 利用对称不对称的优点,在练习一通常使用混合加密。 这意味着生成某个对称方案的随机密钥K,明文使用该方案加密。 为了将这个会话密钥K传输给接收者,我们使用了一个公钥方案对会话...
  • rsa+aes加密

    2021-11-30 10:42:55
    参考:https://www.cnblogs.com/huanzi-qch/p/10913636.html 这里只讨论java代码,详情请看:前后端API交互数据加密——AESRSA混合加密完整实例 AES简介 高级加密标准(AES,Advanced Encryption Standard)为最常见...
  • 既利用了 RSA 的灵活性,可以随时改动 AES 的密钥;又利用了 AES 的高效性,可以高效传输数据。
  • 转载请注明出处: ... ...本文以Androidclient加密提交数据到Java服务端后进行解密为样例。...生成RSA公钥密钥的方法请參考: http://blog.csdn.net/aa464971/article/details/51035200 ...
  • AESRSA混合加密完整实例

    千次阅读 2020-09-05 20:20:16
    前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用RSA加密传输AES的秘钥,用AES加密数据,并提供如下思路: ...
  • 第一版为从c++底层封装的大数计算实现,后来发现miracl的计算效率比较高,此发布版本为从...目前支持RSA\AES混合加密计算。 目前Demo 有主流的Java、C++、基于vs的Qt5.7.5、VC++6,C# 后续继续完善其他计算功能!
  • RSAAES混合加密算法的实现

    千次阅读 2014-05-07 16:57:29
    接收方生成RSA密钥对,将其中的RSA公钥传递给发送方(接收方与发送方建立连接是需要认证的,SSL/TLS协议可以确保RSA公钥的安全完整),然后用RSA公钥对AES密钥进行加密加密后的结果传递给接收方,接收方用RSA私钥...
  • RSA+AES对数据加密

    千次阅读 2022-04-13 11:02:02
    由于RSA加密得字符串长度密钥长度有关,所以一般结合aes加密使用 加密方式如图 解密方式如图 具体java实现如下 RSAUtils.java package com.utils.sign; import com.constant.Constants; import ...
  • RSA和AES前端数据加密,对其进行数据解密,以及返回参数加密,前端解密,完整原始文件,由于是城市表面常用的是这二种加解密方式,所以就写了这二种,每天会自动更换密密钥,后续我会陆续更新其他的加解密算法,...
  • RSA+AES 加密工具类 Java

    2018-03-13 09:53:45
    适用于Android、Java、Web端使用的AESRSA加密工具类
  • 大神弄的RSAAES混合加密解密,这个是J2SE工程、安卓工程 的两个Demo,方便学习测试结果,也方便移植到自己的工程里。
  • 然而,数据加密是非常昂贵的 利用对称不对称的优点,在练习一通常使用混合加密。 这意味着生成某个对称方案的随机密钥K,明文使用该方案加密。 为了将这个会话密钥K传输给接收者,我们使用了一个公钥方案对会话...
  • android开发RSA-AES-混合加密Demo android开发RSA-AES-混合加密Demo
  • C# RSAAES加密解密

    2021-01-29 15:11:59
    啾啾啾~ 来自: https://www.jb51.net/article/88109.htm https://www.jb51.net/article/168179.htm ... public class DecryptionTool { /// <summary>... /// RSA加密 /// </summary>
  • RSA+AES 混合加密在项目中的实践一些解释实现逻辑代码走起 一些解释 RSA 非对称加密,加解密过程中不必网络传输保密的密钥;密钥管理优于AES算法;RSA加解密速度慢,不适合大量数据文件加密; AES 对称加密,...
  • RSA.rar,RSA,.vs,RSA,v14,.suo,RSA.sln,RSA,RSATools.cpp,test.cpp,RSA.vcxproj,RSATools.h,main.cpp,RSA.vcxproj.filters
  • 3.3. AES算法实现数据加密传输3.3.1 AES算法加密原理:3.3.2 AES算法加密解密流程图:四、实验过程与运行结果4.1. 网络传输连接的建立4.2. RSA算法的实现与加密解密4.3. AES的实现与加密解密4.4. 运行总
  • aes是对称加密,使用同一密钥进行加密和解密 原理就是: // 客户端 1.客户端随机产生16位的key String key = AESUtil.generateKey(); 2.客户端对敏感信息加密 String password = “123456”; String encryptPwd = ...
  • rsa des java 混合加密解密

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,411
精华内容 1,364
关键字:

rsa和aes混合加密