iOS 加、解密


對稱密鑰加密

對稱加密相對好理解,加密方和解密方使用的是同一個密鑰。
常見的對稱密鑰加密有AES、DES 等。


MD5

MD5是一個哈希算法,對同一個明文生成的密文(哈希值)是統(tǒng)一的。MD5相較于普通加密來說還有一個優(yōu)點(diǎn):MD5生成的密文長度很短(16位或者32位字符)。全稱MD5消息摘要算法(MD5 Message-Digest Algorithm)。

非對稱密鑰加密

非對稱密鑰加密,又稱為公開密鑰加密。
非對稱密鑰加密需要兩個密鑰,一個是公開密鑰,一個是私有密鑰。私有密鑰用來加密,公開密鑰用來解密。私有密鑰由加密方保管,公有密鑰則公布出來。
實(shí)際上,私有密鑰和共有密鑰在數(shù)學(xué)上是有一定的關(guān)系的。但是僅僅從共有密鑰是推斷不出私有密鑰的,這也是共有密鑰可以公布出來的原因。
通過共有密鑰推斷私有密鑰和質(zhì)數(shù)分解有關(guān)。目前質(zhì)數(shù)分解沒有特別快的算法,通常是通過暴力枚舉的方法來分解。當(dāng)質(zhì)數(shù)非常大時(如2的1024次方級別),暴力分解質(zhì)數(shù)是不現(xiàn)實(shí)的,因此非對稱加密是安全的。
非對稱加密的安全還依賴于加密方對私鑰的管理,一旦私鑰暴露,也就毫無加密可言。
常見的非對稱加密有RSA、DSA。


數(shù)字簽名

數(shù)字簽名用的是非對稱加密,公開密鑰在數(shù)據(jù)接收方,數(shù)字簽名的作用是保證:

  1. 保證數(shù)據(jù)沒有沒有被篡改過
  2. 保證數(shù)據(jù)是經(jīng)過我認(rèn)證的
數(shù)字簽名的過程:非對稱加密+MD5線性加密
  1. 首先算出原始數(shù)據(jù)的摘要。這里的算法要保證:如果原始數(shù)據(jù)有任何變化,則摘要也會發(fā)生變化;對同一份原始數(shù)據(jù),使用相同的算法,計(jì)算出的摘要是相同的。這一步使用的算法通常是MD5消息摘要算法。
  2. 生成一對公鑰和私鑰,使用非對稱加密方式,用私鑰對上一步生成的摘要進(jìn)行加密,加密的結(jié)果就是數(shù)字簽名。
  3. 在返回?cái)?shù)據(jù)時,將原始數(shù)據(jù)和數(shù)字簽名一起返回給請求數(shù)據(jù)方。

接到數(shù)據(jù)之后就行驗(yàn)證數(shù)據(jù)的完整性:


請求數(shù)據(jù)方在接收到數(shù)據(jù)處理過程
  1. 首先用含有的公鑰對數(shù)字簽名進(jìn)行解密,如果能夠解密成功,說明返回的數(shù)據(jù)是經(jīng)過數(shù)據(jù)發(fā)送方認(rèn)證的(否則數(shù)據(jù)發(fā)送方不會對該數(shù)據(jù)加密)。
  2. 對原始的數(shù)據(jù)使用MD5算法,生成原始數(shù)據(jù)的摘要。
  3. 對比第一步和第二步生成的摘要,如果生成的摘要相等,說明原始數(shù)據(jù)沒有被篡改過。
    由此,通過數(shù)字簽名可以達(dá)到確保數(shù)據(jù)沒有被篡改過以及數(shù)據(jù)是合法的目的。

DES加解密

這里使用框架提供的des加解密庫:
首先引入頭文件 #import CommonCrypto/CommonCryptor.h
主要的加解密函數(shù)如下:

/*字符串加密

*參數(shù)

*plainText : 加密明文

*key        : 密鑰 64位

*/

+ (NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key

{

NSString *ciphertext = nil;

const char *textBytes = [plainText UTF8String];

NSUInteger dataLength = [plainText length];

unsigned char buffer[1024];

memset(buffer, 0, sizeof(char));

Byte iv[] = {1,2,3,4,5,6,7,8};

size_t numBytesEncrypted = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,

kCCOptionPKCS7Padding,

[key UTF8String], kCCKeySizeDES,

iv,

textBytes, dataLength,

buffer, 1024,

&numBytesEncrypted);

if (cryptStatus == kCCSuccess) {

NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];

ciphertext = [[[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding] autorelease];

}

return ciphertext;

}

//解密

+ (NSString *) decryptUseDES:(NSString*)cipherText key:(NSString*)key

{

NSData* cipherData = [GTMBase64 decodeString:cipherText];

unsigned char buffer[1024];

memset(buffer, 0, sizeof(char));

size_t numBytesDecrypted = 0;

Byte iv[] = {1,2,3,4,5,6,7,8};

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,

kCCAlgorithmDES,

kCCOptionPKCS7Padding,

[key UTF8String],

kCCKeySizeDES,

iv,

[cipherData bytes],

[cipherData length],

buffer,

1024,

&numBytesDecrypted);

NSString* plainText = nil;

if (cryptStatus == kCCSuccess) {

NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];

plainText = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];

}

return plainText;

}

MD5加密

MD5加密是不可逆的

MD5實(shí)現(xiàn)方法(16位):

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

{

constchar *concat_str = [strUTF8String];

unsignedchar result[CC_MD5_DIGEST_LENGTH];

CC_MD5(concat_str, (unsignedint)strlen(concat_str), result);

NSMutableString *hash = [NSMutableStringstring];

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

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

}

return [hashuppercaseString];

}

AES加密

對稱加密,密鑰key
常用的,詳解:

h文件內(nèi)容:

#import

@class NSString;

@interface NSData (Encryption)

- (NSData *)AESOverCycle:(NSString *)key; //加密

- (NSData *)AESRelaes:(NSString *)key; //解密

@end

m文件內(nèi)容:

加密:

@implementation NSData (Encryption)

- (NSData *)AESOverCycle:(NSString *)key {

char keyPtr[kCCKeySizeAES256+1];

bzero(keyPtr, sizeof(keyPtr));

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;

void *buffer = malloc(bufferSize);

size_t numBytesEncrypted = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,

kCCOptionPKCS7Padding | kCCOptionECBMode,

keyPtr, kCCBlockSizeAES128,

NULL,

[self bytes], dataLength,

buffer, bufferSize,

&numBytesEncrypted);

if (cryptStatus == kCCSuccess) {

return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];

}

free(buffer);

return nil;

}

解密:

- (NSData *)AESRelaes:(NSString *)key {

char keyPtr[kCCKeySizeAES256+1];

bzero(keyPtr, sizeof(keyPtr));

[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [self length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;

void *buffer = malloc(bufferSize);

size_t numBytesDecrypted = 0;

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,

kCCOptionPKCS7Padding | kCCOptionECBMode,

keyPtr, kCCBlockSizeAES128,

NULL,

[self bytes], dataLength,

buffer, bufferSize,

&numBytesDecrypted);

if (cryptStatus == kCCSuccess) {

return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];

}

free(buffer);

return nil;

}

@end

Base64編碼與解碼

Base64編碼是6個二進(jìn)制位一編碼, ASCII碼是8個二進(jìn)制位一編碼,所以轉(zhuǎn)換成字符串后會比ASCII內(nèi)容要多。其使用64個字符來對任意數(shù)據(jù)進(jìn)行編碼。
Base64編碼本質(zhì)上是一種將二進(jìn)制數(shù)據(jù)轉(zhuǎn)成文本數(shù)據(jù)的方案。對于非二進(jìn)制數(shù)據(jù),是先將其轉(zhuǎn)換成二進(jìn)制形式,然后每連續(xù)6比特(2的6次方=64)計(jì)算其十進(jìn)制值,根據(jù)該值在上面的索引表中找到對應(yīng)的字符,最終得到一個文本字符串。
Base64是一個可逆過程,不能用作數(shù)據(jù)加密操作。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容