iOS应用中基于短信的设备绑定安全攻击及解决方案问询
解决方案:防止iOS绑定短信被复制/转发导致恶意绑定
针对你提到的使用MFMessageComposeViewController发送银行设备绑定短信、被攻击者转发后完成恶意绑定的问题,核心解决思路是从服务器端校验逻辑入手,结合客户端辅助限制——单纯阻止短信复制/转发在iOS系统层面难以完全实现,以下是具体可行方案:
1. 一次性动态令牌+设备指纹绑定校验
逻辑说明:
- 客户端发起绑定请求时,先将当前设备的唯一指纹信息(如
identifierForVendor、系统版本、设备型号等组合)上报至银行服务器; - 服务器生成与该设备指纹绑定的一次性令牌,返回给客户端;
- 客户端通过
MFMessageComposeViewController发送仅包含该令牌的短信至银行短号; - 用户在应用内完成绑定操作时,服务器校验当前请求的设备指纹与令牌绑定的指纹是否一致,不一致则拒绝绑定。
客户端代码示例:
// 收集设备指纹信息(可根据安全需求扩展字段) NSString *vendorID = [[UIDevice currentDevice] identifierForVendor].UUIDString; NSString *sysVersion = [[UIDevice currentDevice] systemVersion]; NSString *deviceModel = [[UIDevice currentDevice] model]; NSDictionary *fingerprint = @{@"vendor_id": vendorID, @"sys_version": sysVersion, @"model": deviceModel}; // 上报指纹获取绑定令牌 NSURL *tokenURL = [NSURL URLWithString:@"https://your-bank-api.com/bind/token"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:tokenURL]; request.HTTPMethod = @"POST"; request.HTTPBody = [NSJSONSerialization dataWithJSONObject:fingerprint options:0 error:nil]; NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (!error) { NSDictionary *resp = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSString *bindToken = resp[@"token"]; // 发送绑定短信 if ([MFMessageComposeViewController canSendText]) { MFMessageComposeViewController *msgVC = [[MFMessageComposeViewController alloc] init]; msgVC.body = [NSString stringWithFormat:@"绑定令牌:%@", bindToken]; msgVC.recipients = @[@"95XXX"]; // 银行短号 msgVC.messageComposeDelegate = self; [self presentViewController:msgVC animated:YES completion:nil]; } } }]; [task resume];
2. 短信内容加入设备专属哈希签名
逻辑说明:
- 客户端使用与服务器共享的密钥,对当前设备的唯一标识(如
identifierForVendor)生成HMAC哈希; - 短信内容仅包含该哈希签名(而非明文设备信息);
- 服务器收到短信后,用存储的对应设备标识+密钥重新生成哈希,与短信中的签名对比,不一致则拒绝绑定。
客户端哈希生成示例:
#import <CommonCrypto/CommonHMAC.h> - (NSString *)generateHMAC:(NSString *)content withKey:(NSString *)key { const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding]; const char *cData = [content cStringUsingEncoding:NSUTF8StringEncoding]; unsigned char result[CC_SHA256_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), result); NSData *data = [NSData dataWithBytes:result length:CC_SHA256_DIGEST_LENGTH]; return [data base64EncodedStringWithOptions:0]; } // 生成签名并发送短信 NSString *deviceID = [[UIDevice currentDevice] identifierForVendor].UUIDString; NSString *secretKey = @"your_shared_secret"; // 密钥需存储在Keychain,避免硬编码 NSString *signature = [self generateHMAC:deviceID withKey:secretKey]; if ([MFMessageComposeViewController canSendText]) { MFMessageComposeViewController *msgVC = [[MFMessageComposeViewController alloc] init]; msgVC.body = [NSString stringWithFormat:@"BIND_SIG:%@", signature]; msgVC.recipients = @[@"95XXX"]; msgVC.messageComposeDelegate = self; [self presentViewController:msgVC animated:YES completion:nil]; }
3. 绑定操作增加二次验证
在短信绑定基础上,服务器向用户手机号发送独立的验证码,用户必须在应用内输入该验证码才能完成绑定。即使攻击者转发了绑定短信,没有验证码也无法完成恶意绑定。
4. 限制令牌/签名的有效时长
将绑定令牌或哈希签名的有效期设置为5-10分钟,即使攻击者转发短信,也大概率在有效期外,服务器直接拒绝过期的绑定请求。
关键注意事项
- 不要依赖客户端限制短信复制:
MFMessageComposeViewController是系统控件,应用无法直接禁用其复制、转发功能,客户端限制仅能作为辅助; - 设备标识需安全存储:避免将敏感设备信息明文传输,密钥、令牌等需用Keychain存储,防止被逆向获取;
- 服务器端校验是核心:所有绑定请求必须经过多维度校验(设备指纹、令牌有效性、二次验证码等),仅靠短信内容无法保证安全。
内容的提问来源于stack exchange,提问作者Sommm
相关产品推荐
相关产品推荐

