接口安全要求:
- 防伪装攻击(案例:在公共网络环境中,第三方 有意或恶意 的调用我们的接口)
- 防篡改攻击(案例:在公共网络环境中,请求头/查询字符串/内容 在传输过程被修改)
- 防重放攻击(案例:在公共网络环境中,请求被截获,稍后被重放或多次重放)
- 防数据信息泄漏(案例:截获用户登录请求,截获到账号、密码等)
加密方式
密码学是涉及数学、电子信息、计算机等多学科的一门重要学科,是现代互联网安全的基石,也是目前如火如荼的区块链技术的安全保障。概括来说,加密方式可归结为不可逆加密与可逆加密。
1.1 不可逆加密
Hash加密:Hash算法是一种单向密码体制,即只有加密过程,没有解密过程。此类算法可将任意大小的原始数据变换成规定长度的输出,即获取内容的数字指纹,常用于校验原始内容是否被篡改。
常见的算法包括 MD5、SHA1、PBKDF2、bcrypt 等
MD5 和 SHA1 已经被证实不安全(王小云教授在04年找到 MD5 迅速碰撞方法,谷歌在17年完成了 SHA1 的第一次碰撞),实践中建议至少用 SHA-256 算法,或采用对算力不敏感的 scrypt、Argon2 等算法。
1.2 可逆加密
1.2.1 古典加密算法
基于算法的加密算法,也被称为古典加密算法,如 HTTP 认证中的 base64,比特币生成地址用的 base58(公开的算法也可称作编码方式)。这类算法主要对原始内容进行置换和替换得到密文,安全性依赖于算法是否外泄。
1.2.2 对称加密
对称加密是指加密与解密的使用同一个密钥的加密算法。对称加密算法的出现标志密码学进入现代密码学阶段,密文的安全性从依赖于算法转向依赖于密钥。
目前常见的加密算法有:DES、3DES、AES、IDEA 等
1.2.3 非对称加密
非对称加密使用的是两个密钥,公钥与私钥,我们会使用公钥对网站账号密码等数据进行加密,再用私钥对数据进行解密。这个公钥会发给查看网站的所有人,而私钥是只有网站服务器自己拥有的。
目前常见非对称加密算法:RSA,DSA,DH等。
非对称算法设计巧妙,但实际中要结合对称加密使用。原因是某些算法不能加解密(DH、DSA),或者效率太低(RSA),或者能处理的数据大小有限制(RSA)。而对称加密算法的有点是速度快、加密强度高。常用非对称算法获得共享密钥,之后用对称加密处理数据。
HTTP & HTTPS
会话劫持
会话劫持(Session hijacking),这是一种通过获取用户Session ID后,使用该Session ID登录目标账号的攻击方法,此时攻击者实际上是使用了目标账户的有效Session。会话劫持的第一步是取得一个合法的会话标识来伪装成合法用户,因此需要保证会话标识不被泄漏。
会话劫持发生在地方/途径:
- 通过专门设置的路由器/交换机;所有Hub;同一台物理机上的虚拟机
- 所有上网代理
- 可被ARP攻击的局域网络
- 不安全的无线网络
- 网络运营商具备劫持能力。以前访问http网站,常常能看到网络运营商注入的广告,这说明它是在解析HTTP数据的
HTTPS=数据加密+网站认证+完整性验证+HTTP
HTTPS 就是在 HTTP 下加入了 SSL 层,从而保护了交换数据隐私和完整性,提供对网站服务器身份认证的功能,简单来说它就是安全版的 HTTP。
关于 SSL 与 TLS 的差别,TLS 是 SSL 的升级版本就好。
HTTPS和HTTP的区别
- https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
Certificate Pinning
证书锁定Certificate Pinning是SSL/TLS加密的额外保证手段。它会将服务器的证书公钥预先保存在客户端。在建立安全连接的过程中,客户端会将预置的公钥和接受的证书做比较。如果一致,就建立连接,否则就拒绝连接。
Certificate Pinning在手机软件中应用较多。因为这些应用连接的服务器相对固定,可以预先将服务器的X509证书或者公钥保存在App中。例如,苹果应用商店Apple App Store就预置了这个功能。当使用中间人工具或者Fiddler之类的工具拦截数据,就会造成应用商店无法联网的情况。
AFNetworking 配置如下:
AFSSLPinningModeNone:完全信任服务器证书;
AFSSLPinningModePublicKey:只比对服务器证书和本地证书的Public Key是否一致,如果一致则信任服务器证书;
AFSSLPinningModeCertificate:比对服务器证书和本地证书的所有内容,完全一致则信任服务器证书;
_afManager = [AFHTTPSessionManager manager];
// 方法1 手动加载证书
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"https" ofType:@"cer"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setPinnedCertificates:@[certData]];
[securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setValidatesDomainName:YES];
[securityPolicy setValidatesCertificateChain:NO];
_afManager.securityPolicy = securityPolicy;
// 方法2 AFNetworking会自动去搜索mainBundle下的所有cer结尾的文件并放进内存中
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
[securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];
[securityPolicy setAllowInvalidCertificates:NO];
[securityPolicy setValidatesDomainName:YES];
[securityPolicy setValidatesCertificateChain:NO];
_afManager.securityPolicy = securityPolicy;
OAuth 2.0
OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。
简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
令牌(token)
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
- 令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
- 令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。
- 令牌有权限范围(scope)。对于网络服务来说,只读令牌就比读写令牌更安全。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。
注意,只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。
应用场景
微信、QQ、微博等第三方登陆,获取用户昵称、用户头像等信息
OAuth2授权主要由两部分组成:
- Authorization server:认证服务
- Resource server:资源服务
在实际项目中以上两个服务可以在一个服务器上,也可以分开部署。
OAuth 2.0 应用角色
Resrouce Owner(资源所有者)是数据的所有者。例如:Facebook或Google上的一个用户就是一个Resrouce Owner。他们所拥有的资源就是用户数据。示例图中的那个用户的图标代表的就是Resrouce Owner。Resrouce Owner也可以是一个应用程序。
Resource Server(资源服务器)是存放资源的服务,例如Facebook或Google就是Resource Server。
Client Application(客户端应用)会请求访问存放在资源服务器上的资源,这些资源是属于Resource Owner(资源所有者)的。
Authorization Server(认证服务器)对Client Application(客户端应用)进行授权,授权通过后客户端应用才可以访问资源服务器上的资源。认证服务器和资源服务器可以是同一个应用,也可以分开独立部署。
OAuth2的4种模式
OAuth2根据使用场景不同,分成了4种模式
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
授权码模式,是四种模式中最复杂的,通常网站(web)中经常出现的微博、qq第三方登录,都会采用这个形式。
接口加签验签
加签算法(微信支付)
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
参数名ASCII码从小到大排序(字典序);
如果参数的值为空不参与签名;
参数名区分大小写;
验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
举例:
假设传送的参数如下:(查询我的信息)
Action: myinfo
id: ****
other: ****
- 对参数按照key=value的格式,并按照参数名ASCII字典序排序生成字符串:
string = "Action=myinfo&id=**&other=**"
- 拼接API密钥:
string = string + "&key=192006250b4c09247ec02edce69f6a2d" //注:key为后台接口约定给app的密钥key
- md5 或者 HMAC-SHA256
sign = MD5(string).toUpperCase()="1B62282EEBBE994E0A5189B96ED616CF" //注:MD5签名方式
sign = hash_hmac("sha256",stringSignTemp,key).toUpperCase()="9A7758BBFD8539A97933DB97B86F6709BBFDE5870BCAD514F1D8D19F614FC7C5" //注:HMAC-SHA256签名方式
- 最终得到最终发送的数据:
Action: myinfo
id: ****
other: ****
sign: sign
2、生成随机数算法
微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。
验签算法
同样按上面算法,校验签名