移動端的加解密

首先羅列一些知識點:

1.加密算法通常分為對稱性加密算法和非對稱性加密算法:對于對稱性加密算法强衡,信息接收雙方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是對數(shù)據(jù)進(jìn)行 加解密了。非對稱算法與之不同违寿,發(fā)送雙方A,B事先均生成一堆密匙,然后A將自己的公有密匙發(fā)送給B,B將自己的公有密匙發(fā)送給A胸蛛,如果A要給B發(fā)送消息,則先需要用B的公有密匙進(jìn)行消息加密樱报,然后發(fā)送給B端葬项,此時B端再用自己的私有密匙進(jìn)行消息解密,B向A發(fā)送消息時為同樣的道理迹蛤。

2.關(guān)于公鑰私鑰和數(shù)字簽名民珍, 通過一個發(fā)送郵件的故事讓大家有一個深刻的理解,非常棒的案例:

相信你會明白非對稱加密在網(wǎng)絡(luò)傳輸中的安全性的體現(xiàn)盗飒, 當(dāng)然就是之前談到的https嚷量。

總而言之:公鑰與私鑰的作用是:用公鑰加密的內(nèi)容只能用私鑰解密,用私鑰加密的內(nèi)容只能 用公鑰解密逆趣。公鑰加密私鑰解密津肛, 沒問題,也可以說是"公共密鑰加密系統(tǒng)"私鑰加密公鑰解密,一般不這么說,應(yīng)叫"私鑰簽名,公鑰驗證",也可以說是“公共密鑰簽名系統(tǒng)”

引用一段總結(jié)的話:

公鑰加密私鑰解密汗贫, 沒問題,也可以說是"公共密鑰加密系統(tǒng)"私鑰加密公鑰解密,一般不這么說身坐,應(yīng)叫"私鑰簽名,公鑰驗證",也可以說是“公共密鑰簽名系統(tǒng)”再來說一下"公共密鑰簽名系統(tǒng)"目的:(如果暈就多看幾遍,這個沒搞清落包,后面的代碼就更暈)A欲傳(信息)給B部蛇,但又怕B不確信該信息是A發(fā)的。1.A選計算(信息)的HASH值咐蝇,如用MD5方式計算,得到:[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)然你也知道什么是對稱加密和非對稱加密警绩,有可能你不是很清楚崇败,為了讓你更清楚,給你再講個活生生的例子肩祥,這個例子還要從我的戀愛說起后室, 高中的時候喜歡上一個女生, 那時候青春年少混狠,還喜歡用紙質(zhì)給她寫情書岸霹, 每天寫一些“透明的”文字很繁瑣,于是有一天将饺,我忽然一個念想贡避,把情書改成用漢語拼音寫abcd……xyz, 原來字母是a就用z代替,b用y代替予弧,c用x代替刮吧,……z用a代替, 這樣桌肴,一個只有我們倆能看的懂的情書就這樣誕生了皇筛。其實現(xiàn)在想想琉历, 這不正是一種對稱式加密么坠七。哈哈。

說完了故事旗笔,再來普及下一點簡單的知識嘍

3.幾種對稱性加密算法:AES,DES,3DES

DES是一種分組數(shù)據(jù)加密技術(shù)(先將數(shù)據(jù)分成固定長度的小數(shù)據(jù)塊彪置,之后進(jìn)行加密),速度較快蝇恶,適用于大量數(shù)據(jù)加密拳魁,而3DES是一種基于DES的加密算法,使用3個不同密匙對同一個分組數(shù)據(jù)塊進(jìn)行3次加密撮弧,如此以使得密文強度更高潘懊。

相較于DES和3DES算法而言,AES算法有著更高的速度和資源使用效率贿衍,安全級別也較之更高了授舟,被稱為下一代加密標(biāo)準(zhǔn)。對于具體的算法我們不做深入的了解贸辈, 之前有一篇文章寫得很好释树, 由于時間問題, 我就不給大家找了。

4.幾種非對稱性加密算法:RSA,DSA,ECC

RSA和DSA的安全性及其它各方面性能都差不多奢啥,而ECC較之則有著很多的性能優(yōu)越秸仙,包括處理速度捧杉,帶寬要求弟跑,存儲空間等等

5.幾種線性散列算法(簽名算法):MD5,SHA1,HMAC

這幾種算法只生成一串不可逆的密文,經(jīng)常用其效驗數(shù)據(jù)傳輸過程中是否經(jīng)過修改夭织,因為相同的生成算法對于同一明文只會生成唯一的密文正驻,若相同算法生成的密文不同弊攘,則證明傳輸數(shù)據(jù)進(jìn)行過了修改。通常在數(shù)據(jù)傳說過程前姑曙,使用MD5和SHA1算法均需要發(fā)送和接收數(shù)據(jù)雙方在數(shù)據(jù)傳送之前就知道密匙生成算法襟交,而HMAC與之不同的是需要生成一個密匙,發(fā)送方用此密匙對數(shù)據(jù)進(jìn)行摘要處理(生成密文)伤靠,接收方再利用此密匙對接收到的數(shù)據(jù)進(jìn)行摘要處理捣域,再判斷生成的密文是否相同。

6.對于各種加密算法的選用

由于對稱加密算法的密鑰管理是一個復(fù)雜的過程宴合,密鑰的管理直接決定著他的安全性焕梅,因此當(dāng)數(shù)據(jù)量很小時,我們可以考慮采用非對稱加密算法卦洽。

在實際的操作過程中我們通常采用的方式是:采用非對稱加密算法管理對稱算法的密鑰贞言,然后用對稱加密算法加密數(shù)據(jù),這樣我們就集成了兩類加密算法的優(yōu)點阀蒂,既實現(xiàn)了加密速度快的優(yōu)點该窗,又實現(xiàn)了安全方便管理密鑰的優(yōu)點。如果在選定了加密算法后蚤霞,那采用多少位的密鑰呢酗失?一般來說,密鑰越長昧绣,運行的速度就越慢规肴,應(yīng)該根據(jù)的我們實際需要的安全級別來選擇,一般來說夜畴,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)換呢?就是因為很多加密后的密文后者一些特殊的byte[]數(shù)組需要顯示出來痒玩,或者需要進(jìn)行傳遞(電子郵件)淳附,但是直接轉(zhuǎn)換就會導(dǎo)致很多不可顯示的字符,會丟失一些信息蠢古,因此就轉(zhuǎn)換位Base64編碼奴曙,這些都是可顯示的字符。所以轉(zhuǎn)換后草讶,長度會增加洽糟。它是可逆的。 再就是 3DES,DES 這才是加密算法堕战,因此也是可逆的坤溃,加解密需要密鑰,也就是你說的key最后是 RSA ,這是公鑰密碼,也就是加密和解密密鑰不同践啄,也是可逆的浇雹。

羅列了這么多知識點沉御, 我想這篇文章你應(yīng)該有收藏的必要了吧屿讽,為了更形象,更好玩吠裆, 我從網(wǎng)上找了一些在線工具

1.1-Base64

http://www1.tc711.com/tool/BASE64.htm


1.2-MD5

http://tool.chinaz.com/Tools/MD5.aspx?q=32324&md5type=1


1.3-SHA-1,SHA-2,SHA-256,SHA-512,SHA-3

好吧伐谈,哈希的工具找到了一個更好的工具連接,里面也有MD5.里面還有哈希的一些說明试疙。

http://www.atool.org/hash.php這個鏈接值的收藏一下诵棵, 主要是用到哈希的時候可以經(jīng)常用。

2.1 AES DES

以上我們主要說了哈希算法和數(shù)字證書的一些知識祝旷, 現(xiàn)在我們看一下對稱加密的一些在線工具

DEShttp://e-file.arkoo.com/tools/des3.htm

AEShttp://www.seacha.com/tools/aes.html


如此般履澳, 對稱加密基本上都弄完了嘶窄,現(xiàn)在我們只簡單的了解下非對稱加解密的RSA,上面的過程我們已經(jīng)說的非常詳細(xì)了吧。重點已經(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ù)解碼. 解碼的時候先進(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);

在支付寶支付過程中就使用了RSA加密柄冲。

在在這里有必要提醒下小編自己, 有時間需要研究下蘋果證書的工作機制忠蝗。

弄到這里现横, 我主要是找一些代碼給大家用,看看我自己先建一個工程吧阁最。

#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

3

#import?"Helper.h"

#import?#importstatic?const?char?encodingTable[]?=?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

#define?LocalStr_None??@""

@implementation?Helper

//Md5

+?(NSString?*)?md5:(NSString?*)str?{

if(str?==?nil)?{

returnnil;

}

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])?{

取項目的bundleIdentifier作為KEY??改動了此處

NSString?*key?=?[[NSBundle?mainBundle]?bundleIdentifier];

NSData?*data?=?[text?dataUsingEncoding:NSUTF8StringEncoding];

IOS?自帶DES加密?Begin??改動了此處

data?=?[self?DESEncrypt:data?WithKey:key];

IOS?自帶DES加密?End

return[self?base64EncodedStringFrom:data];

}

else{

returnLocalStr_None;

}

}

由base64轉(zhuǎn)化

+?(NSString?*)textFromBase64String:(NSString?*)base64

{

if(base64?&&?![base64?isEqualToString:LocalStr_None])?{

取項目的bundleIdentifier作為KEY???改動了此處

NSString?*key?=?[[NSBundle?mainBundle]?bundleIdentifier];

NSData?*data?=?[self?dataWithBase64EncodedString:base64];

IOS?自帶DES解密?Begin????改動了此處

data?=?[self?DESDecrypt:data?WithKey:key];

IOS?自帶DES加密?End

return[[NSString?alloc]?initWithData:data?encoding:NSUTF8StringEncoding];

}

else{

returnLocalStr_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ù)了代碼戒祠,比如:一個人用int,一個人用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?個字節(jié)的值設(shè)為值?0

const?void?*iv?=?(const?void?*)?[ivDes?cStringUsingEncoding:NSASCIIStringEncoding];

CCCrypt函數(shù)?加密/解密

ccStatus?=?CCCrypt(kCCEncrypt,加密/解密

kCCAlgorithmDES,加密根據(jù)哪個標(biāo)準(zhǔn)(des姜盈,3des,aes配阵。贩据。。闸餐。)

kCCOptionPKCS7Padding,選項分組密碼算法(des:對每塊分組加一次密??3DES:對每塊分組加三個不同的密)

[key?UTF8String],密鑰????加密和解密的密鑰必須一致

kCCKeySizeDES,DES?密鑰的大斜チ痢(kCCKeySizeDES=8)

iv,可選的初始矢量

dataIn,數(shù)據(jù)的存儲單元

dataInLength,數(shù)據(jù)的大小

(void?*)dataOut,用于返回數(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);

returnhexStr;

}

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ù)了代碼舍沙,比如:一個人用int近上,一個人用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?個字節(jié)的值設(shè)為值?0

const?void?*ivDes?=?(const?void?*)?[iv?cStringUsingEncoding:NSASCIIStringEncoding];

CCCrypt函數(shù)?加密/解密

ccStatus?=?CCCrypt(kCCDecrypt,加密/解密

kCCAlgorithmDES,加密根據(jù)哪個標(biāo)準(zhǔn)(des拂铡,3des壹无,aes。感帅。斗锭。。)

kCCOptionPKCS7Padding,選項分組密碼算法(des:對每塊分組加一次密??3DES:對每塊分組加三個不同的密)

[key?UTF8String],密鑰????加密和解密的密鑰必須一致

kCCKeySizeDES,DES?密鑰的大惺颉(kCCKeySizeDES=8)

ivDes,可選的初始矢量

dataIn,數(shù)據(jù)的存儲單元

dataInLength,數(shù)據(jù)的大小

(void?*)dataOut,用于返回數(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);

returnresult;

}

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];

}

returnnil;

}

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];

}

returnnil;

}

/******************************************************************************

函數(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)

returnnil;

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!

returnnil;

char?*bytes?=?malloc((([string?length]?+?3)?/?4)?*?3);

if(bytes?==?NULL)

returnnil;

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);

returnnil;

}

}

if(bufferLength?==?0)

break;

if(bufferLength?==?1)At?least?two?characters?are?needed?to?produce?one?byte!

{

free(bytes);

returnnil;

}

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)

returnnil;

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)];

elsecharacters[length++]?='=';

if(bufferLength?>?2)

characters[length++]?=?encodingTable[buffer[2]?&?0x3F];

elsecharacters[length++]?='=';

}

return[[NSString?alloc]?initWithBytesNoCopy:characters?length:length?encoding:NSASCIIStringEncoding?freeWhenDone:YES];

}

@end

以上是接口和實現(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?我愛你

returnYES;

}

寫到這里, 產(chǎn)生了一個問題实苞, 就是上面的AES加密最終生成的Base64字符串和工具不一樣 豺撑,不知道是什么問題, 還請高手幫忙解答一下黔牵。

了解下cookie在客戶端里的應(yīng)用

首先帶大家了解下什么是cookie吧


這是維基百科里一段對cookie的描述聪轿,可見cookie是服務(wù)器生成的發(fā)給客戶端,具體應(yīng)用例如:我們打開淘寶的某一個頁面猾浦,登陸了賬號和密碼陆错, 當(dāng)我們再跳轉(zhuǎn)到其他淘寶界面的時候灯抛,我們不必每一次都重新登陸界面, 這就是cookie的作用音瓷, 其實cookie還能記錄用戶選的訂單牧愁, 至于深一層的了解, 我還不是很清楚外莲, 因為沒有學(xué)過前端的開發(fā)猪半,感興趣的讀者可以自行了解。

其實cookie也可以在客戶端使用的偷线。NSHTTPCookieStorage在iOS上是一個單例磨确。那么首先我們通過代碼的方式看看怎么添加cookie和刪除cookie,

增加cookies

+?(void)addCookiesToRequest:(NSMutableDictionary?*)cookieDic

{

NSEnumerator?*?enumeratorKey?=?[cookieDic?keyEnumerator];

for(NSObject?*?keyinenumeratorKey)?{

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];

}

那么最后一個問題就是我們在客戶端什么情況下才添加或者刪除cookie呢声邦。

當(dāng)我們的應(yīng)用在加載一個wap頁面的時候乏奥,可能wap需要知道客戶端的一些信息, 比如你是登陸狀態(tài)還是什么狀態(tài)亥曹,因為這時候我們就可以設(shè)置cookie,wap可以拿到請求的cookie

當(dāng)然需要注意的是在wap將要銷毀的時候邓了,要把cookie信息給移除掉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末媳瞪,一起剝皮案震驚了整個濱河市骗炉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛇受,老刑警劉巖句葵,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兢仰,居然都是意外死亡乍丈,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門把将,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轻专,“玉大人,你說我怎么就攤上這事察蹲∏攵猓” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵递览,是天一觀的道長叼屠。 經(jīng)常有香客問我瞳腌,道長绞铃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任嫂侍,我火速辦了婚禮儿捧,結(jié)果婚禮上荚坞,老公的妹妹穿的比我還像新娘。我一直安慰自己菲盾,他們只是感情好颓影,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著懒鉴,像睡著了一般诡挂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上临谱,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天璃俗,我揣著相機與錄音,去河邊找鬼悉默。 笑死城豁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抄课。 我是一名探鬼主播唱星,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼跟磨!你這毒婦竟也來了间聊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤抵拘,失蹤者是張志新(化名)和其女友劉穎甸饱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仑濒,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡叹话,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了墩瞳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驼壶。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喉酌,靈堂內(nèi)的尸體忽然破棺而出热凹,到底是詐尸還是另有隱情,我是刑警寧澤泪电,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布般妙,位于F島的核電站,受9級特大地震影響相速,放射性物質(zhì)發(fā)生泄漏碟渺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一突诬、第九天 我趴在偏房一處隱蔽的房頂上張望苫拍。 院中可真熱鬧芜繁,春花似錦、人聲如沸绒极。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垄提。三九已至榔袋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間铡俐,已是汗流浹背摘昌。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留高蜂,地道東北人聪黎。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像备恤,于是被迫代替她去往敵國和親稿饰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文主要介紹移動端的加解密算法的分類露泊、其優(yōu)缺點特性及應(yīng)用喉镰,幫助讀者由淺入深地了解和選擇加解密算法。文中會包含算法的...
    蘋果粉閱讀 11,500評論 5 29
  • /**ios常見的幾種加密方法: 普通的加密方法是講密碼進(jìn)行加密后保存到用戶偏好設(shè)置( [NSUserDefaul...
    彬至睢陽閱讀 2,927評論 0 7
  • 引言 如今手機app五彩繽紛,確保手機用戶的數(shù)據(jù)安全是開發(fā)人員必須掌握的技巧沉噩,下面通過實例介紹DES在androi...
    freesan44閱讀 1,137評論 1 1
  • 各位簡友好捺宗!剛來簡書,還請關(guān)照川蒙。 近日起蚜厉,我將在簡書開始寫自己的第一個專欄,主題是微觀經(jīng)濟學(xué)畜眨。本專欄的難度介于原理...
    零敲碎打閱讀 1,231評論 0 2
  • 這里是“游賞麻將”IOS應(yīng)用的技術(shù)支持界面昼牛,如果您使用中遇到什么問題或者對我們的產(chǎn)品有什么改進(jìn)的建議,請隨時與我們...
    游賞麻將閱讀 251評論 0 0