今天做一些特别的说明,避免在使用密码能力的时候带来风险。【蓝色】为推荐,同时对防重复给出解决办法和样例,供参考
- 禁用的算法:MD5,SHA1,RSA1024,DES,自行设计的密码算法、未经安全性论证的密码; 注意:TripleDES【3DES】,不推荐使用!
- 禁用的密码技术:SSH 1.0、SSL 2.0、SSL 3.0、TLS 1.0,自行设计的密码通信协议、未经安全性论证的密码通信协议
- 推荐使用:SM2,SM3【不能单独使用,带盐也不行】,
SM4(IV不能全为0,CBC)/GCM,HMAC-SM3,MAC
注:SM4_ECB 模式由于模式本身的问题,数字信封除外,不推荐使用
- 每个密钥只干做一件事情,如果加密的SM4,不用于HMAC-SM3
- 敏感数据字段加密,增加所在行所有数据做HMAC-SM3字段;禁止存储明文密钥,数据密钥在日志中不能体现,可记录加密后的数据
- 使用密码学随机数,开发语言提供的Random只具备随机性,不具备不可预测性,不能用于密码算法.
java.util.Random 应该替换为 java.security.SecureRandom。
Python 的 random.random() 应该替换为 os.urandom(n) / secrets.token_bytes(n)
什么是重放攻击
重放攻击(Replay Attacks)也称为重播攻击、回放攻击。在这种攻击场景下,攻击者会截获并记录合法用户的通信数据(如数据包、认证信息等),然后在之后的某个时间点重新发送(即重放)这些数据,试图欺骗接收方,让接收方以为这些数据是合法用户刚刚发送的新鲜数据,从而达到获取非法权限或者干扰正常通信等目的。
简单来说就是可以多次使用,这个还是比较常见的。
密钥分发防重放攻击的方法【商用密码应用与安全性评估 P64】
1)密钥计数器:用于传输消息的密钥都有一个标记他的序列号,该序列号被附加到使用该密钥的一对用户所传输的每个消息上
2)密钥调整:将一个与密钥加密密钥有关的计数序列与此进行异或后,再加密所分散数据密钥
3)时间戳:每个传输消息有一个标记它的时间戳,时间戳超期被拒绝
二、防重放攻击的常用方法
- 时间戳(Timestamp)
基本原理:在发送的每个消息中添加一个时间戳,表示消息的发送时间。接收方在收到消息后,会检查时间戳是否在一个合理的范围内。如果消息的时间戳与当前时间超过范围【发送时间-时间值1,发送时间+时间值2】,就会判定为可能是重放攻击而拒绝该消息。
- 序列号(Sequence Number)
基本原理:为每个发送的消息分配一个唯一的序列号。接收方会维护一个已经接收的序列号列表或者范围,当收到新消息时,检查其序列号是否符合预期。如果收到的序列号是已经处理过的或者不符合递增顺序等规则,就判定为可能是重放攻击。如果只用增长等肯定是有问题,我们可以考虑密码随机数。
- 挑战 - 应答机制(Challenge - Response)
基本原理:接收方先向发送方发送一个随机的 “挑战”(Challenge)消息。发送方收到挑战后,使用只有合法用户才知道的密钥或者算法,对挑战进行计算,生成一个 “应答”(Response)消息并返回给接收方。接收方再用相同的密钥或算法验证应答是否正确。因为每次挑战都是随机的,所以攻击者很难重放之前的应答来通过验证。
可以结合序列号使用。
- 一次性密码(One - Time Password,OTP)
基本原理:一次性密码是一种只在一次认证或者一次通信中有效的密码。它可以基于时间同步(如每隔一定时间生成一个新密码)或者事件同步(如每进行一次认证操作生成一个新密码)等方式产生。由于每次使用的密码都不同,所以即使攻击者截获了之前的密码,也无法在后续的通信中使用。
这个也是动态口令的基本原理,比较安全的实现需要客户端有一个密码模块来保护密钥,OTP的生成不依赖于服务端。
我们来思考一下能不能结合以上原理构建一个接口定义的框架,在定义框架内,实现防重复攻击,这样我们的接口以后就可以只关于业务,不再考虑安全问题了。
根据密码学的四个基本特性,机密性,完整性,真实性,不可否认性。
如果不是关键操作,不考虑不可否认性的情况下,我们是否可以用一个接口定义,一个密码方法,同时完成 机密性,完整性,真实性?
这里的真实性指的是接口调用双方的身份真实性,调用端和被调用端都必须保证密钥的安全性,没有这个前提,以上不成立!
SM4/AES 的GCM和CCM模式就可以同时完成 机密性,完整性,真实性。

我们尝试定义一个接口来演示一下。
请求数据:
app_id :发起方业务标识,用于标识使用哪个密钥进行加密!
timestamp:发起方的发起时间戳
random:密码随机数【注意不能使用系统默认的Random】
user_id:用户的身份信息,这里为手机号
key='2934412A66B7A186DC35DC40E926F9EE'
可以使用我在
aead 模式,sm4,aes 的gcm模式,文件名:aead_alg ,bytes 操作-优快云博客
和 https://blog.youkuaiyun.com/CissSimkey/article/details/144770298?spm=1001.2014.3001.5502给出的SM4_GCM 方法试一下
encypt_data:加密的业务数据
{'user_id': '18900000001', 'timestamp': '1736297946.707707', 'random': '71BC2F60AEADF363AC8ADF6C648BA6A7BA9405992DEEBD304128F17D221B83AD'}
encrypt_data 为加密后的数据
mac:是tag
整体请求数据如下:
{'app_id': '10000', 'timestamp': '1736297946.707707', 'random': '71BC2F60AEADF363AC8ADF6C648BA6A7BA9405992DEEBD304128F17D221B83AD', 'encrypt_data': 'B6EBC1ECD3D85CCF00DADC8437610CB785806B19DD0D0A63F3A3D605B12A2C330EA6CC1B3E0229917F37BE43F054480BB4D705FC4300F6EDC8447E6D77480EA5F71B62F449D9C63EF11E4817707E8CFB78B73E9424C2BD236DA15768EE9AE42FFE87D5FAF8800466FAC35BC3C9120ECBAC05C5A4D296B58DF539FF904E1FF939C702A22A3D33B8BF3A03410ABF590FD8', 'mac': '7A674FB3B494BAE7C3F56C4F0A2746AE'}
那么我们就可以构成一个完整的请求数据,这里面有时间戳,随机数,加密的数据。我们需要在接收到数据做一下校验
- 获取发起时间戳,在时间戳有效范围内【发起时间戳-时间范围1,发起时间戳+时间范围2】校验数据是否有效
- 在内存库或者数据库中,校验随机数是否存在,是否被使用过。【注意这个里的随机数可以存在一个小的数据库表内,保留范围可以3个时间时间戳有效范围内,【发起时间戳-3*时间范围1,发起时间戳+3*时间范围2】,保留三个时间段内的数据主要是观察数据,数据库清理数据需要一个时间。
3)注意这里面有个技巧,需要将aad =app_id+timestamp+random【注意将aad排序,即使拼接顺序错误也没有关系】 这样只要可以解密成功,那么这三个参数必然没有被篡改!
- 如果使用了挑战码方式,每次要更新random的使用状态,只能被使用一次,不管是否成功。如果没有使用挑战码只要判断随机数是否存在就可以了,不存在返回成功。
- 根据密码的特性,SM4_GCM模式本身就可以完成,机密性【加密】,完整性【tag】,真实性【tag】,又使用timestamp和random防止了重复。可以考虑在接口定义的时候把这个作为基础,在此上面扩展业务。
- 返回参数参考发起参数处理,由服务端操作,不再重复了,基础的内容一样
以下为样例:
app_id:返回放的系统id,只是个标识,还是用发起时的app_id 对应的密钥
timestamp:返回方的时间戳
random:返回方的随机数
encrypt_data:返回的加密业务数据,其中使用返回方的数据
aad =app_id+timestamp+random
mac:tag
{'app_id': '10086', 'encrypt_data': '1F9D0FC7710A3F359A2CFCD0C68CAFEF4EC7B16BDCDCD243003F21666B7C3F0525DB8C4C91E628FE206D35A6169E19474E6EA852F84CECEC9B21EA4199DADF5087DC07EDC674E60A45D3EC7B60E2AE286C4C03D2A2FD71A26AE3279A1D510752A7B90747164AF522F691EB64FC8741D8A701C8CC452248CBF3AA853BC32B7812B0E5415C4E0629E000109869E747FFA1F7CB0A21884316739157A62AD2D23C4219753CA9DFE8535FB02E3428D7CD99613A79A00D65DE856870AB96A9D6F57C5FBE6A833EC3FDEB8C04BD2518B2B2939346D3B55776F5ADAFFE9182AFECAF156D4C3AE27B35B93DADBE86704D125AA7DBD2B2A7FC92CA09D24779E9E006A5C034A9D272E4102D00DB0BEBC83734507FC15B8D6D8F1755C820CCFB559DF644936E', 'mac': 'AB5D62FFF53CF39CF53D75D450455604', 'random': '6E95C80432C3F01E70EF7974A3369CABF5E205970CBC391FAB0AAB9112CD6914', 'timestamp': '1736298221.70073'}
1万+

被折叠的 条评论
为什么被折叠?



