首先羅列一些知識(shí)點(diǎn):
1.加密算法通常分為對稱性加密算法和非對稱性加密算法:對于對稱性加密算法,信息接收雙方都需事先知道密匙和加解密算法且其密匙是相同的牡属,之后便是對數(shù)據(jù)進(jìn)行 加解密了。非對稱算法與之不同谎替,發(fā)送雙方A,B事先均生成一堆密匙轩拨,然后A將自己的公有密匙發(fā)送給B,B將自己的公有密匙發(fā)送給A院喜,如果A要給B發(fā)送消息,則先需要用B的公有密匙進(jìn)行消息加密晕翠,然后發(fā)送給B端喷舀,此時(shí)B端再用自己的私有密匙進(jìn)行消息解密,B向A發(fā)送消息時(shí)為同樣的道理淋肾。
2.關(guān)于公鑰私鑰和數(shù)字簽名硫麻, 通過一個(gè)發(fā)送郵件的故事讓大家有一個(gè)深刻的理解,非常棒的案例:
http://www.blogjava.net/yxhxj2006/archive/2012/10/15/389547.html
看完這個(gè)之后樊卓, 相信你會(huì)明白非對稱加密在網(wǎng)絡(luò)傳輸中的安全性的體現(xiàn)拿愧, 當(dāng)然就是之前談到的https。
總而言之:公鑰與私鑰的作用是:用公鑰加密的內(nèi)容只能用私鑰解密碌尔,用私鑰加密的內(nèi)容只能 用公鑰解密浇辜。公鑰加密私鑰解密, 沒問題,也可以說是"公共密鑰加密系統(tǒng)"私鑰加密公鑰解密,一般不這么說唾戚,應(yīng)叫"私鑰簽名,公鑰驗(yàn)證",也可以說是“公共密鑰簽名系統(tǒng)”
引用一段總結(jié)的話:
公鑰加密私鑰解密柳洋, 沒問題,也可以說是"公共密鑰加密系統(tǒng)"私鑰加密公鑰解密,一般不這么說,應(yīng)叫"私鑰簽名,公鑰驗(yàn)證",也可以說是“公共密鑰簽名系統(tǒng)”再來說一下"公共密鑰簽名系統(tǒng)"目的:(如果暈就多看幾遍叹坦,這個(gè)沒搞清熊镣,后面的代碼就更暈)A欲傳(信息)給B,但又怕B不確信該信息是A發(fā)的募书。
1.A選計(jì)算(信息)的HASH值绪囱,如用MD5方式計(jì)算,得到:[MD5(信息)]
2.然后用自已的私鑰加密HASH值,得到:[私鑰(MD5(信息))]
3.最后將信息與密文一起傳給B:傳給B:[(信息) + 私鑰(MD5(信息))]B接到 :[(信息) + 私鑰(MD5(信息))]
1.先用相同的HASH算法算出(信息)的HASH值莹捡,這里也使用MD5方式 得到: [MD5(信息)!]
2. 再用A的公鑰解密 [ 私鑰(MD5(信息))] [公鑰(私鑰(MD5(信息)))] = [(MD5(信息)] 如能解開,證明該 [ 私鑰(MD5(信息))]是A發(fā)送的3.再比效[MD5(信息)!]與[(MD5(信息)] 如果相同,表示(信息)在傳遞過程中沒有被他人修改過
OK, 到現(xiàn)在為止鬼吵, 你已經(jīng)懂得了公鑰, 私鑰道盏, 以及數(shù)字證書的概念了而柑, 當(dāng)然你也知道什么是對稱加密和非對稱加密,有可能你不是很清楚荷逞,為了讓你更清楚媒咳,給你再講個(gè)活生生的例子,這個(gè)例子還要從我的戀愛說起种远, 高中的時(shí)候喜歡上一個(gè)女生涩澡, 那時(shí)候青春年少,還喜歡用紙質(zhì)給她寫情書坠敷, 每天寫一些“透明的”文字很繁瑣妙同,于是有一天射富,我忽然一個(gè)念想,把情書改成用漢語拼音寫abcd……xyz, 原來字母是a就用z代替粥帚,b用y代替胰耗,c用x代替,……z用a代替芒涡, 這樣柴灯,一個(gè)只有我們倆能看的懂的情書就這樣誕生了。其實(shí)現(xiàn)在想想费尽, 這不正是一種對稱式加密么赠群。哈哈。
說完了故事旱幼,再來普及下一點(diǎn)簡單的知識(shí)嘍
3幾種對稱性加密算法:AES,DES,3DES
DES是一種分組數(shù)據(jù)加密技術(shù)(先將數(shù)據(jù)分成固定長度的小數(shù)據(jù)塊查描,之后進(jìn)行加密),速度較快柏卤,適用于大量數(shù)據(jù)加密冬三,而3DES是一種基于DES的加密算法,使用3個(gè)不同密匙對同一個(gè)分組數(shù)據(jù)塊進(jìn)行3次加密闷旧,如此以使得密文強(qiáng)度更高长豁。
相較于DES和3DES算法而言,AES算法有著更高的速度和資源使用效率忙灼,安全級別也較之更高了匠襟,被稱為下一代加密標(biāo)準(zhǔn)。對于具體的算法我們不做深入的了解该园, 之前有一篇文章寫得很好酸舍, 由于時(shí)間問題, 我就不給大家找了里初。
4幾種非對稱性加密算法:RSA,DSA,ECC
RSA和DSA的安全性及其它各方面性能都差不多啃勉,而ECC較之則有著很多的性能優(yōu)越,包括處理速度双妨,帶寬要求淮阐,存儲(chǔ)空間等等
5幾種線性散列算法(簽名算法):MD5,SHA1,HMAC
這幾種算法只生成一串不可逆的密文,經(jīng)常用其效驗(yàn)數(shù)據(jù)傳輸過程中是否經(jīng)過修改刁品,因?yàn)橄嗤纳伤惴▽τ谕幻魑闹粫?huì)生成唯一的密文泣特,若相同算法生成的密文不同,則證明傳輸數(shù)據(jù)進(jìn)行過了修改挑随。通常在數(shù)據(jù)傳說過程前状您,使用MD5和SHA1算法均需要發(fā)送和接收數(shù)據(jù)雙方在數(shù)據(jù)傳送之前就知道密匙生成算法,而HMAC與之不同的是需要生成一個(gè)密匙,發(fā)送方用此密匙對數(shù)據(jù)進(jìn)行摘要處理(生成密文)膏孟,接收方再利用此密匙對接收到的數(shù)據(jù)進(jìn)行摘要處理眯分,再判斷生成的密文是否相同。
6對于各種加密算法的選用
由于對稱加密算法的密鑰管理是一個(gè)復(fù)雜的過程柒桑,密鑰的管理直接決定著他的安全性弊决,因此當(dāng)數(shù)據(jù)量很小時(shí),我們可以考慮采用非對稱加密算法魁淳。
在實(shí)際的操作過程中我們通常采用的方式是:采用非對稱加密算法管理對稱算法的密鑰丢氢,然后用對稱加密算法加密數(shù)據(jù),這樣我們就集成了兩類加密算法的優(yōu)點(diǎn)先改,既實(shí)現(xiàn)了加密速度快的優(yōu)點(diǎn),又實(shí)現(xiàn)了安全方便管理密鑰的優(yōu)點(diǎn)蒸走。如果在選定了加密算法后仇奶,那采用多少位的密鑰呢?一般來說比驻,密鑰越長该溯,運(yùn)行的速度就越慢,應(yīng)該根據(jù)的我們實(shí)際需要的安全級別來選擇别惦,一般來說狈茉,RSA建議采用1024位的數(shù)字,ECC建議采用160位掸掸,AES采用128為即可氯庆。
需要注意的是:
哈希函數(shù),比如MD5,SHA,這些都不是加密算法扰付。要注意他們的區(qū)別和用途堤撵,很多網(wǎng)友都把md5說成是加密算法,這是嚴(yán)重不正確的啊羽莺。哈希函數(shù):MD5实昨,SHA 是沒有密鑰的,相當(dāng)與指紋的概念盐固,因此也是不可逆的荒给; md5是128位的,SHA有不同的算法刁卜,有128志电,256等位。长酗。溪北。如SHA-256,SHA-384然后 就是 Base64,這更加不屬于加密算法的范圍了,它只是將byte[]數(shù)組進(jìn)行了轉(zhuǎn)換,為什么要轉(zhuǎn)換呢之拨?就是因?yàn)楹芏嗉用芎蟮拿芪暮笳咭恍┨厥獾腷yte[]數(shù)組需要顯示出來茉继,或者需要進(jìn)行傳遞(電子郵件),但是直接轉(zhuǎn)換就會(huì)導(dǎo)致很多不可顯示的字符蚀乔,會(huì)丟失一些信息烁竭,因此就轉(zhuǎn)換位Base64編碼,這些都是可顯示的字符吉挣。所以轉(zhuǎn)換后派撕,長度會(huì)增加。它是可逆的睬魂。 再就是 3DES,DES 這才是加密算法终吼,因此也是可逆的,加解密需要密鑰,也就是你說的key最后是 RSA ,這是公鑰密碼氯哮,也就是加密和解密密鑰不同际跪,也是可逆的。
羅列了這么多知識(shí)點(diǎn)喉钢, 我想這篇文章你應(yīng)該有收藏的必要了吧姆打,為了更形象,更好玩肠虽, 我從網(wǎng)上找了一些在線工具:
1.1-Base64
http://www1.tc711.com/tool/BASE64.htm
可以按出來這是可逆的編解碼幔戏,注意不是加密幺!K翱巍闲延!
1.2-MD5
http://tool.chinaz.com/Tools/MD5.aspx?q=32324&md5type=1
其實(shí)這個(gè)也不能叫加密工具幺,今晚寫到這里吧韩玩, 眼睛很累了慨代,明天把這篇文章寫完。
1.3-SHA-1,SHA-2,SHA-256,SHA-512,SHA-3
好吧啸如,哈希的工具找到了一個(gè)更好的工具連接侍匙,里面也有MD5.里面還有哈希的一些說明。
http://www.atool.org/hash.php 這個(gè)鏈接值的收藏一下叮雳, 主要是用到哈希的時(shí)候可以經(jīng)常用想暗。
2.1 AES DES
以上我們主要說了哈希算法和數(shù)字證書的一些知識(shí), 現(xiàn)在我們看一下對稱加密的一些在線工具
DES http://e-file.arkoo.com/tools/des3.htm
這個(gè)鏈接可謂非常干凈好用帘不,形象直觀可逆過程说莫,哈哈。
AES http://www.seacha.com/tools/aes.html
忽然發(fā)現(xiàn)這個(gè)在線工具也還湊合http://encode.chahuo.com/
如此般寞焙, 對稱加密基本上都弄完了储狭,現(xiàn)在我們只簡單的了解下非對稱加解密的RSA,上面的過程我們已經(jīng)說的非常詳細(xì)了吧互婿。重點(diǎn)已經(jīng)用黑色字體標(biāo)注出來了。
加密數(shù)據(jù)
RSAEncryptor *rsa = [[RSAEncryptor alloc] init];
NSLog(@"encryptor using rsa");
NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"];
NSLog(@"public key: %@", publicKeyPath);
[rsa loadPublicKeyFromFile:publicKeyPath];
NSString *securityText = @"hello ~";
NSString *encryptedString = [rsa rsaEncryptString:securityText];
NSLog(@"encrypted data: %@", encryptedString);
解密數(shù)據(jù)在
iOS下解碼需要先加載private key, 之后在對數(shù)據(jù)解碼. 解碼的時(shí)候先進(jìn)行Base64 decode, 之后在用private key decrypt加密數(shù)據(jù).
NSLog(@"decryptor using rsa");
[rsa loadPrivateKeyFromFile:[[NSBundle mainBundle] pathForResource:@"private_key" ofType:@"p12"] password:@"123456"];
NSString *decryptedString = [rsa rsaDecryptString:encryptedString];
NSLog(@"decrypted data: %@", decryptedString);
具體詳細(xì)文章可以參考鏈接
http://witcheryne.iteye.com/blog/2171850
http://www.cocoachina.com/bbs/read.php?tid=166990
在支付寶支付過程中就使用了RSA加密辽狈。
在在這里有必要提醒下小編自己慈参, 有時(shí)間需要研究下蘋果證書的工作機(jī)制。
弄到這里刮萌, 我主要是找一些代碼給大家用驮配,看看我自己先建一個(gè)工程吧。
// Created by Lcq on 15/12/16.
// Copyright ? 2015年 Lcq. All rights reserved.
#import @interface Helper : NSObject`
//MD5
+ (NSString *) md5:(NSString *)str;
//Base64
+ (NSString *)base64StringFromText:(NSString *)text;
+ (NSString *)textFromBase64String:(NSString *)base64;
+ (NSString *)base64EncodedStringFrom:(NSData *)data;
//DES加密
+(NSString *)encryptSting:(NSString *)sText key:(NSString *)key andDesiv:(NSString *)ivDes;
//DES解密
+(NSString *)decryptWithDESString:(NSString *)sText key:(NSString *)key andiV:(NSString *)iv;
//AES加密
+ (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data;
//AES解密
+ (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data;
@end
#import "Helper.h"
#import #importstatic const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define LocalStr_None @""
@implementation Helper
//Md5
+ (NSString *) md5:(NSString *)str {
if (str == nil) {
return nil;
}
const char *cStr = [str UTF8String];
unsigned char result[16];
CC_MD5( cStr, strlen(cStr), result );
return [NSString stringWithFormat:
@"XXXXXXXXXXXXXXXX",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
//轉(zhuǎn)化為Base64
+ (NSString *)base64StringFromText:(NSString *)text
{
if (text && ![text isEqualToString:LocalStr_None]) {
//取項(xiàng)目的bundleIdentifier作為KEY 改動(dòng)了此處
//NSString *key = [[NSBundle mainBundle] bundleIdentifier];
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
//IOS 自帶DES加密 Begin 改動(dòng)了此處
//data = [self DESEncrypt:data WithKey:key];
//IOS 自帶DES加密 End
return [self base64EncodedStringFrom:data];
}
else {
return LocalStr_None;
}
}
//由base64轉(zhuǎn)化
+ (NSString *)textFromBase64String:(NSString *)base64
{
if (base64 && ![base64 isEqualToString:LocalStr_None]) {
//取項(xiàng)目的bundleIdentifier作為KEY 改動(dòng)了此處
//NSString *key = [[NSBundle mainBundle] bundleIdentifier];
NSData *data = [self dataWithBase64EncodedString:base64];
//IOS 自帶DES解密 Begin 改動(dòng)了此處
//data = [self DESDecrypt:data WithKey:key];
//IOS 自帶DES加密 End
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
else {
return LocalStr_None;
}
}
//DES加密
+(NSString *)encryptSting:(NSString *)sText key:(NSString *)key andDesiv:(NSString *)ivDes
{
if ((sText == nil || sText.length == 0)
|| (sText == nil || sText.length == 0)
|| (ivDes == nil || ivDes.length == 0)) {
return @"";
}
//gb2312 編碼
NSStringEncoding encoding =CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSData* encryptData = [sText dataUsingEncoding:encoding];
size_t dataInLength = [encryptData length];
const void * dataIn = (const void *)[encryptData bytes];
CCCryptorStatus ccStatus = nil;
uint8_t *dataOut = NULL; //可以理解位type/typedef 的縮寫(有效的維護(hù)了代碼着茸,比如:一個(gè)人用int壮锻,一個(gè)人用long。最好用typedef來定義)
size_t dataOutMoved = 0;
size_t dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1); dataOut = malloc( dataOutAvailable * sizeof(uint8_t));
memset((void *)dataOut, 0x0, dataOutAvailable);//將已開辟內(nèi)存空間buffer的首 1 個(gè)字節(jié)的值設(shè)為值 0
const void *iv = (const void *) [ivDes cStringUsingEncoding:NSASCIIStringEncoding];
//CCCrypt函數(shù) 加密/解密
ccStatus = CCCrypt(kCCEncrypt,// 加密/解密
kCCAlgorithmDES,// 加密根據(jù)哪個(gè)標(biāo)準(zhǔn)(des涮阔,3des猜绣,aes。敬特。途事。。)
kCCOptionPKCS7Padding,// 選項(xiàng)分組密碼算法(des:對每塊分組加一次密 3DES:對每塊分組加三個(gè)不同的密)
[key UTF8String], //密鑰 加密和解密的密鑰必須一致
kCCKeySizeDES,// DES 密鑰的大猩眯摺(kCCKeySizeDES=8)
iv, // 可選的初始矢量
dataIn, // 數(shù)據(jù)的存儲(chǔ)單元
dataInLength,// 數(shù)據(jù)的大小
(void *)dataOut,// 用于返回?cái)?shù)據(jù)
dataOutAvailable,
&dataOutMoved);
//編碼 base64
NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved];
Byte *bytes = (Byte *)[data bytes];
//下面是Byte 轉(zhuǎn)換為16進(jìn)制。
NSString *hexStr=@"";
for(int i=0;i<[data length];i++){
NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16進(jìn)制數(shù)
if([newHexStr length]==1)
hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
else
hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
}
free(dataOut);
return hexStr;
}
//DES解密
+(NSString *)decryptWithDESString:(NSString *)sText key:(NSString *)key andiV:(NSString *)iv
{
if ((sText == nil || sText.length == 0)
|| (sText == nil || sText.length == 0)
|| (iv == nil || iv.length == 0)) {
return @"";
}
const void *dataIn;
size_t dataInLength;
char *myBuffer = (char *)malloc((int)[sText length] / 2 + 1);
bzero(myBuffer, [sText length] / 2 + 1);
for (int i = 0; i < [sText length] - 1; i += 2) {
unsigned int anInt;
NSString * hexCharStr = [sText substringWithRange:NSMakeRange(i, 2)];
NSScanner * scanner = [[NSScanner alloc] initWithString:hexCharStr];
[scanner scanHexInt:&anInt];
myBuffer[i / 2] = (char)anInt;
}
NSData *decryptData =[NSData dataWithBytes:myBuffer length:[sText length] / 2 ];//轉(zhuǎn)成utf-8并decode
dataInLength = [decryptData length];
dataIn = [decryptData bytes];
free(myBuffer);
CCCryptorStatus ccStatus = nil;
uint8_t *dataOut = NULL; //可以理解位type/typedef 的縮寫(有效的維護(hù)了代碼义图,比如:一個(gè)人用int减俏,一個(gè)人用long。最好用typedef來定義)
size_t dataOutAvailable = 0; //size_t 是操作符sizeof返回的結(jié)果類型
size_t dataOutMoved = 0;
dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);
dataOut = malloc( dataOutAvailable * sizeof(uint8_t));
memset((void *)dataOut, 0x0, dataOutAvailable);//將已開辟內(nèi)存空間buffer的首 1 個(gè)字節(jié)的值設(shè)為值 0
const void *ivDes = (const void *) [iv cStringUsingEncoding:NSASCIIStringEncoding];
//CCCrypt函數(shù) 加密/解密
ccStatus = CCCrypt(kCCDecrypt,// 加密/解密
kCCAlgorithmDES,// 加密根據(jù)哪個(gè)標(biāo)準(zhǔn)(des碱工,3des娃承,aes。怕篷。历筝。。)
kCCOptionPKCS7Padding,// 選項(xiàng)分組密碼算法(des:對每塊分組加一次密 3DES:對每塊分組加三個(gè)不同的密)
[key UTF8String], //密鑰 加密和解密的密鑰必須一致
kCCKeySizeDES,// DES 密鑰的大欣任健(kCCKeySizeDES=8)
ivDes, // 可選的初始矢量
dataIn, // 數(shù)據(jù)的存儲(chǔ)單元
dataInLength,// 數(shù)據(jù)的大小
(void *)dataOut,// 用于返回?cái)?shù)據(jù)
dataOutAvailable,
&dataOutMoved);
NSStringEncoding encoding =CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
NSString *result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:encoding];
free(dataOut);
return result;
}
//AES加密
+ (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data
{
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
bzero(ivPtr, sizeof(ivPtr));
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
int newSize = 0;
if(diff > 0)
{
newSize = (int)(dataLength + diff);
}
char dataPtr[newSize];
memcpy(dataPtr, [data bytes], [data length]);
for(int i = 0; i < diff; i++)
{
dataPtr[i + dataLength] = 0x00;
}
size_t bufferSize = newSize + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
0x00, //No padding
keyPtr,
kCCKeySizeAES128,
ivPtr,
dataPtr,
sizeof(dataPtr),
buffer,
bufferSize,
&numBytesEncrypted);
if(cryptStatus == kCCSuccess)
{
// NSData *data =[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
// NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
return nil;
}
//AES解密
+ (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv withNSData:(NSData *)data
{
char keyPtr[kCCKeySizeAES128+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
char ivPtr[kCCKeySizeAES128+1];
bzero(ivPtr, sizeof(ivPtr));
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
kCCAlgorithmAES128,
0x00, //No padding
keyPtr,
kCCKeySizeAES128,
ivPtr,
[data bytes],
dataLength,
buffer,
bufferSize,
&numBytesEncrypted);
if(cryptStatus == kCCSuccess)
{
// NSData *data =[NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
// NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
return nil;
}
/******************************************************************************
函數(shù)名稱 : + (NSData *)dataWithBase64EncodedString:(NSString *)string
函數(shù)描述 : base64格式字符串轉(zhuǎn)換為文本數(shù)據(jù)
輸入?yún)?shù) : (NSString *)string
輸出參數(shù) : N/A
返回參數(shù) : (NSData *)
備注信息 :
******************************************************************************/
+ (NSData *)dataWithBase64EncodedString:(NSString *)string
{
if (string == nil)
[NSException raise:NSInvalidArgumentException format:nil];
if ([string length] == 0)
return [NSData data];
static char *decodingTable = NULL;
if (decodingTable == NULL)
{
decodingTable = malloc(256);
if (decodingTable == NULL)
return nil;
memset(decodingTable, CHAR_MAX, 256);
NSUInteger i;
for (i = 0; i < 64; i++)
decodingTable[(short)encodingTable[i]] = i;
}
const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL) // Not an ASCII string!
return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (YES)
{
char buffer[4];
short bufferLength;
for (bufferLength = 0; bufferLength < 4; i++)
{
if (characters[i] == '\0')
break;
if (isspace(characters[i]) || characters[i] == '=')
continue;
buffer[bufferLength] = decodingTable[(short)characters[i]];
if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
{
free(bytes);
return nil;
}
}
if (bufferLength == 0)
break;
if (bufferLength == 1) // At least two characters are needed to produce one byte!
{
free(bytes);
return nil;
}
// Decode the characters in the buffer to bytes.
bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
if (bufferLength > 2)
bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
if (bufferLength > 3)
bytes[length++] = (buffer[2] << 6) | buffer[3];
}
bytes = realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}
/******************************************************************************
函數(shù)名稱 : + (NSString *)base64EncodedStringFrom:(NSData *)data
函數(shù)描述 : 文本數(shù)據(jù)轉(zhuǎn)換為base64格式字符串
輸入?yún)?shù) : (NSData *)data
輸出參數(shù) : N/A
返回參數(shù) : (NSString *)
備注信息 :
******************************************************************************/
+ (NSString *)base64EncodedStringFrom:(NSData *)data
{
if ([data length] == 0)
return @"";
char *characters = malloc((([data length] + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [data length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [data length])
buffer[bufferLength++] = ((char *)[data bytes])[i++];
// Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}
@end
以上是接口和實(shí)現(xiàn)文件注益, 現(xiàn)在我們來看看調(diào)用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//MD5
NSString *md5Str = [Helper md5:@"我愛你"];
NSLog(@"md5Str is %@",md5Str);//Log is 4F2016C6B934D55BD7120E5D0E62CCE3
//Base64
NSString *Base64Str = [Helper base64StringFromText:@"我愛你"];
NSLog(@"Base64Str is %@",Base64Str);//Log is 5oiR54ix5L2g
NSString *oriBase64Str = [Helper textFromBase64String:Base64Str];
NSLog(@"oriBase64Str is %@",oriBase64Str);//Log is 我愛你
//DES
NSString *desEnStr = [Helper encryptSting:@"我愛你" key:@"521" andDesiv:@"521"];
NSLog(@"desEnStr is %@",desEnStr);//Log is 389280aa791ee933
NSString *desDeStr =[Helper decryptWithDESString:desEnStr key:@"521" andiV:@"521"];
NSLog(@"desDeStr is %@",desDeStr);//Log is 我愛你
//AES
NSData *aesEnData = [Helper AES128EncryptWithKey:@"521" iv:@"521" withNSData:[@"我愛你" dataUsingEncoding:NSUTF8StringEncoding]];
NSString *aesEnStr = [Helper base64EncodedStringFrom:aesEnData];
NSLog(@"aesEnStr is %@",aesEnStr);//Log is HZKhnRLlQ8XjMjpelOAwsQ==
NSData *aesDeData = [Helper AES128DecryptWithKey:@"521" iv:@"521" withNSData:aesEnData];
NSString *aesDEStr = [Helper base64EncodedStringFrom:aesDeData];
NSString *result = [Helper textFromBase64String:aesDEStr];
NSLog(@"aesDEStr is %@ and result is %@",aesDEStr,result);//Log is aesDEStr is 5oiR54ix5L2gAAAAAAAAAA== and result is 我愛你
return YES;
}
寫到這里搭幻, 產(chǎn)生了一個(gè)問題, 就是上面的AES加密最終生成的Base64字符串和工具不一樣 ,不知道是什么問題浙垫, 還請高手幫忙解答一下。
大家也可以嘗試下網(wǎng)上其他人的代碼
//AES可以參考一個(gè)鏈接 http://www.tuicool.com/articles/UVRjmyN
好了盹沈, 文章的最后敦捧,我們來簡單學(xué)習(xí)和了解下cookie在客戶端里的應(yīng)用
首先帶大家了解下什么是cookie吧
這是維基百科里一段對cookie的描述,可見cookie是服務(wù)器生成的發(fā)給客戶端榛鼎,具體應(yīng)用例如:我們打開淘寶的某一個(gè)頁面逃呼,登陸了賬號(hào)和密碼鳖孤, 當(dāng)我們再跳轉(zhuǎn)到其他淘寶界面的時(shí)候,我們不必每一次都重新登陸界面抡笼, 這就是cookie的作用苏揣, 其實(shí)cookie還能記錄用戶選的訂單, 至于深一層的了解蔫缸, 我還不是很清楚腿准, 因?yàn)闆]有學(xué)過前端的開發(fā),感興趣的讀者可以自行了解拾碌。
其實(shí)cookie也可以在客戶端使用的吐葱。NSHTTPCookieStorage在iOS上是一個(gè)單例。那么首先我們通過代碼的方式看看怎么添加cookie和刪除cookie校翔,
///增加cookies
+ (void)addCookiesToRequest:(NSMutableDictionary *)cookieDic
{
NSEnumerator * enumeratorKey = [cookieDic keyEnumerator];
for (NSObject * key in enumeratorKey) {
NSHTTPCookie *userInfoCookie = [NSHTTPCookie cookieWithProperties:
[NSDictionary dictionaryWithObjectsAndKeys:
@".baidu.com", NSHTTPCookieDomain,
@"/", NSHTTPCookiePath,
[NSString stringWithFormat:@"%@",key], NSHTTPCookieName,
[NSDate dateWithTimeIntervalSinceNow:30*24*3600], NSHTTPCookieExpires,
[NSString stringWithFormat:@"%@",[cookieDic objectForKey:key]], NSHTTPCookieValue,
nil]];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:userInfoCookie];
NSHTTPCookie *txdaiCookie = [NSHTTPCookie cookieWithProperties:
[NSDictionary dictionaryWithObjectsAndKeys:
@".jingdong.com", NSHTTPCookieDomain,
@"/", NSHTTPCookiePath,
[NSString stringWithFormat:@"%@",key], NSHTTPCookieName,
[NSDate dateWithTimeIntervalSinceNow:30*24*3600], NSHTTPCookieExpires,
[NSString stringWithFormat:@"%@",[cookieDic objectForKey:key]], NSHTTPCookieValue,
nil]];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:txdaiCookie];
}
}
同樣刪除cookie也非常簡單
///刪除基本cookies
+(void)deleteBaseCookie{
NSHTTPCookie *passportCookie = [NSHTTPCookie cookieWithProperties:
[NSDictionary dictionaryWithObjectsAndKeys:
@".baidu.com", NSHTTPCookieDomain,
@"/", NSHTTPCookiePath,
@"sfut", NSHTTPCookieName,
@"", NSHTTPCookieValue,
nil]];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:passportCookie];
NSHTTPCookie *txdaiCookie = [NSHTTPCookie cookieWithProperties:
[NSDictionary dictionaryWithObjectsAndKeys:
@".jingdong.com", NSHTTPCookieDomain,
@"/", NSHTTPCookiePath,
@"sfut", NSHTTPCookieName,
@"", NSHTTPCookieValue,
nil]];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:txdaiCookie];
}
那么最后一個(gè)問題就是我們在客戶端什么情況下才添加或者刪除cookie呢弟跑。
當(dāng)我們的應(yīng)用在加載一個(gè)wap頁面的時(shí)候,可能wap需要知道客戶端的一些信息防症, 比如你是登陸狀態(tài)還是什么狀態(tài)孟辑,因?yàn)檫@時(shí)候我們就可以設(shè)置cookie,wap可以拿到請求的cookie
當(dāng)然需要注意的是在wap將要銷毀的時(shí)候,要把cookie信息給移除掉蔫敲。
本篇文章轉(zhuǎn)載自:http://www.cocoachina.com/ios/20151231/14835.html