移動端的加解密

首先羅列一些知識點:

1.加密算法通常分為對稱性加密算法和非對稱性加密算法:對于對稱性加密算法,信息接收雙方都需事先知道密匙和加解密算法且其密匙是相同的,之后便是對數據進行 加解密了。非對稱算法與之不同,發送雙方A,B事先均生成一堆密匙,然后A將自己的公有密匙發送給B,B將自己的公有密匙發送給A,如果A要給B發送消息,則先需要用B的公有密匙進行消息加密,然后發送給B端,此時B端再用自己的私有密匙進行消息解密,B向A發送消息時為同樣的道理。

2.關于公鑰私鑰和數字簽名, 通過一個發送郵件的故事讓大家有一個深刻的理解,非常棒的案例:

相信你會明白非對稱加密在網絡傳輸中的安全性的體現, 當然就是之前談到的https。

總而言之:公鑰與私鑰的作用是:用公鑰加密的內容只能用私鑰解密,用私鑰加密的內容只能 用公鑰解密。公鑰加密私鑰解密, 沒問題,也可以說是"公共密鑰加密系統"私鑰加密公鑰解密,一般不這么說,應叫"私鑰簽名,公鑰驗證",也可以說是“公共密鑰簽名系統”

引用一段總結的話:

公鑰加密私鑰解密, 沒問題,也可以說是"公共密鑰加密系統"私鑰加密公鑰解密,一般不這么說,應叫"私鑰簽名,公鑰驗證",也可以說是“公共密鑰簽名系統”再來說一下"公共密鑰簽名系統"目的:(如果暈就多看幾遍,這個沒搞清,后面的代碼就更暈)A欲傳(信息)給B,但又怕B不確信該信息是A發的。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發送的3.再比效[MD5(信息)!]與[(MD5(信息)] 如果相同,表示(信息)在傳遞過程中沒有被他人修改過

OK, 到現在為止, 你已經懂得了公鑰, 私鑰, 以及數字證書的概念了, 當然你也知道什么是對稱加密和非對稱加密,有可能你不是很清楚,為了讓你更清楚,給你再講個活生生的例子,這個例子還要從我的戀愛說起, 高中的時候喜歡上一個女生, 那時候青春年少,還喜歡用紙質給她寫情書, 每天寫一些“透明的”文字很繁瑣,于是有一天,我忽然一個念想,把情書改成用漢語拼音寫abcd……xyz, 原來字母是a就用z代替,b用y代替,c用x代替,……z用a代替, 這樣,一個只有我們倆能看的懂的情書就這樣誕生了。其實現在想想, 這不正是一種對稱式加密么。哈哈。

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

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

DES是一種分組數據加密技術(先將數據分成固定長度的小數據塊,之后進行加密),速度較快,適用于大量數據加密,而3DES是一種基于DES的加密算法,使用3個不同密匙對同一個分組數據塊進行3次加密,如此以使得密文強度更高。

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

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

RSA和DSA的安全性及其它各方面性能都差不多,而ECC較之則有著很多的性能優越,包括處理速度,帶寬要求,存儲空間等等

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

這幾種算法只生成一串不可逆的密文,經常用其效驗數據傳輸過程中是否經過修改,因為相同的生成算法對于同一明文只會生成唯一的密文,若相同算法生成的密文不同,則證明傳輸數據進行過了修改。通常在數據傳說過程前,使用MD5和SHA1算法均需要發送和接收數據雙方在數據傳送之前就知道密匙生成算法,而HMAC與之不同的是需要生成一個密匙,發送方用此密匙對數據進行摘要處理(生成密文),接收方再利用此密匙對接收到的數據進行摘要處理,再判斷生成的密文是否相同。

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

由于對稱加密算法的密鑰管理是一個復雜的過程,密鑰的管理直接決定著他的安全性,因此當數據量很小時,我們可以考慮采用非對稱加密算法。

在實際的操作過程中我們通常采用的方式是:采用非對稱加密算法管理對稱算法的密鑰,然后用對稱加密算法加密數據,這樣我們就集成了兩類加密算法的優點,既實現了加密速度快的優點,又實現了安全方便管理密鑰的優點。如果在選定了加密算法后,那采用多少位的密鑰呢?一般來說,密鑰越長,運行的速度就越慢,應該根據的我們實際需要的安全級別來選擇,一般來說,RSA建議采用1024位的數字,ECC建議采用160位,AES采用128為即可。

需要注意的是:

哈希函數,比如MD5,SHA,這些都不是加密算法。要注意他們的區別和用途,很多網友都把md5說成是加密算法,這是嚴重不正確的啊。哈希函數:MD5,SHA 是沒有密鑰的,相當與指紋的概念,因此也是不可逆的; md5是128位的,SHA有不同的算法,有128,256等位。。。如SHA-256,SHA-384然后 就是 Base64,這更加不屬于加密算法的范圍了,它只是將byte[]數組進行了轉換,為什么要轉換呢?就是因為很多加密后的密文后者一些特殊的byte[]數組需要顯示出來,或者需要進行傳遞(電子郵件),但是直接轉換就會導致很多不可顯示的字符,會丟失一些信息,因此就轉換位Base64編碼,這些都是可顯示的字符。所以轉換后,長度會增加。它是可逆的。 再就是 3DES,DES 這才是加密算法,因此也是可逆的,加解密需要密鑰,也就是你說的key最后是 RSA ,這是公鑰密碼,也就是加密和解密密鑰不同,也是可逆的。

羅列了這么多知識點, 我想這篇文章你應該有收藏的必要了吧,為了更形象,更好玩, 我從網上找了一些在線工具

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這個鏈接值的收藏一下, 主要是用到哈希的時候可以經常用。

2.1 AES DES

以上我們主要說了哈希算法和數字證書的一些知識, 現在我們看一下對稱加密的一些在線工具

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

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


如此般, 對稱加密基本上都弄完了,現在我們只簡單的了解下非對稱加解密的RSA,上面的過程我們已經說的非常詳細了吧。重點已經用黑色字體標注出來了。

加密數據

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

解密數據在

iOS下解碼需要先加載private key, 之后在對數據解碼. 解碼的時候先進行Base64 decode, 之后在用private key decrypt加密數據.

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]

];

}

轉化為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轉化

+?(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?的縮寫(有效的維護了代碼,比如:一個人用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);//將已開辟內存空間buffer的首?1?個字節的值設為值?0

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

CCCrypt函數?加密/解密

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

kCCAlgorithmDES,加密根據哪個標準(des,3des,aes。。。。)

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

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

kCCKeySizeDES,DES?密鑰的大?。╧CCKeySizeDES=8)

iv,可選的初始矢量

dataIn,數據的存儲單元

dataInLength,數據的大小

(void?*)dataOut,用于返回數據

dataOutAvailable,

&dataOutMoved);

編碼?base64

NSData?*data?=?[NSData?dataWithBytes:(const?void?*)dataOut?length:(NSUInteger)dataOutMoved];

Byte?*bytes?=?(Byte?*)[data?bytes];

下面是Byte?轉換為16進制。

NSString?*hexStr=@"";

for(int?i=0;i<[data?length];i++){

NSString?*newHexStr?=?[NSString?stringWithFormat:@"%x",bytes[i]&0xff];16進制數

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

轉成utf-8并decode

dataInLength?=?[decryptData?length];

dataIn?=?[decryptData?bytes];

free(myBuffer);

CCCryptorStatus?ccStatus?=?nil;

uint8_t?*dataOut?=?NULL;可以理解位type/typedef?的縮寫(有效的維護了代碼,比如:一個人用int,一個人用long。最好用typedef來定義)

size_t?dataOutAvailable?=?0;size_t??是操作符sizeof返回的結果類型

size_t?dataOutMoved?=?0;

dataOutAvailable?=?(dataInLength?+?kCCBlockSizeDES)?&?~(kCCBlockSizeDES?-?1);

dataOut?=?malloc(?dataOutAvailable?*?sizeof(uint8_t));

memset((void?*)dataOut,?0x0,?dataOutAvailable);將已開辟內存空間buffer的首?1?個字節的值設為值?0

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

CCCrypt函數?加密/解密

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

kCCAlgorithmDES,加密根據哪個標準(des,3des,aes。。。。)

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

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

kCCKeySizeDES,DES?密鑰的大?。╧CCKeySizeDES=8)

ivDes,可選的初始矢量

dataIn,數據的存儲單元

dataInLength,數據的大小

(void?*)dataOut,用于返回數據

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;

}

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

函數名稱?:?+?(NSData?*)dataWithBase64EncodedString:(NSString?*)string

函數描述?:?base64格式字符串轉換為文本數據

輸入參數?:?(NSString?*)string

輸出參數?:?N/A

返回參數?:?(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];

}

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

函數名稱?:?+?(NSString?*)base64EncodedStringFrom:(NSData?*)data

函數描述?:?文本數據轉換為base64格式字符串

輸入參數?:?(NSData?*)data

輸出參數?:?N/A

返回參數?:?(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

以上是接口和實現文件, 現在我們來看看調用

-?(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;

}

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

了解下cookie在客戶端里的應用

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


這是維基百科里一段對cookie的描述,可見cookie是服務器生成的發給客戶端,具體應用例如:我們打開淘寶的某一個頁面,登陸了賬號和密碼, 當我們再跳轉到其他淘寶界面的時候,我們不必每一次都重新登陸界面, 這就是cookie的作用, 其實cookie還能記錄用戶選的訂單, 至于深一層的了解, 我還不是很清楚, 因為沒有學過前端的開發,感興趣的讀者可以自行了解。

其實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呢。

當我們的應用在加載一個wap頁面的時候,可能wap需要知道客戶端的一些信息, 比如你是登陸狀態還是什么狀態,因為這時候我們就可以設置cookie,wap可以拿到請求的cookie

當然需要注意的是在wap將要銷毀的時候,要把cookie信息給移除掉。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容

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