编程学习加密

加密

2016-01-23  本文已影响368人  河南蓝鸥科技有限公司

A:数据为什么要加密呢?

B:废话,为了安全呗。

在互联网发展趋势迅猛的今天,用户的资金安全、企业的信息安全......安全!安全!安全!——数据安全的重要性日趋凸显。也成为我们必须了解的互联网知识。

数据安全:是一种主动的包含措施,数据本身的安全必须基于可靠的加密算法与安全体系,主要是有对称算法与公开密钥密码体系两种(非对称算法),都包含了数据的加密和解密过程。

今天就来介绍几种加密方式:

一,MD5:加密算法有很多种,在iOS开发当中,MD5是我们常用的摘要算法。

PS:哈希算法,哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。 哈希值是一段数据唯一且极其紧凑的数值表示形式。数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。 典型的哈希算法有:MD2、MD4、MD5 和 SHA-1等。

MD5:Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。

MD5算法具有以下特点:

1、 压缩性:任意长度的数据,算出的MD5值长度都是固定的(16进制,32位)。

2、容易计算:从原数据计算出MD5值很容易。

3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

下面送上MD5加密的使用方式:

首先,引入<CommonCrypto/CommonCrypto.h>

1)针对于字符串对象:

//准备字符串

NSString * foo = @"I love my iOS teacher";

//1.获取C字符串(MD5加密基于C语言实现,Foundation框架字符串需要转化)

const char * fooData = [foo UTF8String];//__strong const char *UTF8String,C语言无法持有字符串,必须用__strong修饰来拷贝内容

//2.创建字符串数组接收MD5值

//一个字节是8位,两个字节是16位,两个字符可以表示一个16位进制的数,MD5结果为32位,实际上由16位16进制数组成。

unsigned char resut[CC_MD5_DIGEST_LENGTH];

//3.计算MD5值(结果存储在result数组中)

CC_MD5(fooData, (CC_LONG)strlen(fooData), resut);

//4.获取摘要值

NSMutableString *bar = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH];

for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i ++) {

[bar appendFormat:@"%02X",resut[i]];

}

NSLog(@"%@",bar);

2)针对于非字符串的其他类型:

将其它对象转化为NSData对象(可以将对象事先写入文件),然后获取NSData对象的MD5值。

//1.NSData对象获取

//获取文件路径

NSString *path = [[NSBundle mainBundle] pathForResource:@"一双人" ofType:@“mp3"];

//根据文件路径获取NSData对象

NSData *data = [NSData dataWithContentsOfFile:path];

//2.创建MD5变量

CC_MD5_CTX md5;

//3.初始化MD5变量

CC_MD5_Init(&md5);

//4.准备MD5加密

CC_MD5_Update(&md5, data.bytes, (CC_LONG)data.length);

//5.结束MD5加密

unsigned char result[CC_MD5_DIGEST_LENGTH];

CC_MD5_Final(result, &md5);

//6.获取结果

NSMutableString *resultString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH];

for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i ++) {

[resultString appendFormat:@"%02X",result[i]];

}

NSLog(@"%@",resultString);

总的来说,哈希算法是一种摘要算法,主要作用是用来获取数据的摘要。严格意义上来说不属于加密算法(因为没有解密过程)。获取字符串的MD5值比较简单,其它对象可以先转化成NSData对象再进行操作。可以根据路径直接获取文件数据,也可以将对象写入文件件后获取为NSData对象。iOS同样支持SHA1、base64、AES、钥匙串等方式加密数据。

二,钥匙串加密

钥匙串:(英文:Keychain)是苹果公司Mac OS中的密码管理系统。它在Mac OS 8.6中和iOS7之后被导入,并且包括在了所有后续的各版本中。一个钥匙串可以包含多种类型的数据:密码(包括网站,FTP服务器,SSH帐户,网络共享,无线网络,群组软件,加密磁盘镜像等),私钥,电子证书和加密笔记等。

保存在钥匙串的内容相当于系统对其做了保护,在设备锁定时进行了加密处理。

钥匙串中的条目称为SecItem,但它是存储在CFDictionary中的。SecItemRef类型并不存在。SecItem有五类:通用密码、互联网密码、证书、密钥和身份。在大多数情况下,我们用到的都是通用密码

钥匙串的使用和字典非常的相似。

用原生的 Security.framework 就可以实现钥匙串的访问、读写。但是只能在真机上进行。通常我们使用KeychainItemWrapper来完成钥匙串的加密。

使用钥匙串加密的步骤:

步骤一:拷贝钥匙串类到工程中

步骤二:引入标准头文件

步骤三:生成钥匙串对象

步骤四:存储加密的数据

步骤五:获得钥匙串对象

步骤六:获取加密的数据

以下是代码演示:(要导入工程的文件是一对儿KeychainItemWrapper文件)

在要使用钥匙串加密的类中导入KeychainItemWrapper.h,然后按照上述步骤操作即可。

注意:引入的头文件是MRC模式的,需要进行混编。

代码送上:

//创建并初始化

KeychainItemWrapper *wrapperItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyKeychainItem" accessGroup:nil];

//现在可以对wrapperItem进行读取和写入了,就跟使用NSDictionary一样。它会自动跟钥匙串同步。__bridge强制转换用来将Core Foundation的常量传给一个使用ARC的Cocoa方法。

//系统提供的键值对中的两个键,非系统的键是没法添加到字典中的

id usernameKey = (__bridge id)kSecAttrAccount;

id passwordKey = (__bridge id)kSecValueData;

//注意,我使用的是个Core Foundation类型(kSecAttrAccount),这里它需要用到id(objectForKey:),不要用类型转换,也不要用__bridge。这是一个新特性。

//存值

[wrapperItem setObject:@"user" forKey:usernameKey];

[wrapperItem setObject:@"123" forKey:passwordKey];

//通过相同 的标记创建的钥匙串中具有相同的数据,可以看做是一个对象

KeychainItemWrapper *wrapperItemSec = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyKeychainItem" accessGroup:nil];

//取值

NSString *userName = [wrapperItemSec objectForKey:usernameKey];

NSLog(@"用户名为: %@",userName);

NSString *password = [wrapperItem objectForKey:passwordKey];

NSLog(@"密码为: %@", password);

//KeyChainItemWrapper会缓存读入数据,但不会缓存写出的数据。向钥匙串中写数据的成本很高,所以我们不会频繁写入。钥匙串不适合用来存储经常改变的敏感数据。那类数据应该保存到加密文件中

三,公钥加密

公钥加密也叫非对称加密,常用算法有RSA、ElGamal、背包算法、Rabin等等,iOS中用的最多的是RSA,iOS 使用 RSA 加密, 只需要公钥。

使用RSA,需要首先导入RSA.h和RSA.m文件。

实例代码:

//公钥和私钥都是使用证书生成的,并非我们自定义字符串就可以。我们使用的是生成好的公钥和私钥

//其中-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----不属于密钥部分

//公钥,用于加密数据. 用于公开, 一般存放在数据提供方, 例如iOS客户端.

NSString *publickey = @"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEChqe80lJLTTkJD3X3Lyd7Fj+\nzuOhDZkjuLNPog3YR20e5JcrdqI9IFzNbACY/GQVhbnbvBqYgyql8DfPCGXpn0+X\nNSxELIUw9Vh32QuhGNr3/TBpechrVeVpFPLwyaYNEk1CawgHCeQqf5uaqiaoBDOT\nqeox88Lc1ld7MsfggQIDAQAB\n-----END PUBLIC KEY-----";

//私钥,用于解密数据. 必须保密, 私钥泄露会造成安全问题.

NSString *privatekey = @"-----BEGIN RSA PRIVATE KEY-----\nMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMQKGp7zSUktNOQk\nPdfcvJ3sWP7O46ENmSO4s0+iDdhHbR7klyt2oj0gXM1sAJj8ZBWFudu8GpiDKqXw\nN88IZemfT5c1LEQshTD1WHfZC6EY2vf9MGl5yGtV5WkU8vDJpg0STUJrCAcJ5Cp/\nm5qqJqgEM5Op6jHzwtzWV3syx+CBAgMBAAECgYEApSzqPzE3d3uqi+tpXB71oY5J\ncfB55PIjLPDrzFX7mlacP6JVKN7dVemVp9OvMTe/UE8LSXRVaFlkLsqXC07FJjhu\nwFXHPdnUf5sanLLdnzt3Mc8vMgUamGJl+er0wdzxM1kPTh0Tmq+DSlu5TlopAHd5\nIqF3DYiORIen3xIwp0ECQQDj6GFaXWzWAu5oUq6j1msTRV3mRZnx8Amxt1ssYM0+\nJLf6QYmpkGFqiQOhHkMgVUwRFqJC8A9EVR1eqabcBXbpAkEA3DQfLVr94vsIWL6+\nVrFcPJW9Xk28CNY6Xnvkin815o2Q0JUHIIIod1eVKCiYDUzZAYAsW0gefJ49sJ4Y\niRJN2QJAKuxeQX2s/NWKfz1rRNIiUnvTBoZ/SvCxcrYcxsvoe9bAi7KCMdxObJkn\nhNXFQLav39wKbV73ESCSqnx7P58L2QJABmhR2+0A5EDvvj1WpokkqPKmfv7+ELfD\nHQq33LvU4q+N3jPn8C85ZDedNHzx57kru1pyb/mKQZANNX10M1DgCQJBAMKn0lEx\nQH2GrkjeWgGVpPZkp0YC+ztNjaUMJmY5g0INUlDgqTWFNftxe8ROvt7JtUvlgtKC\nXdXQrKaEnpebeUQ=\n-----END RSA PRIVATE KEY-----";

//创建字符串

NSString *originString = @"hello world!";

//打印原始字符串

NSLog(@"原始字符串: %@", originString);

//使用公钥对数据进行加密

NSString *encWithPublicKey = [RSA encryptString:originString publicKey:publickey];

NSLog(@"Enctypted with public key公钥加密: %@", encWithPublicKey);

//使用私钥对数据进行解密

NSString *decWithPrivateKey = [RSA decryptString:encWithPublicKey privateKey:privatekey];

NSLog(@"Decrypted with private key私钥解密: %@", decWithPrivateKey);

//服务器端

encWithPublicKey = @"p/hm1SvJm9SuuPy66rrf37+EhynkpVnCxbSCZfKznrAKVfpciX/TZM9GfLrAs+bXlND+GeOeZDz2zm+nZDtxpGV1pyQY03hOWn1MQ2+wBKKQdveEdYJ4TVXwGtC3PMaA3dwdRY+WqInQj9WX4JfuQfkYCqbmI0w86uydjFpenwE=";

//使用私钥对数据进行解密

decWithPrivateKey = [RSA decryptString:encWithPublicKey privateKey:privatekey];

NSLog(@"(PHP enc)Decrypted with private key私钥解密: %@", decWithPrivateKey);

//使用公钥对数据进行解密

NSString *encWithPrivKey = @"F+feHOH6807tUV/drvepAMzKlVKRsoDFRkFNfhS9kgVoBt2E6OnUIVw12l608yQGWiqtq8rgZgMY/VCQYZB+3r2rhDlyZ2fjo00sUFOp5BkNPFTs/NpQAolD6V3ifNgDmBQP92uVbxbod1pLRwLC0wLOhr5flQXvvobeg5KrDeE=";

NSString *decWithPublicKey = [RSA decryptString:encWithPrivKey publicKey:publickey];

NSLog(@"(PHP enc)Decrypted with public key公钥解密: %@", decWithPublicKey);

另外,后台和前端开发工程师可根据实际需要,决定谁来加密,谁来解密。

上一篇 下一篇

猜你喜欢

热点阅读