iOS进阶

App 常用签名设计

2017-04-26  本文已影响138人  大慈大悲大熊猫

前言

一般来说,客户端 App 与服务器端是通过接口进行交互,来互相传递数据的,而为了保证数据的安全性,一般都会专门设计一个签名规则。

三种安全强度的签名设计

第一种:客户端加密(对称加密,如 AES),服务端解密,配合 token 和流水号

优点:能够保持用户登录状态、区分用户,相对于不返回任何信息的登录要安全了一些。

缺点:如果通过网络嗅探器(例如:青花瓷)可以获取到http链接,会造成信息泄露,并且还能被伪造请求。

第二种:客户端加密(非对称加密,如 RSA),服务端解密,配合 token 和流水号

采用 RSA 非对称加密。具体流程如下:

第三种:非对称加密 + token + 流水号

前两种方法如果 token 被截获了,那么他人完全就能够模拟出用户的请求,所以在服务器向客户端发送的 token 数据,也需要加密。

具体流程如下:

实践

从签名强度来看,上面方法第三种 > 第二种 > 第一种,所以此处省略第一二种实践方式,主要看看第三种。

流程

具体的实践分为登录(拿 token) 和与用户信息相关的接口加密(AES) ,比上文第三种签名方式,多出一步 AES 加密:

密钥传递与处理

首先要明确 RSA 公私钥密文格式,这里建议客户端和服务端统一使用字符串,即公私钥在客户端是以字符串的形式传递的。

其次,本地存储的公钥1、公钥2、私钥2、AES 密钥、sessionId 和 token,建议统一放到 keychain 中去,防止泄露。

密钥生成

利用 OpenSSL 在客户端生成 RSA 密钥对时,并没找到方法将密钥(SecKeyRef)转成字符串(若您找到了,请告知于我,不胜感激),所以在这用了一个取巧的方法:将公私钥保存为本地文件,然后再从这个文件中读取出来。

#pragma mark - 本地生成 RSA 公私钥对
+ (NSArray *)generateKeys {
    RSA *rsa = NULL;
    rsa = RSA_new();
    rsa = RSA_generate_key(1024,0x10001,NULL,NULL);
    // 路径
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)objectAtIndex:0];
    //获取公钥字符串
    NSString *pubPath = [documentsPath stringByAppendingPathComponent:@"PubFile.txt"];
    FILE *pubWrite = NULL;
    pubWrite = fopen([pubPath UTF8String],"wb");
    if(pubWrite == NULL) {
        NSLog(@"Read Filed.");
    }else{
        PEM_write_RSA_PUBKEY(pubWrite,rsa);
        fclose(pubWrite);
    }
    NSString *publicStr = [NSString stringWithContentsOfFile:pubPath encoding:NSUTF8StringEncoding error:nil];
    publicStr = [publicStr stringByReplacingOccurrencesOfString:@"-----BEGIN PUBLIC KEY-----"withString:@""];
    publicStr = [publicStr stringByReplacingOccurrencesOfString:@"-----END PUBLIC KEY-----"withString:@""];
    publicStr = [publicStr stringByReplacingOccurrencesOfString:@"\n"withString:@""];
    //获取私钥字符串
    NSString *priPath = [documentsPath stringByAppendingPathComponent:@"PriFile.txt"];
    FILE *priWtire = NULL;
    priWtire = fopen([priPath UTF8String],"wb");
    EVP_PKEY *pkey = NULL;
    if(priWtire == NULL) {
        NSLog(@"Read Filed.");
    }else{
        pkey =EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
        PEM_write_PKCS8PrivateKey(priWtire, pkey,NULL,NULL,0,0,NULL);
        fclose(priWtire);
    }
    NSString *privateStr = [NSString stringWithContentsOfFile:priPath encoding:NSUTF8StringEncoding error:nil];
    privateStr = [privateStr stringByReplacingOccurrencesOfString:@"-----BEGIN PRIVATE KEY-----"withString:@""];
    privateStr = [privateStr stringByReplacingOccurrencesOfString:@"-----END PRIVATE KEY-----"withString:@""];
    privateStr = [privateStr stringByReplacingOccurrencesOfString:@"\n"withString:@""];
    
    return @[publicStr,privateStr];
}

最后

以上只是较常用三种安全强度的签名设计,真正 App 签名设计远远不止这三种,比这些安全强度高的也有许多,继续学习。

上一篇 下一篇

猜你喜欢

热点阅读