本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

转载请注明出处:http://blog.csdn.net/chay_chan/article/details/58605605

数据传输加密

  在开发应用过程中,客户端与服务端经常需要进行数据传输,涉及到重要隐私信息时,开发者自然会想到对其进行加密,即使传输过程中被“有心人”截取,也不会将信息泄露。对于加密算法,相信不少开发者也有所耳闻,比如MD5加密,Base64加密,DES加密,AES加密,RSA加密等等。在这里我主要向大家介绍一下我在开发过程中使用到的加密算法,RSA加密算法+AES加密算法。简单地介绍一下这两种算法吧。

RSA

  之所以叫RSA算法,是因为算法的三位发明者RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准,主要的算法原理就不多加介绍,如果对此感兴趣的话,建议去百度一下RSA算法。需要了解的是RSA算法属于非对称加密算法,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。简单的说是“公钥加密,私钥解密;私钥加密,公钥解密”。

AES

  高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

为什么要结合使用这两种算法

  如果不清楚非对称算法和对称算法,也许你会问,为什么要结合使用这两种算法,单纯使用一种算法不行吗?这就要结合不同的场景和需求了。

客户端传输重要信息给服务端,服务端返回的信息不需加密的情况

  客户端传输重要信息给服务端,服务端返回的信息不需加密,例如绑定银行卡的时候,需要传递用户的银行卡号,手机号等重要信息,客户端这边就需要对这些重要信息进行加密,使用RSA公钥加密,服务端使用RSA解密,然后返回一些普通信息,比如状态码code,提示信息msg,提示操作是成功还是失败。这种场景下,仅仅使用RSA加密是可以的。

客户端传输重要信息给服务端,服务端返回的信息需加密的情况

  客户端传输重要信息给服务端,服务端返回的信息需加密,例如客户端登录的时候,传递用户名和密码等资料,需要进行加密,服务端验证登录信息后,返回令牌token需要进行加密,客户端解密后保存。此时就需要结合这两种算法了。至于整个流程是怎样的,在下面会慢慢通过例子向你介绍,因为如果一开始就这么多文字类的操作,可能会让读者感到一头雾水。

使用RSA加密和解密

产生公钥和私钥

  产生RSA公钥和密钥的方法有很多,在这里我直接使用我封装好的方法产生,都最后我会将两个算法的工具类赠送给大家。

/*** 生成公钥和私钥* * @throws Exception* */
public static void getKeys() throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");keyPairGen.initialize(1024);KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();String publicKeyStr = getPublicKeyStr(publicKey);String privateKeyStr = getPrivateKeyStr(privateKey);System.out.println("公钥\r\n" + publicKeyStr);System.out.println("私钥\r\n" + privateKeyStr);
}public static String getPrivateKeyStr(PrivateKey privateKey)throws Exception {return new String(Base64Utils.encode(privateKey.getEncoded()));
}public static String getPublicKeyStr(PublicKey publicKey) throws Exception {return new String(Base64Utils.encode(publicKey.getEncoded()));
}

公钥

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRQZ5O/AOAjeYAaSFf6Rjhqovws78I716I9oGF7WxCIPmcaUa1YuyLOncCCuPsaw69+RMWjdbOBp8hd4PPM/d4mKTOVEYUE0SfxhhDTZaM5CzQEUXUyXy7icQTGR5wBjrbjU1yHCKOf5PJJZZQWB06husSFZ40TdL7FdlBpZ1u1QIDAQAB

私钥

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJFBnk78A4CN5gBpIV/pGOGqi/CzvwjvXoj2gYXtbEIg+ZxpRrVi7Is6dwIK4+xrDr35ExaN1s4GnyF3g88z93iYpM5URhQTRJ/GGENNlozkLNARRdTJfLuJxBMZHnAGOtuNTXIcIo5/k8klllBYHTqG6xIVnjRN0vsV2UGlnW7VAgMBAAECgYBMoT9xD8aRNUrXgJ7YyFIWCzEUZN8tSYqn2tPt4ZkxMdA9UdS5sFx1/vv1meUwPjJiylnlliJyQlAFCdYBo7qzmib8+3Q8EU3MDP9bNlpxxC1go57/q/TbaymWyOk3pK2VXaX+8vQmllgRZMQRi2JFBHVoep1f1x7lSsf2TpipgQJBANJlO+UDmync9X/1YdrVaDOi4o7g3w9u1eVq9B01+WklAP3bvxIoBRI97HlDPKHx+CZXeODx1xj0xPOK3HUz5FECQQCwvdagPPtWHhHx0boPF/s4ZrTUIH04afuePUuwKTQQRijnl0eb2idBe0z2VAH1utPps/p4SpuT3HI3PJJ8MlVFAkAFypuXdj3zLQ3k89A5wd4Ybcdmv3HkbtyccBFALJgs+MPKOR5NVaSuF95GiD9HBe4awBWnu4B8Q2CYg54F6+PBAkBKNgvukGyARnQGc6eKOumTTxzSjSnHDElIsjgbqdFgm/UE+TJqMHmXNyyjqbaA9YeRc67R35HfzgpvQxHG8GN5AkEAxSKOlfACUCQ/CZJovETMmaUDas463hbrUznp71uRMk8RP7DY/lBnGGMeUeeZLIVK5X2Ngcp9nJQSKWCGtpnfLQ==

  很明显,公钥字符串长度比较短,私钥的比较长。生成完密钥后,公钥可以存放在客户端,即使被别人知道公钥,也是没有问题的;私钥则一定要保存在服务端。如果到时公司面临人事变动,避免私钥被离职人员泄露,可以重新生成公钥和密钥。

使用公钥加密,私钥解密

  这里在客户端模拟加密的情况,对字符串"Beyond黄家驹"使用RSA加密,调用RSAUtils的encryptByPublicKey()方法,输出结果为:

密文: BRFjf3tUqRqlwuP5JtzxZinf7lp+AHuHM9JSabM5BNFDxuUe9+uuO6RpCHVH5PibifqQHzGNsyZn1G9QcIENT9Tbm+PZwAbNUlMPZRDBU1FSnOtY8dBdeW/lJdnY9sJVwNvIBnOLQk66hxRh6R2149dwlgdsGUpWMOMBzcP3vsU=

  在服务端,可以使用RSAUtils的decryptByPrivateKey()方法进行解密,现在模拟服务端解密

  在这里虽然没有完全模拟数据传输过程,比如说客户端发起一个网络请求,传递参数给服务端,服务端接收参数并进行处理,也是为了让大家可以更加容易明白,所以这里只是进行简单的模拟。可以看到android客户端端和java服务端的RSA加密解密算法是可以互通的,原因是他们所使用到的base64加密类是一致的,所以才可以实现加密和解密的算法互通。

  使用到的jar包都是javabase64-1.3.1.jar,相信不少人都知道,java中有自带的Base64算法类,但是安卓中却没有,之前出现的情况是,使用的Base64类不统一,比如在安卓客户端开发使用的Base64算法是使用第三方提供的jar包,而java服务端中使用的是JDK自带的Base64,导致从客户端传过来的密文,服务端解析出错。

  上面的例子展示了客户端使用公钥加密,服务端使用私钥解密的过程。也许你会这么想,既然可以如此,那服务端那边信息也可以通过RSA加密后,传递加密信息过来,客户端进行解密。但是,这样做,显示是不安全的。原因是,由于客户端并没有保存私钥,只有公钥,只可以服务端进行私钥加密,客户端进行公钥解密,但由于公钥是公开,别人也可以获取到公钥,如果信息被他们截取,他们同样可以通过公钥进行解密,那么这样子加密,就毫无意义了,所以这个时候,就要结合对称算法,实现客户端与服务端之前的安全通信了。

使用AES加密解密
加密

  模拟客户端进行AES加密,我们通过调用AESUtils中的generateKey()方法,随机产生一个密钥,用于对数据进行加密。输出的结果为:

密钥: 6446c69c0f914a57
密文: GECDQOsc22yV48hdJENTMg==
解密

  模拟服务端进行AES解密,由于AES属于对称算法,加密和解密需要使用同一把密钥,所以,服务端要解密传递过来的内容,就需要密钥 + 密文。这里模拟一下服务端解密。

  到这里也许你会问,客户端使用AES进行加密,服务端要进行解密的话,需要用到产生的密钥,那密钥必须从客户端传输到服务端,如果不对密钥进行加密,那加密就没有意义了。所以这里终于谈到了重点,RSA算法+AES算法结合使用。

RSA算法+AES算法的使用

  举一个简单的例子来说明一下吧,例如实名认证功能,需要传递用户真实姓名和身份证号,对于这种重要信息,需要进行加密处理。

客户端使用RSA + AES对重要信息进行加密

客户端加密过程主要分为以下三个步骤:

1.客户端随机产生AES的密钥;

2.对身份证信息(重要信息)进行AES加密;

3.通过使用RSA对AES密钥进行公钥加密。

  这样在传输的过程中,即时加密后的AES密钥被别人截取,对其也无济于事,因为他并不知道RSA的私钥,无法解密得到原本的AES密钥,就无法解密用AES加密后的重要信息。

服务端使用RSA + AES对重要信息进行解密

服务端解密过程主要分为以下两个步骤:

1.对加密后的AES密钥进行RSA私钥解密,拿到密钥原文;

2.对加密后的重要信息进行AES解密,拿到原始内容。

  现实开发中,服务端有时也需要向客户端传递重要信息,比如登录的时候,返回token给客户端,作为令牌,这个令牌就需要进行加密,原理也是差不多的,比上面多一个步骤而已,就是将解密后的AES密钥,对将要传递给客户端的数据token进行AES加密,返回给客户端,由于客户端和服务端都已经拿到同一把AES钥匙,所以客户端可以解密服务端返回的加密后的数据。如果客户端想要将令牌进行保存,则需要使用自己定义的默认的AES密钥进行加密后保存,需要使用的时候传入默认密钥和密文,解密后得到原token。

  上面提及到客户端加密,服务端返回数据不加密的情况,上面说到仅仅使用RSA是可以,但是还是建议同时使用这两种算法,即产生一个AES密钥,使用RSA对该密钥进行公钥加密,对重要信息进行AES加密,服务端通过RSA私钥解密拿到AES密钥,再对加密后的重要信息进行解密。如果仅仅使用RSA,服务端只通过RSA解密,这样会对于性能会有所影响,原因是RSA的解密耗时约等于AES解密数据的100倍,所以如果每个重要信息都只通过RSA加密和解密,则会影响服务端系统的性能,所以建议两种算法一起使用。

同时还有相应的JS版RSA和AES算法,使用方式也差不多,在这里简单演示一下:

下面是一个html页面的代码,引入了rsa.js和aes.js

<!DOCTYPE html>
<html><head><title>RSA+AES.html</title><meta name="keywords" content="keyword1,keyword2,keyword3"><meta name="description" content="this is my page"><meta name="content-type" content="text/html; charset=UTF-8"><script type="text/javascript" src="./js/rsa.js"></script><script type="text/javascript" src="./js/aes.js"></script><script type="text/javascript">var key = getKey();//随机产生AES密钥var encryptKey = RSA(key);//对AES密钥进行RSA加密console.log("encryptKey: " + encryptKey);//测试AES加密和解密var cipherText = AESEnc(key,"123456");var plainText = AESDec(key,cipherText);console.log("密文: " + cipherText);console.log("明文: " + plainText);</script></head><body>This is my HTML page. <br></body>
</html>

打开页面后,查看控制台输出:

同时,模拟服务端解密,运行结果如下:

  在这里将我自己封装的RSAUtils、AESUtils以及使用第三方jar包的Base64Utils还有JS版的RSAHE AES分享给大家,希望可以帮助到大家,由于刚注册博客不久,没有多少积分,下载一些资料的时候需要积分,所以收取大家1积分,谢谢了。

http://download.csdn.net/detail/chay_chan/9766486

需要注意的是:

1.RSAUtils中配置公钥和密钥,可以使用getKeys()方法产生。如果是客户端,则无须配置私钥,把没有私钥的RSAUtils放到客户端,因为仅需要用到公钥加密的方法。

2.AESUtils中配置偏移量IV_STRING;

3.rsa.js中最底部配置公钥,须和上面RSAUtils配置的公钥一致;

4.aes.js中的底部var iv = CryptoJS.enc.Utf8.parse(“16-Bytes–String”); //加密向量中,替换里面的字符串,加密向量须和
是上面的AESUtils中的偏移量一致。

  为了完成这篇博客,花费了接近半天的时间,相当于总结自己在数据传输这一方面的经验,希望可以帮助到更多的开发者,一起交流学习,互相提升和进步。

数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)相关推荐

  1. 数据传输加密非对称加密算法以及对称算法-RSA+AES

    转载:http://blog.csdn.net/chay_chan/article/details/58605605 源码:https://github.com/Javen205/IJPay 数据传输 ...

  2. Java加密技术(四)——非对称加密算法RSA

    转自:http://snowolf.iteye.com/blog/381767 接下来我们介绍典型的非对称加密算法--RSA RSA     这种算法1978年就出现了,它是第一个既能用于数据加密也能 ...

  3. java js 非对称加密算法_Java加密技术(四)——非对称加密算法RSA

    Java非对称加密算法rsa 接下来我们介绍典型的非对称加密算法--RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很流行.算法的名字 ...

  4. Java进阶(七)Java加密技术之非对称加密算法RSA

    Java加密技术(四)--非对称加密算法RSA 非对称加密算法--RSA 基本概念 非对称加密算法是一种密钥的保密方法. 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priv ...

  5. python实现非对称加密算法_Python3非对称加密算法RSA实例详解

    本文实例讲述了Python3非对称加密算法RSA.分享给大家供大家参考,具体如下: python3 可以使用 Crypto.PublicKey.RSA 和 rsa 生成公钥.私钥. 其中 python ...

  6. Java实现非对称加密算法-RSA加解密

    RSA是由三位数学家Rivest.Shamir 和 Adleman 发明的非对称加密算法,这种算法非常可靠,秘钥越长,就越难破解. 目前被破解的最长RSA秘钥是768个二进制位,长度超过768位的秘钥 ...

  7. 网络安全_密码学实验_非对称加密算法RSA

    网络安全_密码学实验_非对称加密算法RSA 一.实验环境 二.非对称加密RSA 1.理解RSA算法原理 2.加密过程 解密过程 一.实验环境 PyCharm 2019.2.4 (Professiona ...

  8. 非对称加密算法-RSA

    2019独角兽企业重金招聘Python工程师标准>>> 1.概述 RSA有两个密钥,一个是公开的,称为公开密钥:一个是私密的,称为私密密钥. 特点: 公开密钥是对大众公开的,私密密钥 ...

  9. 在非对称加密算法RSA中,假设“大”素数p=5,q=11,试给出计算过程。

    文章目录 1. 题目在非对称加密算法RSA中,假设"大"素数p=5,q=11,试给出计算过程. 2. 分析步骤 3. 抄作业简单粗暴看这里 4. 参考 1. 题目在非对称加密算法R ...

最新文章

  1. (正确姿势)Centos7如何安装Nvidia驱动并安装Pytorch使用GPU
  2. 如果编程语言是飞机 | 每日趣闻
  3. linux centos7 createrepo 创建本地 yum 仓库
  4. ajax 公共请求头部,ajax请求中全局增加请求头,如常见的token
  5. Android 动画(四)---逐帧动画
  6. vim配置文件~/.vimrc
  7. 微信、QQ都在用的腾讯云EB级对象存储架构剖析
  8. Linux 编译 mysql
  9. SAP ABAP Workflow 显示问题
  10. hiho1257 Snake Carpet
  11. 红橙Darren视频笔记 自定义sidebar 自定义View ViewGroup套路
  12. LeetCode:螺旋矩阵【54】
  13. P1464 Function
  14. RocketMQ安装使用
  15. pdfplumber库解析pdf格式
  16. 【Python】如何将文件中\xe8\x85\xbe\xe8字符转成中文?
  17. CPU idle框架
  18. 金融数字化平台建设的三大误区和破局之道
  19. CVTE+网易+微盟面经
  20. 针对正方教务开发大学App(查成绩,课表,一键评教,图书馆,正方系统)

热门文章

  1. 32位w7怎么升64位|w7系统32位升级64位教程
  2. 不入耳式蓝牙耳机什么牌子好、最好的骨传导耳机推荐
  3. js中怎样把ASCII码中的字符与十进制的数相互转换-学习笔记
  4. Android仿新浪微博弹出界面动画,Android仿新浪微博启动界面或登陆界面(1)
  5. java 将对象写入链表_在Java中,_____类可用于创建链表数据结构的对象。
  6. 机器学习和深度学习相关问题总结
  7. vue-seamless-scroll数据量少时,暂停滚动,继续滚动
  8. 在Ubuntu虚拟机使用ffmpeg采集摄像头的yuv视频数据
  9. “机器学习实战“刻意练习2/8周
  10. 离线在Jenkins安装CoBOT安装插件