一着绷、突然發(fā)現(xiàn)少寫(xiě)了一個(gè)RSA - -#...,加解密原理參照RSA算法原理笨使,常規(guī)的加解算法一般都是對(duì)稱加密:
(1)甲方選擇某一種加密規(guī)則棠笑,對(duì)信息進(jìn)行加密
(2)乙方使用同一種規(guī)則容劳,對(duì)信息進(jìn)行解密辉词。
由于加密和解密使用同樣規(guī)則(簡(jiǎn)稱"密鑰")必孤,這被稱為"對(duì)稱加密算法"(Symmetric-key algorithm)。
這種加密模式有一個(gè)最大弱點(diǎn):甲方必須把加密規(guī)則告訴乙方瑞躺,否則無(wú)法解密敷搪。保存和傳遞密鑰,就成了最頭疼的問(wèn)題幢哨。
常用的是AES如:iOS開(kāi)發(fā)加解密算法-基礎(chǔ)篇(2)<AES加密算法>
而RSA是非對(duì)稱加密:
(1)乙方生成兩把密鑰(公鑰和私鑰)赡勘。公鑰是公開(kāi)的,任何人都可以獲得捞镰,私鑰則是保密的闸与。
(2)甲方獲取乙方的公鑰毙替,然后用它對(duì)信息加密。
(3)乙方得到加密后的信息践樱,用私鑰解密厂画。
如果公鑰加密的信息只有私鑰解得開(kāi),那么只要私鑰不泄漏拷邢,通信就是安全的袱院。
特點(diǎn)
A.便于理解,使用廣泛
RSA算法是第一個(gè)能同時(shí)用于加密和數(shù)字簽名的算法瞭稼,也易于理解和操作忽洛。RSA是被研究得最廣泛的公鑰算法,從提出到現(xiàn)今的三十多年里环肘,經(jīng)歷了各種攻擊的考驗(yàn)欲虚,逐漸為人們接受,普遍認(rèn)為是目前最優(yōu)秀的公鑰方案之一悔雹。
B.缺點(diǎn)與不足:加密和解密花費(fèi)時(shí)間長(zhǎng)苍在、速度慢,只適合對(duì)少量數(shù)據(jù)進(jìn)行加密荠商。
為提高保密強(qiáng)度寂恬,RSA密鑰至少為500位長(zhǎng),一般推薦使用1024位莱没。這就使加密的計(jì)算量很大初肉。為減少計(jì)算量,在傳送信息時(shí)饰躲,常采用傳統(tǒng)加密方法與公開(kāi)密鑰加密方法相結(jié)合的方式牙咏,即信息采用改進(jìn)的DES或IDEA對(duì)話密鑰加密,然后使用RSA密鑰加密對(duì)話密鑰和信息摘要嘹裂。對(duì)方收到信息后妄壶,用不同的密鑰解密并可核對(duì)信息摘要。
二寄狼、RSA的方法實(shí)現(xiàn):
1.一般移動(dòng)端的RSA加解密的公私鑰都是由服務(wù)端生成的,我們要做的其實(shí)是拿著公私鑰去做加解密的操作丁寄。
2.我們公司的項(xiàng)目使用的加解密流程是
雖然RSA加密后基本無(wú)解,但是RSA不適合對(duì)大文本進(jìn)行加密,所以我們采用的是對(duì)文件采用AES加密,對(duì)AES的秘鑰進(jìn)行RSA的加密,AES秘鑰是動(dòng)態(tài)的每一個(gè)文件的秘鑰都是唯一的泊愧,RSA的私鑰在傳輸?shù)臅r(shí)候再用一層AES加密.解密的流程就是再倒著來(lái)一遍...
3.RSA解密伊磺,使用第三方加解密庫(kù)openssl
- 一般公私鑰都是由我們服務(wù)端提供的的(java后臺(tái)),這里遇到過(guò)坑删咱,我們當(dāng)時(shí)雙方都沒(méi)做過(guò)RSA的加解密,格子調(diào)研在自己的平臺(tái)上自己加密和解密是沒(méi)有問(wèn)題的屑埋,但是用服務(wù)端傳給我們的私鑰解密他們的加密文本卻不能解密。最后發(fā)現(xiàn)原來(lái)生成的跨平臺(tái)的私鑰不能直接使用,需要進(jìn)行統(tǒng)一的編碼處理后才能使用痰滋,我們采用的是統(tǒng)一的PKCS#8編碼處理后生成的.pem格式摘能⌒拢可以參考:Java中使用OpenSSL生成的RSA公私鑰進(jìn)行數(shù)據(jù)加解密
2.秘鑰文本
AES秘鑰經(jīng)過(guò)RSA加密后的Base64字符串<code>
key = eY4bZZsiqDCsNgHVaT5OJfDkGp5pNlJbYUUPOTauXO5Yz9szXgz1XOmjTq8aoPnHTkuh1GCSF/hj0g182U2iUTZFIwRoL7MZ/LtuTpwDMaa3XHAOjvTqxfHKy3htd9gpR/2/w9+l9urm2MPS31GD/ZalX8GGBltDVNZWXj0zyX4=;</code>
RSA私鑰經(jīng)過(guò)PKCS#8編碼處理后獲取的私鑰字符串:
<code>
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCWWQqoCxHmu9yklZ7DAME9lvw0t37SqBhIcvnma7Rl3kTn4lfJ
WEoycvNmduhf59g193c8/4tQKs/B71OUIDWfASNhnaBVzyHXTupeUSo5yaXYdSja
VIhc/HmSms1SqlsDWBzJldi0JVaN5MqNnitHpxPOBHEu6J3Xr+Cobkd1XwIDAQAB
AoGAVHmtQiQOJ92QKK2kqZ6H9SobhSdAy+4EzthDT1Ne5gnQH5YOiyPfdJ8f4YeY
IyLqWdA0oAJZbW7Qkv/8rvK2DUbH97LkeGOuJtY5SxmbWI0w7fGvefg9TPrDSyRq
PWvohEZSM2w7slhHTiPFeiRFIEmuWGTJAcnmPLAraxn5QTkCQQDWfX4ybSk5mX9y
iSt952C78c80bX54XW9VMCnDIFGDkSsG3zyXlI4i3PJAXYHFwzcysD0irxQPVjTA
7k6b1eflAkEAs3G8mxCAbuqbzw7zuJUgMshns2tD5BIH8/7DwhRl/ecz6Az6SQ6Q
ZF02XpDyqpNtllwc2WDIyTE7go33bNeL8wJBALYb6Hix/A1+iRna4sVMHPKV1QJD
cNyLIAqpENwt5Weaani0MwLTy3ZIN5p0ick5/PSZc96t3Y9D9xhTfQSMsg0CQFlC
wmcAFmMWINsmvOWciJ+6QJtnSCYzMfGVURtBulpKn+9WRUoCDKFgHKN9xrhDDcg1
mcQn+Ljb3JZcuC9UKTECQQCRCHnaY7sp3hIizdIRN5lI0vhyipVVIymTTgmtu7rV
LrnmEEas1RhUVOyVJaw08mON/eH17//9X29cA9ntFSLh
-----END RSA PRIVATE KEY-----
</code>
4.代碼實(shí)現(xiàn)
a.將私鑰寫(xiě)入到本地后綴名不限制
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@".private_key.rce"];
NSFileManager *manger = [NSFileManager defaultManager];
[manger removeItemAtPath:path error:nil];
NSError *error = nil;
BOOL success = [str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:&error];
b.將私鑰導(dǎo)入
//根據(jù)鑰匙類型導(dǎo)入公鑰私鑰
- (BOOL)importRSAKeyWithType:(KeyType)type {
FILE *file;
if (type == KeyTypePublic) {
file = fopen([OpenSSLRSAPublicKeyFile cStringUsingEncoding:NSASCIIStringEncoding],"rb");
}else{
file = fopen([OpenSSLRSAPrivateKeyFile1 cStringUsingEncoding:NSASCIIStringEncoding],"rb");
}
if (NULL != file) {
if (type == KeyTypePublic) {
_rsa = PEM_read_RSAPublicKey(file,NULL, NULL, NULL);
assert(_rsa != NULL);
// PEM_write_RSAPublicKey(stdout, _rsa);
}else{
_rsa = PEM_read_RSAPrivateKey(file, NULL, NULL, NULL);
assert(_rsa != NULL);
PEM_write_RSAPrivateKey(stdout, _rsa, NULL, NULL, 0, NULL, NULL);
}
fclose(file);
return (_rsa != NULL)?YES:NO;
} return NO;
}
c.導(dǎo)入完成后對(duì)加密二進(jìn)制流進(jìn)行解密
- (NSData*)decryptRSAKeyWithType:(KeyType)keyType paddingType:(RSA_PADDING_TYPE)padding encryptedData:(NSData*)data {
if (data && [data length]) {
NSUInteger flen = [data length];
unsigned char from[flen];
bzero(from, sizeof(from));
memcpy(from, [data bytes], [data length]);
// 這里可以更改解密密文長(zhǎng)度
unsigned char to[32];
bzero(to, sizeof(to));
[self decryptRSAKeyWithType:keyType :from :flen :to :padding];
NSData *data = [NSData dataWithBytes:to length:sizeof(to)];
[[NSFileManager defaultManager] removeItemAtPath:OpenSSLRSAPrivateKeyFile1 error:nil];
return data;
}
return nil;
}
- (NSData *)decryptRSAKeyWithType:(KeyType)keyType paddingType:(RSA_PADDING_TYPE)padding encryptedData:(NSData *)data andKeyName:(NSString *)name {
[self importRSAKeyWithType:KeyTypePrivate keyName:name];
if (data && [data length])
{
NSUInteger flen = [data length];
unsigned char from[flen];
bzero(from, sizeof(from));
memcpy(from, [data bytes], [data length]);
unsigned char to[32];
bzero(to, sizeof(to));
[self decryptRSAKeyWithType:keyType :from :flen :to :padding];
return [NSData dataWithBytes:to length:sizeof(to)];
}
return nil;
}