123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- // tag::main[]
- == 术语定义:
- * 用户数据 User Data
- ** 指用户拥有的数据,包括但不限于原始数据(用户输入的数据)、处理原始数据产生的数据(用户上线习惯、用户画像等)、系统运行产生的数据(音视频、图片、日志、事件等)。
- * 隐私数据 Privacy Data
- ** 用户的机密/隐私信息以及个人的敏感数据。
- ** 如:个人敏感信息包括身份证件号码、个体生物识别信息(指纹、人脸等)、银行账户、通信记录和内容、行踪轨迹、住宿信息、14周岁及以下儿童的个人信息等。
- * 数据主体 Data Subject
- ** 用户数据所标识的自然人或者拥有数据的组织或个人,包括但不限于个人、用户、第三方。
- * 数据处理 Processing of Data
- ** 针对用户数据进行的操作行为:如采取收集、记录、组织、构造、存储、调整、更改、检索、咨询、使用、通过传输而公开、散布或其他方式对他人公开、排列或组合、限制、删除或销毁而公开等自动化方式。
- * 生物性识别数据 Biometric Recognition Data
- ** 基于特别技术处理自然人的相关身体、生理或行为特征而得出的个人数据,这种个人数据能够识别或确定自然人的独特标识,例如脸部形象或指纹数据。
- == 规范约束
- === 安全设计原则
- ==== 最小攻击面原则
- 系统每增加一个功能特性就有可能会引入新的风险,通过安全开发可以减少攻击面进而达到控制系统整体风险的目的。
- * 增加了攻击条件(过滤输入)
- * 减少了可以攻击的人数(功能鉴权)
- * 删除无用功能(绝对避免)
- ==== 权限最小化原则
- * 系统只授予主体必要的权限,而不要过度授权,这样就能有效地减少系统、网络、应用、数据库出错的机会。
- * 事物只拥有可以完成他们任务的最小权限,即不赋予不必要的权限。
- * 包括但不限于:用户权限和资源权限(比如可以使用的CPU、内存、网络流量和存储容量等等)。
- ==== 默认安全原则
- * 在软件领域的含义就是:让默认的配置和策略尽可能的安全。如,许多场景,安全和产品体验经常会发生冲突,这时候应当选择安全优先,在安全的前提下,可以允许通过手动关闭安全配置或策略来提升产品体验。
- * 如,默认打开密码复杂度策略,但产品可能可以允许用户关闭这个策略来提升体验。
- ==== 失效安全原则
- * 即业务系统能够正确安全地处理各种异常和错误,即使再访问出错时,也不至于导致信息安全受到威胁。例如,在网页访问出错时,不能输出错误日志甚至包密码等含敏感信息。
- ==== 不信任第三方系统原则
- * 第三方的系统也可能会存在安全漏洞,进而被人攻击,应充分考虑到当第三方系统被攻击时,如何保障自己的业务系统的安全性。
- * 如:当我们向第三方系统查询数据时,必须对数据进行有效性验证后才可以使用(比如使用这些数据进行数据库查询或显示到用户浏览器上)
- ==== 业务隔离原则
- * 不要把所有鸡蛋都放在一个篮子里。
- ==== 公开设计原则
- * 私有算法不公开不一定就是安全,因为有可能泄露,如抓包、反编译、入侵服务器等,如网易云异或加密。
- * 正确地做法应该是:假设算法被破解或完全公开,同样能保证系统的安全。典型的案例诸如业界广泛使用的对称加密算法(AES)和非对称加密算法(RSA),它们的设计实现都是公开的,但是仍然是安全的。
- ==== 正确地修复漏洞
- * 一旦漏洞被发现和确认,首先要找到测试它的方法和弄清产生根因,对于产生漏洞的代码,需要确认该代码是否也在其它产品或版本上使用,即需要对漏洞进行完整地排查和修复
- ==== 数据与代码分离原则
- * 数据与代码分离原则广泛适用于各种由于 `"注入"` 而引发的安全问题的场景。如 `XSS`、`SQL Injection`、`CRLF Injection`、`X-Path Injection` 等。
- ==== 不可预测性原则
- * 我们无法要求运行的系统完全没有漏洞,因此可采取让攻击失效的办法,大大提高攻击的门槛,经过实践检验,证明这个思路确实是有效的,即使无法修复code,但是如果能够使得攻击的方法无效,那么也可以算是成功的防御。
- * 不可预测原则可以巧妙地用在一些敏感数据上,该原则的的实现往往需要用到加密算法、随机数算法、哈希算法等。
- ==== 木桶短板原则
- * 要首先把精力重点放在弥补安全短板上,而不是放在巩固安全优势上(虽然也很重要)。
- === 数据保护原则
- ==== 信息保密意识
- 保持高度信息安全和保密意识,拒绝以任何形式向未经用户授权的第三方透露用户隐私信息。
- ==== 数据分级原则
- 不同数据有不同的敏感程度和访问密级,如果对所有数据都采用高密级的保护,会影响实际运作的效率,同时也是对资源的浪费,因此需要建立一套数据的分级保护原则,针对不同级别的数据采用不同的保护措施。根据数据的敏感程度和访问密级,对数据密级划分为4个等级:
- * 公开(不会产生任何影响)
- ** 公开信息,比如公钥、域名、连接等公开信息,这些信息通常不设置访问门槛。
- * 敏感(易引起用户反感的数据)
- ** 联系方式信息:如手机号码、电话号码、电子邮箱、通讯地址。
- ** 证件号码:如身份证、驾驶证、护照号码。
- ** 建模后的生物性识别数据:如人脸数据、指纹数据。
- ** 位置与轨迹:如地理位置、出行记录、运动轨迹。
- ** 14周岁及以下儿童的相关信息。
- * 秘密(一般的秘密信息,泄露会影响数据主体的利益)
- ** 密码密钥类:如登录密码、支付密码、密钥信息。
- ** 具有关联性质的个人原始信息,比如姓名+身份证号码+人脸共存。
- * 机密(泄露会使数据主体的利益遭受严重的损害)
- ** 如用户的商绝密信息、商业机密、服务器私钥。
- ==== 合法性、合理原则
- * 数据处理要有合法基础,如数据主体的同意、履行与数据主体之间的合同或执行数据主体所要求的合同所必须、公共利益等。
- * 在处理数据前,必须向数据主体说明数据处理的种类、目的、方式、范围、存储期限、是否转移至第三方等,并征求其授权同意。
- * 数据处理的目的必须要满足合法、正当、必要、明确的要求,不能进行与这些目的不一致的处理。
- ==== 主体参与原则
- 数据主体具有知情权、访问权、纠正权、删除权(被遗忘权)、限制处理权、可携带权、拒绝权、不受自动化处理约束等权利。应尽多的将支持个人数据主体行使上述权利的功能包括进去。
- ==== 最小化原则
- 只处理满足数据主体授权同意的目的所需的最少的数据类型和数量,不能收集用户授权同意范围之外的数据。
- ==== 安全性原则
- * 在数据的生命周期内必须有足够的安全机制,确保数据的完整性、保密性和可用性。防止未经授权的访问、销毁、使用、修改和不当披露。
- * 须在用户信息或主界面中提供隐私声明,描述本软件涉及所有用户数据类型、目的、处理方式、留存期、风险或建议。
- * 用户数据的处理过程要进行清晰、完整的记录,做到数据处理过程可追溯、可问责。
- === 认证与鉴权
- ==== 认证方式
- * 基于知道的(口令认证):如账号密码认证;实现简单、使用简单、用户接受度最高、安全性最低。
- * 基于拥有的(硬件认证、第三方认证):如智能卡、身份识别卡、SIM认证(短信)、邮箱认证;实现较简单、使用较简单、用户接受度较高、安全性较高。
- * 基于固有的(生物信息认证):如指纹、人脸或虹膜;实现有一定难度、使用较简单、用户接受度较低、安全性高。
- * 基于关系的():如指纹、人脸或虹膜;实现有一定难度、使用较简单、用户接受度较低、安全性高。
- ==== 认证要求
- * 身份认证的判断处理逻辑应在服务端进行。
- * 禁止通过比较密码本身来鉴别身份,要通过比较密码的摘要来鉴别身份,防止基于对比时间的破解、减少密码明文的传输。
- * 需要有复杂度要求,禁止使用弱密码、风险密码等。
- * 需要有防暴力破解能力,避免暴力破解。
- * 按应用场景确定密码过期策略:保证账号密码定期更换。
- ==== 访问控制
- * 根据应用场景提供对应的鉴权机制,依据安全策略控制用户对数据的访问。
- * 最小权限原则,仅仅授予对应角色所需的最小/最少权限,并在它们之间形成互相制约的关系。
- * 对操作敏感数据功能做一定的标识与限制。
- === 数据安全
- ==== 网络安全
- * 应采用密码安全技术或其他手段保证传输数据的完整性、保密性和抗抵赖。
- * 传输认证类信息时,应采用安全技术措施处理后再进行传输,比如仅传输原数据的摘要。
- * 公网环境使用安全的传输通信协议,如:HTTPS、TLS、DTLS等,尽量避免使用不安全的传输通信协议,比如FTP、SNMPv2。
- * 禁止使用不安全的传输通信协议、加密方案。如需版本兼容,默认不兼容,充分告知用户使用不安全传输通信协议的风险,用户知晓并确认后开启。
- ==== 存储安全
- * 应采用密码安全技术或其他有效措施保证存储的数据的完整性、保密性和抗抵赖。
- * 若需存储敏感信息的原始信息和处理后数据时,原始信息与处理后的数据分开存储。
- * 采用密钥分级保护管理机制(如下图所示),至少实现2级保护机制。密钥部件至少由2部分构成,且至少有1部分在部署时随机生成。
- * 禁止密钥硬编码写死在代码中。
- ==== UI去敏感化
- * 展示层默认显示时脱敏后的敏感信息,以降低在展示环节的泄露风险,如手机号、银行卡号、身份证号码中间几位用 `*` 号代替。
- * 输入密码等敏感信息时,需脱敏处理,如使用 `*` 号替代输入的信息,且禁止拷贝。
- * 根据场景对用户数据去标识化处理,并与用户信息存储分离。
- ==== 日志审计
- 日志审计是对数据访问活动的跟踪记录,从而实现对用户访问行为的主动监控,生成审计所需的信息,失败各类异常时间。
- * 数据活动包括但不限于用户登录、权限设置、数据查询、数据导出、敏感数据访问等。
- * 日志记录内容包括但不限于操作人、操作时间、操作动作、操作途径、操作对象和操作结果。
- * 确保日志审计信息无法删除、修改和覆盖。
- * 日志数据安全存储,利用密码技术保护避免非法查看及篡改。
- ==== 其他
- * 鼓励用户选择复杂的密码,警告用户不要各处使用相同密码
- * 不要泄露用户的敏感信息
- * 能够侦测登录异常、恶意尝试,即使制止
- * 要派人潜伏到安全行业里,或者聘安全顾问,别等到门户网站报道了才知道密码大规模泄露
- * 能够使密码失效(锁定账户),或者周期性提醒修改密码
- * 提前规划密码算法升级的办法
- === 密码强弱规则
- 密码输入分为数字,小写字母,大写字母,特殊符号4类,等级分为4个等级,具体如下:
- . 风险密码
- ** 密码长度小于8位,或者只包含4类字符中的任意一类,或者密码与用户名一样,或者密码是用户名的倒写。
- . 弱密码
- ** 包含两类字符,且组合为(数字+小写字母)或(数字+大写字母),且长度大于等于8位。
- . 中密码
- ** 包含两类字符,且组合不能为(数字+小写字母)和(数字+大写字母),且长度大于等于8位。
- . 强密码
- ** 包含三类字符及以上,且长度大于等于8位。
- [source, javascript]
- .JavaScript 判断密钥强度
- ----
- function getPwdRank(username, userPassword) {
- var iRank = 0;
- userPassword.match(/[a-z]/g) && iRank++;
- userPassword.match(/[A-Z]/g) && iRank++;
- userPassword.match(/[0-9]/g) && iRank++;
- userPassword.match(/[^a-zA-Z0-9]/g) && iRank++;
- iRank = (iRank > 3 ? 3 : iRank);
- if (userPassword.length < 8 || iRank === 1 || userPassword === username || userPassword === username.split("").reverse().join("")) {
- iRank = 0;
- }
- if (iRank === 2) {
- if ((userPassword.match(/[0-9]/g) && userPassword.match(/[a-z]/g)) || (userPassword.match(/[0-9]/g) && userPassword.match(/[A-Z]/g))) {
- iRank = 1;
- }
- }
- return iRank;
- }
- ----
- ==== 密码相关功能设计
- * 支持设置用户密码最低强度限制:弱密码、中密码和强密码,默认是中密码。
- * 其他安全性设计:用户激活机制,密码过期时间机制
- * 记住密码/自动登录设计
- ** 禁止客户端本地保存密码,容易泄露。
- ** 应通过向服务端请求自动登录的票据,客户端保存此票据。下次登录时,用该票据作为请求自动登录。
- *** 客户端根据登录成功后获取的TGC向CMS申请令牌。
- *** 自动登录票据应该与登录客户端的MAC地址、IP地址关联绑定,同时设置该自动登录票据的失效时间。
- === 五类安全服务 footnote:[OSI五类安全服务和八大安全机制, https://blog.csdn.net/algzjh/article/details/62216040]
- 认证(鉴别)服务:在网络交互过程中,对收发双方的身份及数据来源进行验证。
- 访问控制服务:防止未授权用户非法访问资源,包括用户身份认证和用户权限确认。
- 数据保密性服务:防止数据在传输过程中被破解、泄露。
- 数据完整性服务:防止数据在传输过程中被篡改。
- 抗否认性服务:也称为抗抵赖服务或确认服务。防止发送方与接收方双方在执行各自操作后,否认各自所做的操作。
- === OSI 八大安全机制 footnote:[OSI五类安全服务和八大安全机制, https://blog.csdn.net/algzjh/article/details/62216040]
- . 加密
- ** 常用的加密算法有对称加密算法(例如DES/AES/SM4等算法)和非对称加密算法(如RSA/ECC/SM2等算法)。
- . 认证/数字签名
- ** 数字签名是认证(鉴别)服务最核心的技术。常用的签名算法有RSA算法、ECDSA算法、SM2算法等等
- . 访问控制
- ** 通过用户角色、用户组等规则进行验证,一般的应用常使用基于用户角色的访问控制方式。
- . 数据完整性
- ** 通常可以使用单向加密算法对数据加密,生成唯一验证码,用以校验数据完整性。常用的加密算法有MD5和SHA
- . 业务流填充
- ** 在数据传输过程中传输随机数的方式,混淆真实的数据,加大数据破解的难度,提高数据的保密性。
- . 网络隔离
- ** 避免使用不安全网络进行数据交互,如网关来隔离公网直接访问微服务。
- . 公证
- ** 公证机制对应抗否认性服务。公证机制的作用在于解决收发双方的纠纷问题,确保两方利益不受损害。类似于显示生活中,合同双方签署合同的同时,需要将合同的第三份交由第三方公证机构进行公证。
- == 加密算法的使用
- === 对称加密算法使用
- * 常用算法:AES、SM4(类AES)
- * AES标准有一些要素:密钥、加密模式、向量、填充模式等。(标准本身是公开的)
- [IMPORTANT]
- ====
- 关键点:位数足够(至少128位,推荐256位),保护密钥,针对不同特性的明文选用合适的加密模式。
- ====
- 模式选型说明
- * ECB
- ** 适用:分组少(字符长度小于32,两个分组以下),且数据本身随机性较好
- ** 避免:分组较多(>32个字符,>2个分组),部分格式固定
- * CBC
- ** 适用:分组一般(10个分组以下),第一个分组随机性较好
- ** 避免:分组较多(>10个分组),第一个分组格式固定
- ==== 密码(口令)加解密
- 密码(口令)包括登录密码、中间件(数据库、消息队列、缓存服务)访问密码等,使用AES对称加密算法对密码(口令)加密存储和传输。
- 特点:长度在8~32字节,在AES中,最多2个分组,且密码本身具有随机性,因此可以使用ECB模式,更推荐使用CBC模式。
- ==== 私钥证书加解密
- 服务实现https协议,需要私钥证书,私钥证书需要加密保存。
- 特点:私钥证书的格式是公开的,而且头尾带有固定标识,如PEM格式的私钥:
- ----
- —–BEGIN RSA PRIVATE KEY—–
- MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
- ...
- 1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
- —–END RSA PRIVATE KEY—–
- ----
- 在AES加密过程中会产生多个分组,考虑到证书文件中有明显的固定标识,因此禁止使用 `ECB` 模式对私钥证书加解密(已知明文攻击,破解密钥),推荐使用 `GCM` 模式。
- ==== 长段数据加解密
- 如:图片、语音、视频等。
- * 这些数据往往超过1024字节,分组较多,因此禁止使用 `ECB` 模式,推荐使用 `GCM` 模式。
- * 由于这类文件自身较大,数据量大时不方便更换密钥,因此推荐定义加密头来表示,包含加密标识和标识对应的解析策略。
- * 加密头示例:
- ** 加密标记:固定 `x` 字节,对应一类加密算法、策略,下面以带向量的对称加密策略为例定义请求头剩余部分。
- ** 密钥密文长度:1字节,保存密钥密文的长度,单位字节
- ** 密钥密文:n字节
- ** 向量长度:1字节,保存向量的长度,单位字节
- ** 向量:n字节
- === 非对称加密算法使用
- * 常用算法:RSA、ECC(SM2)
- * AES标准有一些要素:公钥、私钥。公钥可以向外部公开,私钥必须妥善保管。
- [IMPORTANT]
- ====
- 关键点:位数足够(RSA至少1024位,推荐2048位,ECC至少192推荐192),私钥必须妥善保管。由于性能较差尽量加密少量数据,加密大量数据时,生成临时密钥,只加密临时密钥,然后再通过对称加密进行加解密。
- ====
- ==== 编码传输
- 在网络传输过程中,为了使得数据不乱码,故需要先编码,再传输,再解码。可以选择以下两种方式
- * 16 进制编码
- ** 编码速度相对较快,编码后文本较长
- * 64 进制编码
- ** 编码速度相对较慢,编码后文本较短
- 注意:
- * 编码后的数据一定会使得编码后的数据比原文本更长,占用更多的网络带宽,编码解码仅是为了更好地兼容性。
- * 为了性能,不同场景有更合适的编码选择;但处于简化系统的目的,推荐在一个系统内统一使用一种编码方式。
- // end::main[]
|