网络传输数据加解密方案选择(RSA+AES)

本文探讨了数据加密的重要性,介绍了对称加密(AES)和非对称加密(RSA)的选择,以及如何根据项目安全需求选择合适的加密方案。重点讲解了如何结合RSA和AES实现单向认证和双向验证,以提升数据传输的安全性。

转自:https://blog.youkuaiyun.com/yuzhiqiang_1993/article/details/88641265

为什么要对数据加密
理由很简单,为了安全。
因为之前一直在赶项目,没有对传输的数据做处理,导致我这边通过抓包软件直接能看到我请求发的是什么数据,服务端给我返回的数据是什么。

而且可以通过抓包软件修改响应数据返回给客户端,这样一来,客户端实际上接收到的数据并不是服务端给我的源数据,而是被第三者修改过的数据,如此一来,数据传输的安全就很有必要了。

那如何保证数据传输的安全呢?
总体要做到一下两点

1. 保证传输的数据是经过加密或者编码过的,即使有人通过抓包软件抓取到数据,也看不懂或者很难解开的。
2. 要能够确定接收到的数据没有经过篡改,也就是确认发送者的身份

虽然说没有绝对的安全,但是做到以上两点,我们能够极大程度的提高数据的安全性以及对身份的确定性

加密算法的选择
市面上的加密算法众多,但是就目前来讲加密大致分为以下两种:

1. 对称加密
2. 非对称加密

关于对称加密和非对称加密的原理等文章有很多,这里我就不展开介绍了,可以看看下面的文章,都写的很好!
感谢以下文章作者的分享!

常用加密算法概述
浅谈常见的七种加密算法及实现
MD5算法和SHA-1算法
对称加密及AES加密算法
从支付宝SDK的支付流程理解什么是公钥和私钥,什么是加密和数字签名
非对称加密及RSA加密算法

这里我们就不再去纠结算法的原理是什么了,说实话,我也看不懂(很难受)


我们的目的就是选择一个合适的方案并且能够合理的用在项目中就行了。

所以,我们先来简单的根据上面的文章来总结一下加解密的相关知识

秘钥
下面的解释来自百度百科:
秘钥,即密钥,在密码学中,密钥(key,又常称金钥)是指某个用来完成加密、解密、完整性验证等密码学应用的秘密信息。在对称密码学(或称密钥密码学)中,加密和解密用的是同一个钥匙,因此钥匙需要保密。而在公钥密码学(或称非对称密码学)中,加密和解密用的钥匙不同:通常一个是公开的,称为公钥;另一个保密,称为私钥。

对称加密
加密和解密都是使用一个秘钥

优点: 对数据没有长度限制,加解密速度快
缺点: 秘钥的传输及保管是个问题,任何一方的秘钥泄漏都将导致数据的不安全

在众多的对称加密算法中,目前来讲AES是最好的,最安全的,因为它是最新出的。
一般来讲,新出的都会比以前的好。

实际上是因为DES的秘钥相对较短,也就相对更容易破解,因此,目前更推荐使用AES进行对称加密。

不过需要注意的是,AES在不同的Android版本上需要注意兼容性的问题,这个后面再讲

非对称加密
非对称加密首先要生成一对秘钥,分为公钥和私钥
公钥和私钥能够相互解密。
一般来讲,长度长的作为私钥,要放在服务端保管好,千万不能泄露。长度短的作为公钥,分发给客户端,公钥是公开的。
支付宝给我们提供了生成RSA秘钥的工具,一键生成RSA秘钥
需要的可以下载。
嫌麻烦的也可以使用在线生成RSA秘钥

注意事项:
生成的秘钥大概如下,根据你自己的需求生成
秘钥位数: 一般来讲秘钥的长度选择为1024位或2048位。2048位的安全性更高,支付宝也建议使用2048位来生成秘钥。不过这里有个坑,网上的大部分RSA工具类在使用2048位秘钥进行解密的时候都会报错,这个坑我们后面再来解决。
秘钥格式: 我们选择目前比较流行的PKCS#8即可,如果出现问题,就选择pkcs#1格式

说了这么多,我们来看看非对称秘钥的优缺点:

优点:无需关心秘钥的传输问题,只要在服务端把私钥保管好即可
缺点:加密速度慢,对加密的数据长度有限制
加密方案选择
好了,了解可加密的相关知识,下面我们来分几个安全等级来排列一下下面的加密方案(安全等级依次提升)

方案一,使用Base64编码

这里我们引入一下编码,我们在使用加密的时候一般都要对加密后的数据进行一下编码,防止传输的过程中出现乱码的情况。
最常用的就是Base64编码了,Base64不算是加密,只是把字符经过编码变成不可读一串文字。
如果你的项目对安全根本没有什么要求,你就可以使用编码的方式,简单省事。但是这个方式只是比“裸奔”好那么一点,可以防止大部分小白用户吧。

方案二,双方约定好密码,使用AES加密

这种方案要求服务端和客户端约定好加密的密码,两端分别保留,在处理数据时就用本地约定好的密码对数据进行加解密。
这中方案能应付一些对安全要求不是很高的项目。由于密码是分别放在两端的,一些别有用心之人如果通过一些手段(例如Android端通过反编译或者逆向)获取到了密码,就能通过抓包软件篡改传输的数据然后再次加密给服务端了,此时,服务端是不知道数据是被篡改过的。

在线AES加密解密 这个网站我们可以收藏一下,后面调试项目的时候很可能会用上。

方案三,使用AES加密,密码随机生成

这种方案可以在服务端和客户端中写一个随机函数,生成一个随机的密码,两端均通过这个随机密码进行加密,然后传输数据的时候把这个随机密码传输给对方(例如放到请求头中),对方用接收到的随机密码进行解密。

实际上这个方案有点掩耳盗铃的意思,你都把解密的密码放到请求头中去了,人家一抓包很容易就获取到密码,甚至比方案二还要容易。

方案四,RSA结合AES进行加密,实现对客户端的单向认证

我们知道了RSA虽然能过做到身份验证,但是其加密速度较慢,并且不适合对大数据进行加密。
那么,单纯的使用RSA加密肯定是不可取的。
而AES的加密速度快且对加密数据没有大小限制,但是,秘钥的传输及管理是个问题,上面我们已经举过例子了。
那么,我们把两者结合起来取长补短不就好了吗?

我们可以这样:
以客户端给服务端传输数据为例

服务端生成一对RSA秘钥,私钥放在服务端(不可泄露),公钥下发给客户端
客户端使用随机函数生成AES加密要用的key
客户端使用随机的key对要传输的数据用AES进行加密
使用服务端给的公钥对生成的随机Key进行加密。
客户端将使用AES加密的数据以及使用RSA公钥加密的随机key一起发给服务端
服务端拿到数据后,先使用私钥对加密的随机key进行解密,解密成功即可确定是客户端发来的数据,没有经过他人修改,然后使用解密成功的随机key对使用AES加密的数据进行解密,获取最终的数据
这个方案跟方案二的区别在于:即使公钥被别人获取到,但是服务端的私钥他是拿不到的,也就没办法解密你要传给服务端的数据,想篡改数据后再提交给服务端就不存在了。

我为什么更倾向于使用RSA加密而不是签名呢?
因为我个人觉得签名的话要把签名后的数据和加密后的数据一起传输,会增加传输数据的大小,其实正常来讲,私钥是只有服务端有的,只要是私钥能够成功的解密,实际上就已经能够确认传输来的数据是通过公钥加密且没有被修改过的

这种方案实际上已经很安全了,实现了对客户端身份的单向认证以及对传输数据的加密,基本上可以应付绝大部分的项目了

方案五,RSA结合AES,实现双向验证

如果你的客户端也要对服务端的身份进行验证,那么,你可以使用这个方案。

该方案实际上就是在方案四的基础上多了一对RSA秘钥,要求服务端和客户端都生成一对秘钥,服务端保管好自己生成的私钥,把公钥给客户端,客户端也保管好自己生成的私钥,把公钥给服务端。

大概流程如下;
本次以服务端给客户端传输数据为例

两端均生成一对RSA秘钥,各自保管好私钥,公钥给对方
服务端使用随机函数生成AES加密要用的key
服务端使用随机的key对要传输的数据用AES进行加密
服务端使用客户端给的公钥对生成的随机Key进行加密。
服务端将使用AES加密的数据以及使用客户端给的公钥加密的随机key一起发给客户端
客户端拿到数据后,先使用客户端的私钥对加密的随机key进行解密,解密成功即可确认服务端的身份,没有经过他人修改,然后使用解密成功的随机key对使用AES加密的数据进行AES解密,获取最终的数据
客户端给服务传输数据其实就是方案四。都是一样的流程

总结来讲就是:

两端各自用对方提供的RSA公钥对AES随机key进行加密
两端各自用私钥对经过RSA公钥加密的随机Key数据进行解密
剩下的都一样,就是使用解密的得到的AES密码进行解密了
但是能实现认证的前提是私钥都没有泄漏出去,一旦泄漏了,那怎么弄都不好使了。

基本上加密的方案就这么多,足够你使用了,选一个适合你项目的即可,本篇博客主要就是介绍加密方案的选择,下一篇博客,我们来代码进行实战,以及解决实战中遇到的坑

Android完美使用RSA2结合AES对数据进行加密(兼容RSA2 SHA256WithRSA,可使用2048长度的秘钥,AES Android各版本通用)

<think>嗯,用户想了解如何在RSA加密中使用salt来增强安全性。首先,我需要回忆一下RSA的基本原理和盐值的作用。RSA是一种非对称加密算法,使用公钥加密,私钥解密。而盐值通常是随机生成的数据,用于防止彩虹表攻击,常见于密码哈希中,比如加盐的哈希存储。 那么,用户的问题是如何将salt与RSA结合使用。可能的思路是在加密过程中加入盐值,增加随机性,从而提升安全性。需要确保盐值的随机性和唯一性,每次加密都生成不同的盐。这样即使同样的明文被多次加密,由于盐的不同,生成的密文也会不同,防止攻击者通过重复密文推断明文。 接下来,考虑具体实现步骤。首先在加密前生成随机盐,然后将盐与明文结合,可能的方式有拼接或者使用HMAC等。之后用RSA公钥加密这个组合后的数据解密时,用私钥解密得到盐和明文,再分离两者。需要注意的是,盐值需要和密文一起传输,以便解密时使用。 另外,可能的应用场景包括用户登录时的密码加密。客户端生成随机盐,加在密码上,再用RSA公钥加密整个结果发送到服务器。服务器解密后分离盐和密码,进行后续验证。这样可以防止重放攻击,因为每次加密的盐都不同。 还要考虑安全性方面。盐的长度应足够,比如16字节以上,确保随机性。盐的存储和传输需要安全,虽然RSA本身加密了,但盐和密文一起发送,可能不需要额外保护,因为密文已经加密。不过,如果攻击者获取到盐,可能尝试其他攻击,所以盐的随机性很重要。 可能的问题是如何在加密数据中嵌入盐,并在解密时正确提取。一种方法是将盐附加在明文前面或后面,加密后的密文包含盐的信息。解密后,按照约定好的长度分割盐和明文。 此外,参考用户提供的引用中,有提到RSA用于登录认证,客户端使用RSA加密密码,防止明文传输。结合盐值的话,可以进一步提升安全性,避免相同的密码生成相同的密文。 总结步骤:生成盐、组合盐和明文、RSA加密组合后的数据、传输密文和盐(如果需要)、解密后分离盐和明文。这样能有效增强RSA加密的安全性,防止重放和彩虹表攻击。</think>### RSA加密与盐值(salt)结合使用方法 #### 1. 基本原理 在RSA加密中结合盐值(salt)的核心思路是**通过随机盐值增加加密数据的随机性**,从而避免相同明文多次加密生成相同密文,防止重放攻击或彩虹表攻击。盐值通常是一个随机生成的字符串,与明文结合后再进行加密。 #### 2. 实现步骤 ##### 步骤1:生成随机盐值 - 盐值需满足:**长度足够(如16字节以上)**、**随机性高**(使用安全随机数生成器)。 - 示例代码(Python): ```python import os salt = os.urandom(16) # 生成16字节随机盐值 ``` ##### 步骤2:盐值与明文结合 - 方式1:**直接拼接**(明文 + 盐值或盐值 + 明文) ```python plaintext = "user_password".encode('utf-8') combined_data = salt + plaintext # 盐值在前,明文在后 ``` - 方式2:**使用HMAC等哈希算法**(盐值作为密钥) ```python import hmac hashed_data = hmac.new(salt, plaintext, digestmod='sha256').digest() ``` ##### 步骤3:RSA加密组合数据 - 使用RSA公钥加密结合后的数据: ```python from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP public_key = RSA.import_key(open('public.pem').read()) cipher = PKCS1_OAEP.new(public_key) ciphertext = cipher.encrypt(combined_data) # 加密盐值+明文 ``` ##### 步骤4:传输或存储密文与盐值 - 盐值需**与密文一起传输或存储**(因RSA加密后无法直接提取盐值): ```python final_data = salt + ciphertext # 盐值在前,密文在后 ``` ##### 步骤5:解密与验证 - 解密后分离盐值与明文: ```python private_key = RSA.import_key(open('private.pem').read()) cipher = PKCS1_OAEP.new(private_key) decrypted_data = cipher.decrypt(ciphertext) extracted_salt = decrypted_data[:16] # 提取前16字节为盐值 extracted_plaintext = decrypted_data[16:] # 剩余部分为明文 ``` #### 3. 安全性增强分析 1. **防重放攻击**:因每次盐值随机,相同明文加密结果不同[^4]。 2. **抗彩虹表攻击**:盐值增加了明文复杂性,使预计算哈希表失效[^2]。 3. **密钥分离**:盐值动态变化,避免仅依赖RSA密钥的安全性。 #### 4. 典型应用场景 - **用户登录认证**:客户端每次生成新盐值,加密`密码+salt`后传输,服务器解密后验证[^4]。 - **敏感数据存储**:加密数据库字段时,为每条记录生成独立盐值。 #### 5. 注意事项 - 盐值存储:需与密文绑定存储,但无需额外加密(因已被RSA保护)。 - 性能影响:盐值增加数据长度,可能略微影响加密效率。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值