密钥串、类名混淆
1)异或
#define XOR_KEY 0xFA
#define DataDecrypt(content, key) \
{ \
unsigned char *p = content; \
while( ((*p) ^= key) != '\0') p++; \
}
/* 本地数据加密串 */
#define kXorLocalKey ({ \
unsigned char local_key[] = {(XOR_KEY ^ 'L'), (XOR_KEY ^ 'T'), (XOR_KEY ^ 'a'), \
(XOR_KEY ^ 'b'), (XOR_KEY ^ 'c'), (XOR_KEY ^ 'd'), (XOR_KEY ^ 'e'), (XOR_KEY ^ '\0')}; \
DataDecrypt(local_key, XOR_KEY); \
unsigned char result[8]; \
memcpy(result, local_key, 8); \
[NSString stringWithFormat:@"%s", result]; \
})
2)对称加密
#define DataDecrypt(content) [MKCryptDES decryptWithContent:content]
#define kLocalSecretKey ({ \
NSString *keyStr = @"JbLyWGbiDC/1FFT08EF9BtSed/D/6NPkbJVrv+KLSZbEg=="; \
DataDecrypt(keyStr); \
})
3)类名/方法混淆
/* 类名混淆 */
#ifndef MKCryptDES
#define MKCryptDES MKDataCrypt
#endif
/* 方法名混淆 */
#define decryptWithContent signWithContent
- (void)demo {
[MKCryptDES decryptWithContent:@"JbLyWGbiDC/6NPkbJVrv+KLSZbEg=="];
// 静态分析:[MKDataCrypt signWithContent:]
}
登录态cookie校验
- 设置sessionId的有效期(可由后端实现自动延期)
- 添加后端生成的tokenId(匹配sessionId与uid)
- 通过Hash(签名规则+盐串)生成签名sign(本地盐串做混淆处理)
- 使用Https单向认证加强请求的安全性
JWT身份验证机制
JWT(JSON Web Token):登录后返回acces_token、及refresh_token,请求携带access_token做验证身份,每次用access_token判断其是否过期,如果以过期失效,用refresh_token请求接口刷新access_token。
对称/非对称加密密钥长度
- 3DES:16字节、24个字节
- DES:8个字节(长度56位+8个校验位)
- AES:16个字节、24个字节、32个字节
- RSA:128个字节、256个字节
Hash算法
- MD5:低安全性
- SHA2:高安全性
- SM3:高安全性
公钥、私钥、证书的关系
数字证书是经过CA认证过的公钥,包含有效期,认证机构等信息,公钥和私钥是相对的,一个加密一个解密,一个签名一个验签;
cer文件包含了数字签名信息和公钥,为二进制文件,pem为Base64文件,P12文件包含了cer文件(数字证书)和私钥,为Base64文件。
Charles实现浏览器Https抓包
- 设置网页代理为本地IP地址,端口默认8888;
- 浏览器输入chls.pro/ss下载并安装pem证书;
- “钥匙串访”问双击Charles证书,设置为“始终信任”;
- charles-SSL Proxying Settings-添加“域名:端口”;
- charles-Proxy-macOS Proxy-开启HTTPS抓包;
备注:域名:端口-如(*.tencent.com、*:443、*.tencent.com:443)
Https防中间人攻击(charles、fiddler抓包)
以AFNetworking为例,实现bundle-cer数字证书校验
- (AFSecurityPolicy *)configSecurityPolicy:(NSString *)url {
BOOL cerVerify = [url containsString:@"根域名"];
if (cerVerify) {
if (self.certifiPolicy.pinnedCertificates.count == 0) {
return self.defaultPolicy;
}
return self.certifiPolicy;
} else {
return self.defaultPolicy;
}
}
- (AFSecurityPolicy *)certifiPolicy {
if (_certifiPolicy == nil) {
_certifiPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
[_certifiPolicy setAllowInvalidCertificates:NO];
[_certifiPolicy setValidatesDomainName:YES];
[_certifiPolicy setPinnedCertificates:[self configcertificates]];
}
return _defaultPolicy;
}
- (AFSecurityPolicy *)defaultPolicy {
if (_defaultPolicy == nil) {
_defaultPolicy = [AFSecurityPolicy defaultPolicy];
[_defaultPolicy setAllowInvalidCertificates:YES];
[_defaultPolicy setValidatesDomainName:NO];
}
return _defaultPolicy;
}
- (NSSet *)configcertificates {
NSArray *paths = [[NSBundle mainBundle] pathsForResourcesOfType:@"cer" inDirectory:@"."];
NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
for (NSString *path in paths) {
NSData *certificateData = [NSData dataWithContentsOfFile:path];
[certificates addObject:certificateData];
}
return certificates;
}