iOS加密学习

2021-12-16  本文已影响0人  冷武橘

安全的原则
1、在网络上不允许传输用户隐私数据的明文
2、在本地不允许保存用户隐私数据的明文

数据安全
相对POST请求而言,GET请求的所有参数都直接暴露在URL中,请求的URL一般会记录在服务器的访问日志中,而服务器的访问日志是黑客攻击的重点对象之一。
然仅仅使用Post请求提交用户隐私数据,还是不能完全解决安全问题的,可以使用软件(比如Charles)设置代理服务器,拦截查看手机的请求数据,因此,提交用户的隐私数据时,一定不要明文提交,要加密处理后提交。

信息安全所面临的威胁
机密性(被窃听,秘密泄露)
完整性(篡改,信息被修改)
认证(伪装,伪装成通信双方)
不可否认性(否认,事后不承认是自己发送的)

常用的加密算法
MD5 \ SHA \ DES \ 3DES \ RC2和RC4 \ RSA \ IDEA \ DSA \ AES

加密算法的选择
一般公司都会有一套自己的加密方案,按照公司接口文档的规定去加密

一、Base64编码

描述:Base64可以成为密码学的基石,非常重要。
特点:可以将任意(图片、音频、视频、字符串)的二进制数据进行Base64编码;
能够逆运算,不够安全,但却被很多加密算法 作为编码方式;

结果:所有的数据(图片、音频、视频、字符串)都能被编码为并只用65个字符就能表示的文本文件。
65字符:A~Z a~z 0~9 + / =
对文件进行base64编码后文件数据的变化:编码后的数据~=编码前数据的4/3,会大1/3左右。

//字符串转base64字符串
-(NSString *)base64Encoding:(NSString *)string
{
    //01 把字符串转换为二进制数据
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    
    //02 对二进制数据进行BASe64编码,返回字符串
    return [data base64EncodedStringWithOptions:kNilOptions];
}

//base64字符串转字符串
-(NSString *)base64Decoding:(NSString *)string
{
    //01 先对数据进行base64解码
    NSData *data = [[NSData alloc]initWithBase64EncodedString:string options:kNilOptions];
    
    //02 把二进制数据转换为字符串
    return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}
//图片转base64字符串
- (NSString *)base64withimage:(UIImage *)image{
    NSData *data=UIImagePNGRepresentation(image);
    return [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}

//base64字符串转图片
-(UIImage *)base64Encodingwithimagestring:(NSString *)imagestring{
    NSData *decodedImageData = [[NSData alloc]
                                initWithBase64EncodedString:imagestring options:NSDataBase64DecodingIgnoreUnknownCharacters];
    return  [UIImage imageWithData:decodedImageData];

}

命令行进行Base64编码和解码

1.1、 字符串

    编码:  echo -n "我" | base64
    解码:echo -n "YWFhCg=="| base64 -D

1.2、 文件

    #pragma mark - 文件
    编码:base64 123.png -o 123.txt
    解码:base64 123.txt -o test.png -D

二、单向散列函数

单向[散列函数就是把任意长度的输入消息串变化成固定长的输出串且由输出串难以得到输入串的一种函数。

单向散列函数,又被称为消息摘要函数(message digest function),哈希函数。

输出的散列值,也被称为消息摘要(message digest)、指纹(fingerprint)

1、单向散列函数的特点:

2、常见的几种单向散列函数:

3、单向散列函数应用领域

三、MD5加密算法

MD5加密算法简单说明:
1、对字符串进行MD5加密可以得到一个32个字符的密>文
2、加密之后不能根据密文逆推出明文
3、MD5已经被破解(暴力破解|碰撞检测)

3.1、md5加密

    NSString *password=@“13663815139”;
    NSString *md5string=[password md5String];
    NSDictionary *parmers =@{
                         @"account”:password,
                         @"password”:md5string
                         };

3.2、md5加盐

现在的MD5已不再是绝对安全,对此,可以对MD5稍作改进,以增加解密的难度。加盐就是在明文的固定位置插入随机串,然后再进行MD5。

   NSString *password=@“13663815139”;
    NSString *salt = @“hlt”;
    NSString *saltstr=[password stringByAppendingString:salt];
    NSString *md5string=[saltstr md5String];
    NSDictionary *parmers =@{
                             @"account”:password,
                             @"password”:md5string
                             };
   NSString *str1 = [string substringFromIndex:3];
    NSString *str2 = [string substringToIndex:3];
    NSLog(@"%@-%@",str1,str2);
    NSString *str = [str1 stringByAppendingString:str2];
    NSLog(@"%@",[str md5String]);

4、散列函数加密命令行

MD5加密-字符串    $ echo -n "520" |md5
MD5加密-文件1     $ md5 abc.png
SHA1加密:        $ echo -n “520" |openssl sha -sha1
SHA256            $ echo -n "520" |openssl sha -sha256
SHA512            $ echo -n "520" |openssl sha -sha512
hmacMD5加密       $ echo -n "520it" |openssl dgst -md5 -hmac "123"

四、对称加密和非对称密码

4.1、非对称加密(公钥密码)

特点:

目前使用最广泛的非对称加密算法RSA。RSA的名字,由它的3位开发者,即Ron Rivest、Adi Shamir、Leonard Adleman的姓氏首字母组成。

 openssl genrsa -out private.pem 2048

该命令生成一个模长2048位,名字为rsa_private_key.pemPKCS1格式的RSA私钥文件.

- genrsa:指定生成算法使用RSA
-out:后面参数是生成的私钥的文件名
2048:生成私钥的模长,单位字节(bits)

openssl rsa -in private.pem -out public.pem 
-outform PEM -pubout
截屏2021-12-15 下午12.30.21.png

至此就已经生成了密钥对,可以用文本编辑器直接打开pem查看

 openssl rsautl -encrypt -pubin -inkey public.pem
 -in msg.txt -out msg.bin
openssl rsautl -decrypt -inkey private.pem 
-in msg.bin -out a.txt

4.2、RSA的实践应用

在实践项目中开发中,常用的是:1、直接使用公私钥字符串加解密,2、使用数字证书的公钥加密。

   NSString *publicpath = [[NSBundle mainBundle] pathForResource:@"public.pem" ofType:nil];
    NSData *publicdata = [NSData dataWithContentsOfFile:publicpath];
    NSString *publicdataString = [[NSString alloc]initWithData:publicdata encoding:NSUTF8StringEncoding];
    
    NSString *privatepath = [[NSBundle mainBundle] pathForResource:@"private.pem" ofType:nil];
    NSData *privatedata = [NSData dataWithContentsOfFile:privatepath];
    NSString *privatedataString = [[NSString alloc]initWithData:privatedata encoding:NSUTF8StringEncoding];

获取到公私钥就可以使用,iosRSA算法工具:https://github.com/ideawu/Objective-C-RSA注意:这里就需要PKCS8格式的私钥,要不然解密不出来一直是空。 如果你要直接使用PKCS1格式的私钥,注释掉添加私钥内:的data = [RSA stripPrivateKeyHeader:data];这个方法

补充:mac openssl 生成的私钥格式默认是PKCS1, java、php端一般用的是PKCS8格式的,网上一些ios RSA工具算法也是PKCS8格式。所以实际开发中很有必要将PKCS1转换成PKCS8 PKCS8和PKCS1的区别

openssl pkcs8 -topk8 -inform PEM -in private.pem 
-outform PEM -nocrypt -out pkcs8private.pem

证书和驾照很相似,里面记有姓名、组织、地址等个人信息,以及属于此人的公钥,并有认证机构施加数字签名,只要看到公钥证书,我们就可以知道认证机构认证该公钥的确属于此人。数字证书的内容包括:1、公钥 2、认证机构的数字签名。

数字证书本身就含有公钥,所以可以从证书内引用公钥。

    1)生成私钥 openssl genrsa -out private.pem 1024
    2)创建证书请求 openssl req -new -key private.pem -out rsacert.csr
    3)生成证书并签名,有效期10年 openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
    4)将 PEM 格式文件转换成 DER 格式 openssl x509 -outform der -in rsacert.crt -out rsacert.der
    5)导出P12文件 openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt

iOS开发中的注意点:在iOS开发中,不能直接使用 PEM 格式的证书,因为其内部进行了Base64编码,应该使用的是DER的证书,是二进制格式的。

RSA代码演示: https://www.jianshu.com/p/6c1340e116ca

4.3、对称加密

在对称密码中,加密、解密时使用的是同一个密钥

常见的对称密码算法有

对称加密的特点:


分组密码

密码算法可以分为分组密码和流密码两种。

分组密码:每次只能处理特定长度的一zu数据的一类密码算法。一个分组的比特数量就称之为分组长度。
ex:DES和3DES的分组长度都是64比特。即每次只能加密64比特的明文,并生成64比特的密文。AES的分组长度有128比特、192比特和256比特可以选择。
流密码:对数据流进行连续处理的一类算法。流密码中一般以1比特、8比特或者是32比特等作为单位俩进行加密和解密。

AES

AES高级加密标准,其密钥长度有128、192、256bit三种,
目前AES,已经逐步取代DES、3DES,成为首选的对称密码算法

AES(ECB)加密

 echo -n iostest| openssl enc -aes-128-ecb -K 616263 -nosalt | base64

AES(CBC)加密

echo -n iostest| openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64

AES(ECB)解密

echo -n FqRpCOQG9IL2QrKBHhM+fA== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d

AES(CBC)解密

echo -n Kd9MN/rNEI40hdLhayPbUw== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d

注abc == 616263,字符串abc的16进制就是616263

在实际开发中使用AES的ECB分组模式就可以了。

密钥配送问题

在使用对称密码时,双方是共用同一密钥的,所以一定要考虑密钥配送问题。

密钥配送方法:

总结

对称密码的缺点:不能很好地解决密钥配送问题
公钥密码的缺点:加密解密速度比较慢。
所以在开发中使用最多的是用AES加密信息,需要配送密钥或者信息量比较小的话可以用RSA加解密

五、数字签名

在网络传输过程中,A发送给B一条消息,信息有可能会被篡改或者有人伪装成A发送消息,或者说A可以否认是自己发的。为了解决篡改、伪装、否人就需要数字签名。

数字签名,其实就是将公钥密码反过来使用,使用私钥加密生成签名,公钥解密验签。

如果直接使用RSA的话,考虑到信息量比较大的话,RSA的效率会很低,所以通常会这样改进一下:消息发送者先使用单向散列函数对信息进行单向散列计算会得到定长的散列值,然后使用RSA的私钥对散列值进行签名之后发送签名和消息。消息接收者得到再使用公钥对签名验签,得到散列值之后,消息接收者使用同样的单向散列函数对消息进行运算也得到一个散列值,最后对比两个散列值是否一样,如果不一样说明消息被篡改过。
数字签名的作用:确认消息的完整性、识别消息是否被篡改、防止消息发送者发送,数字签名不能保证机密性。

六、数字证书

正确使用数字签名,前提是用于验证签名的公钥必须属于真正的发送者。如果遇到了中间人攻击,公钥被伪造,签名自然也将失效。所以在签名之前,必须先验证公钥的合法性。为了保证公钥的合法性,就需要证书了。

证书,联想的是驾驶证、毕业证、英语四六级证等等,都是由权威机构认证的。密码学中的证书,全称叫公钥证书(Public-key Certificate,PKC),跟驾驶证类似。

数字证书里面有姓名、邮箱等个人信息,以及个人的公钥。

上一篇下一篇

猜你喜欢

热点阅读