亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

RSA算法及其在iOS中的使用

2019-11-14 18:50:28
字體:
來源:轉載
供稿:網友
因為項目中需要傳輸用戶密碼,為了安全需要用RSA加密,所以就學習了下RSA加密在iOS中的應用。
關于RSA的歷史及原理,下面的兩篇文章講的很清楚了:
 
簡單來說,RSA建立在一個數學難題之上,就是大數分解:將兩個大素數相乘十分容易,但是想要對其乘積進行因式分解卻極其困難。至于為什么難,難在哪里那就是數學家的事了。。。
明白了這個就可以大致知道RSA的原理:非對稱加密
(1)乙方生成兩把密鑰(公鑰和私鑰)。公鑰是公開的,任何人都可以獲得,私鑰則是保密的。
(2)甲方獲取乙方的公鑰,然后用它對信息加密。
(3)乙方得到加密后的信息,用私鑰解密。
 
就好比有一套特殊的鎖和鑰匙,鎖是公開的,誰都可以拿這個鎖來鎖住他的東西,只有有鑰匙的人可以打開。
那么問題來了,既然鎖是公開的,難道不能通過鎖的結構來倒推出鑰匙的形狀嗎?
答案是:不能!因為這個鎖是特殊的,它就特殊在很難倒推。(這個倒不是絕對的,也許將來某一天大數分解的數學難題解決了,這種算法就不安全了,詳見開頭鏈接)
 
我遇到的應用場景是,客戶端有服務器的公鑰,客戶端要把用戶的密碼用公鑰加密上后上傳到服務器,服務器可以用私鑰解密。
所以客戶端要做的是,將需要加密的內容用服務器給的公鑰進行RSA加密。
iOS上并沒有直接的RSA加密API,所以需要折騰一下。
gitHub上的代碼大同小異,主要是三個方法(抄自https://github.com/ideawu/Objective-C-RSA
注意代碼里有個kSecPaddingPKCS1是作者寫死的,而我們的項目中需要傳kSecPaddingNone才行?。?!
 
+ (NSData *)stripPublicKeyHeader:(NSData *)d_key{// Skip ASN.1 public key headerif (d_key == nil) return(nil);unsigned long len = [d_key length];if (!len) return(nil);unsigned char *c_key = (unsigned char *)[d_key bytes];unsigned int  idx    = 0;if (c_key[idx++] != 0x30) return(nil);if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;else idx++;// PKCS #1 rsaEncryption szOID_RSA_RSAstatic unsigned char seqiod[] ={ 0x30,   0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,0x01, 0x05, 0x00 };if (memcmp(&c_key[idx], seqiod, 15)) return(nil);idx += 15;if (c_key[idx++] != 0x03) return(nil);if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;else idx++;if (c_key[idx++] != '/0') return(nil);// Now make a new NSData from this bufferreturn([NSData dataWithBytes:&c_key[idx] length:len - idx]);}

 

 
 
+ (SecKeyRef)addPublicKey:(NSString *)key{NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"];if(spos.location != NSNotFound && epos.location != NSNotFound){NSUInteger s = spos.location + spos.length;NSUInteger e = epos.location;NSRange range = NSMakeRange(s, e-s);key = [key substringWithRange:range];}key = [key stringByReplacingOccurrencesOfString:@"/r" withString:@""];key = [key stringByReplacingOccurrencesOfString:@"/n" withString:@""];key = [key stringByReplacingOccurrencesOfString:@"/t" withString:@""];key = [key stringByReplacingOccurrencesOfString:@" "  withString:@""];// This will be base64 encoded, decode it.NSData *data = base64_decode(key);data = [RSA stripPublicKeyHeader:data];if(!data){return nil;}NSString *tag = @"what_the_fuck_is_this";NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];// Delete any old lingering key with the same tagNSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];[publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];[publicKey setObject:d_tag forKey:(__bridge id)kSecAttrapplicationTag];SecItemDelete((__bridge CFDictionaryRef)publicKey);// Add persistent version of the key to system keychain[publicKey setObject:data forKey:(__bridge id)kSecValueData];[publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass];[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];CFTypeRef persistKey = nil;OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);if (persistKey != nil){CFRelease(persistKey);}if ((status != noErr) && (status != errSecDuplicateItem)) {return nil;}[publicKey removeObjectForKey:(__bridge id)kSecValueData];[publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];// Now fetch the SecKeyRef version of the keySecKeyRef keyRef = nil;status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);if(status != noErr){return nil;}return keyRef;}

 

 
 1 + (NSString *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{ 2 if(!data || !pubKey){ 3 return nil; 4 } 5 SecKeyRef keyRef = [RSA addPublicKey:pubKey]; 6 if(!keyRef){ 7 return nil; 8 } 9 10 const uint8_t *srcbuf = (const uint8_t *)[data bytes];11 size_t srclen = (size_t)data.length;12 13 size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);14 if(srclen > outlen - 11){15 CFRelease(keyRef);16 return nil;17 }18 void *outbuf = malloc(outlen);19 20 OSStatus status = noErr;21 status = SecKeyEncrypt(keyRef,22   kSecPaddingNone, //原作者寫的是kSecPaddingPKCS1,經春哥研究這里寫成kSecPaddingNone才符合我們使用23   srcbuf,24   srclen,25   outbuf,26   &outlen27   );28 NSString *ret = nil;29 if (status != 0) {30 //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status);31 }else{32 NSData *data = [NSData dataWithBytes:outbuf length:outlen];33 ret = base64_encode_data(data);34 }35 free(outbuf);36 CFRelease(keyRef);37 return ret;38 }

 

 
還有一篇文章可以參考:http://blog.iamzsx.me/show.html?id=155002
 
 
簽名機制
僅僅加密某個參數是不夠的,還需要保證請求沒有被篡改,所以簽名機制就很有必要。
比較簡單和常用就是md5簽名:
拿到待簽名的字符串A(比如某個url),將其與服務器約定好的密鑰拼成新的字符串B,對B進行MD5算法得到簽名C,
然后將C作為A的簽名一起發送到服務器。
服務器收到請求后,對A用與客戶端約定好的密鑰進行相同的算法得到C’,如果C==C’,那就說明改請求沒有被篡改過,
否則驗證不通過
 
當然也可以做RSA簽名
這個要比MD5簽名要稍微麻煩一點,因為需要客戶端生成公鑰私鑰對,基本流程也和MD5簽名一樣
拿到待簽名的字符串A(比如某個url),將其用私鑰加密得到的字符串B,然后將B和原數據A還有自己的公鑰一起發送給服務器,
服務器收到請求,用公鑰解密得到B',如果B==B',則說明原數據沒有被篡改過,否則驗證不通過。
 
也有說這里得到B以后,需要再用服務器的公鑰加密一遍得到C,將C和原數據和自己的公鑰一起發送給服務器,
服務器收到之后,現需要用自己的私鑰解密一遍得到C',然后再用客戶端公鑰解密得到B',然后同上。。。
 
RSA簽名及驗證我還沒用到,所以具體怎么實現的還需要研究下,待補充!??!
 
 
HTTPS
https算是對RSA加密的一個典型應用吧,不過這個服務器的公鑰私鑰不是自己生產的,而是CA頒發的。
具體原理網上很多,其中一個:http://jingyan.baidu.com/article/2fb0ba4048e15500f3ec5f7e.html
 
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美第一页| 日韩av影片在线观看| 一本色道久久88亚洲综合88| 欧美性理论片在线观看片免费| 8x海外华人永久免费日韩内陆视频| 国产精品偷伦免费视频观看的| 国产精品高潮呻吟久久av无限| 亚洲欧美激情视频| 成人h视频在线观看播放| 91在线免费网站| 亚洲欧洲视频在线| 国产91亚洲精品| 国产成人精品电影久久久| 亚洲老板91色精品久久| 欧美老女人在线视频| 日韩精品视频在线观看网址| 国产日韩欧美91| 欧美激情网站在线观看| 日韩69视频在线观看| 日韩中文字幕av| 欧美在线视频在线播放完整版免费观看| 亚洲精品99久久久久中文字幕| 亚洲精品一区在线观看香蕉| 欧美裸体xxxx极品少妇| 国产日本欧美一区二区三区在线| 国产98色在线| 最新国产精品亚洲| 国产精品海角社区在线观看| 亚洲精品一区久久久久久| 国产精品色悠悠| 91网站免费观看| 欧美激情精品久久久久久黑人| 亚洲欧美精品一区| 日本精品性网站在线观看| 国产精品va在线| 久久这里有精品视频| 欧美一区二区三区艳史| 久久亚洲春色中文字幕| 成人久久一区二区三区| 亚洲国产精品久久久| 欧洲精品在线视频| 青青久久av北条麻妃黑人| 日韩日本欧美亚洲| 国产成人久久久精品一区| 国产精品在线看| 日韩欧美亚洲一二三区| 亚洲天堂免费观看| 久久久国产一区| 国产91在线播放九色快色| 国产成人在线视频| 亚洲白虎美女被爆操| 欧美日韩亚洲激情| 亚洲三级黄色在线观看| 色婷婷av一区二区三区在线观看| 亚洲国产成人av在线| 亚洲午夜精品视频| 北条麻妃在线一区二区| 国产精品pans私拍| 国内免费精品永久在线视频| 欧美精品成人91久久久久久久| 国产精品99久久久久久久久久久久| 91精品国产综合久久香蕉的用户体验| 欧美乱大交xxxxx| 亚洲精品wwwww| 午夜精品久久久久久久99热| 97高清免费视频| 国产欧美精品日韩精品| 久久夜精品va视频免费观看| 欧美日韩国产精品一区| 国产亚洲视频中文字幕视频| 久久精品国产一区| 亚洲欧美综合精品久久成人| 国产精品色视频| 欧美xxxx18国产| 91日本在线视频| 亚洲电影中文字幕| 日本高清+成人网在线观看| 91精品在线观| 亚洲国产精品推荐| 亚洲第一色在线| 国产日韩欧美在线播放| 欧美日韩亚洲国产一区| 亚洲最大的av网站| 欧美性在线视频| 日本a级片电影一区二区| 国产男女猛烈无遮挡91| 欧美激情按摩在线| 国产精品激情av电影在线观看| 韩国福利视频一区| 韩国精品美女www爽爽爽视频| 久久香蕉国产线看观看网| 精品日本高清在线播放| 亚洲人成在线电影| 国产精品白嫩美女在线观看| 亚洲影院色无极综合| 国产精品视频男人的天堂| 欧美黄色小视频| 国外成人性视频| 亚洲欧美在线看| 亚洲成年网站在线观看| 国产精品视频区| 亚洲剧情一区二区| 欧美亚洲视频在线观看| 久久精品视频在线| 亚洲第一国产精品| 国产精品一区二区女厕厕| 一区二区三区久久精品| 2019中文字幕全在线观看| 亚洲aa在线观看| xxxxx成人.com| 欧美与欧洲交xxxx免费观看| 欧美亚洲免费电影| 欧美大片va欧美在线播放| 91精品视频网站| 欧美午夜片欧美片在线观看| 国产精品69久久| 国产精品第100页| 亚洲丝袜av一区| 日韩精品在线私人| 日韩免费观看高清| 性夜试看影院91社区| 亚洲成av人影院在线观看| 一区二区三区视频免费| 2025国产精品视频| 色偷偷综合社区| 亚洲免费视频在线观看| 国产精品女主播视频| 国产亚洲精品激情久久| 久久久视频精品| 国产91av在线| 亚洲精品国产精品久久清纯直播| 91精品国产一区| 亚洲欧美变态国产另类| 日韩成人av网址| 亚洲电影在线观看| 草民午夜欧美限制a级福利片| 久久影院模特热| 欧美日韩国产综合视频在线观看中文| 亚洲中国色老太| 国产精品三级在线| 午夜精品在线观看| 亚洲在线视频观看| 久久久www成人免费精品| 日本高清+成人网在线观看| 国产精品网红直播| 亚洲精品国产精品国自产观看浪潮| 欧美国产在线电影| 91成人福利在线| 亚洲国产成人精品女人久久久| 久久成人这里只有精品| 国产盗摄xxxx视频xxx69| 日韩电影中文字幕一区| xxxx欧美18另类的高清| 亚洲国产成人精品久久| 91久久综合亚洲鲁鲁五月天| 日韩av免费看网站| 91精品久久久久久久久中文字幕| 亚洲欧洲在线观看| 亚洲精品一区二区在线| 色综久久综合桃花网| 久久视频国产精品免费视频在线| 亚洲自拍偷拍福利| 欧美成人免费全部| 国产aaa精品|