❶ 怎麼在ios進行rsa公鑰加密,java做rsa私鑰解密
1、用公鑰加密,用私鑰解密。
2、給別人發信息,就從伺服器上拉下來別人的公鑰,加密後發給他。
3、對方拿到信息後用自己的私鑰解密。
4、這樣,公鑰加密後除了私鑰持有人,別人都看不到信息。
5、若是用私鑰加密,那麼公鑰都能解密,還有何安全性可言?
6、私鑰加密的場合只有一個,那就是數字簽名,用來表明這個信息來源於你。
❷ iOS逆向(1)-密碼學(RSA)
要講逆向,那麼肯定少不了密碼學,因為所有的逆向(攻防)都是對已加密的數據進行解密。所以我們必須初步了解加密的方式有哪些,畢竟知己知彼,才能百戰百勝。
接下來,我將從以下四方面來講述密碼學相關的內容:
1、什麼是密碼學
2、RSA數學原理
3、RSA終端命令
4、總結
密碼學的歷史大致可以追溯到兩千年前,相傳古羅馬名將凱撒大帝為了防止敵方截獲情報,用密碼傳送情報。凱撒的做法很簡單,就是對二十幾個羅馬字母建立一張對應表。這樣,如果不知道密碼本,即使截獲一段信息也看不懂。
從凱撒大帝時代到上世紀70年代這段很長的時間里,密碼學的發展非常的緩慢,因為設計者基本上靠經驗。沒有運用數學原理。
在1976年以前,所有的加密方法都是同一種模式:加密、解密使用同一種演算法。在交互數據的時候,彼此通信的雙方就必須將規則告訴對方,否則沒法解密。那麼加密和解密的規則(簡稱密鑰),它保護就顯得尤其重
要。傳遞密鑰就成為了最大的隱患。這種加密方式被成為對稱加密演算法(symmetric encryption algorithm)。
1976年,兩位美國計算機學家 迪菲(W.Diffie)、赫爾曼( M.Hellman ) 提出了一種嶄新構思,可以在不直接傳遞密鑰的情況下,完成密鑰交換。這被稱為「迪菲赫爾曼密鑰交換」演算法。開創了密碼學研究的新方向。
1977年三位麻省理工學院的數學家 羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起設計了一種演算法,可以實現非對稱加密。這個演算法用他們三個人的名字命名,叫做RSA演算法。
也就是說「迪菲赫爾曼密鑰交換」在密碼學歷史的車輪中成為了一個轉折點。
咱們這里先把所有需要用到的公式定理列出來:
1、取模運算
2、歐拉函數φ
3、歐拉定理,費馬小定理
4、模反元素
5、迪菲赫爾曼密鑰交換
取模運算(「Molo Operation」)和取余運算(「Complementation 」)兩個概念有重疊的部分但又不完全一致。主要的區別在於對負整數進行除法運算時操作不同。
在這列出各種負數情況的例子供大家理解:
7 mod 4 = 3(商 = 1 或 2,1<2,取商=1)
-7 mod 4 = 1(商 = -1 或 -2,-2<-1,取商=-2)
7 mod -4 = -1(商 = -1或-2,-2<-1,取商=-2)
-7 mod -4 = -3(商 = 1或2,1<2,取商=1)
函數值符號規律(余數的符號) mod(負,正)=正 mod(正,負)=負
結論:兩個整數求余時,其值的符號為除數的符號。
可以簡單理解為:
如果n可以分解為 兩個互質(不一定是兩個質數) 的數之積A和B,那麼:
φ(n) = φ(A) * φ(B)
如果 A和B 又同時為質數,那麼:
φ(n) = (A-1) * (B-1)
首先這里說一下,定製之所以是定理是被人證明過的,如何證明的不管,當然你也可以增加去證明下,反正我不管(……&%¥%……&%&……&%),哈哈
如果m、n為正整數,且m、n互質,那麼:
如果n為質數,那麼:
公式轉換:
如果兩個正整數e和x互質,那麼一定可以找到整數d,使得 e*d-1 被x整除。那麼d就是e對於x的「模反元素」。
如上圖:
客戶端持有一個隨機數13 ,服務端持有隨機數15,再選一對特殊的數,3是17的原根(啥是 原根 ?)。
兩端交換的都是密文,就算中間被劫持,也不知道最後需要的傳輸的內容是10
那麼這個10就是最後真正的秘鑰。
證明過程
設
那麼:
又由於上面模反元素 最後得出
所以得出最終結論:
這個公式也就是我們最後的RSA加密公式!!!
其中:
補充:
1、n會非常大,長度一般為1024個二進制位。(目前人類已經分解的最大整數,232個十進制位,768個二進制位)
2、由於需要求出φ(n),所以根據歐函數特點,最簡單的方式n 由兩個質數相乘得到: 質數:p1、p2
Φ(n) = (p1 -1) * (p2 - 1)
3、最終由φ(n)得到e 和 d 。
總共生成6個數字:p1、p2、n、φ(n)、e、d
關於RSA的安全:
除了公鑰用到了n和e 其餘的4個數字是不公開的。
目前破解RSA得到d的方式如下:
1、要想求出私鑰 d 。由於e d = φ(n) k + 1。要知道e和φ(n);
2、e是知道的,但是要得到 φ(n),必須知道p1 和 p2。
3、由於 n=p1*p2。只有將n因數分解才能算出。
由於Mac系統內置OpenSSL(開源加密庫),所以我們可以直接在終端上使用命令來玩RSA. OpenSSL中RSA演算法常用指令主要有三個:
1、由於RSA加密解密用的不是一套數據,所以其保證了安全性。
2、由於私鑰過大,所以效率較低
3、如果有一天量子計算機被普及(計算速度極快),那麼1024位已經不足以讓RSA安全。
❸ java 生成的rsa私鑰怎麼給ios解密
java使用jdk的KeyPairGenerator 生成公鑰和私鑰;
java服務端把公鑰轉化為一個字元串發送給ios端;
然後ios端根據此字元串還原公鑰,使用公鑰進行加密;
服務端使用秘鑰進行解密;
邏輯是這樣的沒問題,可是語言不通,java發送出來的字元串IOS不一定能還原成公鑰,就算有還原的方法,還原了也不一定對(與java端私鑰不對稱);同理私鑰也一樣
❹ ios 中開發中用戶信息中的加密方式有哪些
5.1 通過簡單的URLENCODE + BASE64編碼防止數據明文傳輸
5.2 對普通請求、返回數據,生成MD5校驗(MD5中加入動態密鑰),進行數據完整性(簡單防篡改,安全性較低,優點:快速)校驗。
5.3 對於重要數據,使用RSA進行數字簽名,起到防篡改作用。
5.4 對於比較敏感的數據,如用戶信息(登陸、注冊等),客戶端發送使用RSA加密,伺服器返回使用DES(AES)加密。
原因:客戶端發送之所以使用RSA加密,是因為RSA解密需要知道伺服器私鑰,而伺服器私鑰一般盜取難度較大;如果使用DES的話,可以通過破解客戶端獲取密鑰,安全性較低。而伺服器返回之所以使用DES,是因為不管使用DES還是RSA,密鑰(或私鑰)都存儲在客戶端,都存在被破解的風險,因此,需要採用動態密鑰,而RSA的密鑰生成比較復雜,不太適合動態密鑰,並且RSA速度相對較慢,所以選用DES)
把相關演算法的代碼也貼一下吧 (其實使用一些成熟的第三方庫或許會來得更加簡單,不過自己寫,自由點)。注,這里的大部分加密演算法都是參考一些現有成熟的演算法,或者直接拿來用的。
1、MD5
//因為是使用category,所以木有參數傳入啦
-(NSString *) stringFromMD5 {
if(self == nil || [self length] == 0) {
return nil;
}
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return [outputString autorelease];
}
2、Base64
+ (NSString *) base64EncodeData: (NSData *) objData {
const unsigned char * objRawData = [objData bytes];
char * objPointer;
char * strResult;
// Get the Raw Data length and ensure we actually have data
int intLength = [objData length];
if (intLength == 0) return nil;
// Setup the String-based Result placeholder and pointer within that placeholder
strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char));
objPointer = strResult;
// Iterate through everything
while (intLength > 2) { // keep going until we have less than 24 bits
*objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
*objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
*objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)];
*objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f];
// we just handled 3 octets (24 bits) of data
objRawData += 3;
intLength -= 3;
}
// now deal with the tail end of things
if (intLength != 0) {
*objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
if (intLength > 1) {
*objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
*objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2];
*objPointer++ = '=';
} else {
*objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4];
*objPointer++ = '=';
*objPointer++ = '=';
}
}
// Terminate the string-based result
*objPointer = '\0';
NSString *rstStr = [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];
free(objPointer);
return rstStr;
}
3、AES
-(NSData*) EncryptAES: (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;
}
4、RSA
- (NSData *) encryptWithData:(NSData *)content {
size_t plainLen = [content length];
if (plainLen > maxPlainLen) {
NSLog(@"content(%ld) is too long, must < %ld", plainLen, maxPlainLen);
return nil;
}
void *plain = malloc(plainLen);
[content getBytes:plain
length:plainLen];
size_t cipherLen = 128; // currently RSA key length is set to 128 bytes
void *cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plain,
plainLen, cipher, &cipherLen);
NSData *result = nil;
if (returnCode != 0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %ld", returnCode);
}
else {
result = [NSData dataWithBytes:cipher
length:cipherLen];
}
free(plain);
free(cipher);
return result;
}
❺ iOS RSA加密生成公鑰私鑰
該命令生成一個模長 2048 位,名字為 rsa_private_key.pem 、 PKCS1 格式的 RSA 私鑰文件.
genrsa :指定生成演算法使用 RSA
-out :後面參數是生成的私鑰的文件名
2048 :生成私鑰的模長,單位位元組(bits)
根據生成的私鑰 rsa_private_key.pem 文件,生成公鑰 rsa_public_key.pem 文件
生成名字為 rsa_pkcs8_private_key.pem 的私鑰文件
Java 和 Android 用到的密鑰:
公鑰: rsa_public_key.pem
私鑰: rsa_pkcs8_private_key.pem
終端會提示輸入國家、省市、所在地、組織、組織單位、常用名稱、郵箱地址等信息,按要求填寫(可以隨便填寫), 輸入完對應信息後會提示輸入一個密碼 :
最終會生成 rsacert.csr 文件
用最開始生成的私鑰 rsa_private_key.pem 和 rsacert.csr 證書請求文件生成一個數字證書 rsacert.crt
使用 x509 工具自建CA。由於 x509 無法建立證書請求文件,所以只能使用 openssl req 來生成請求文件,然後使用 x509 來自簽署, 也可以用來簽署他人的證書請求,即為他人頒發證書。
知識點 :
終端會提示設置密碼,該密碼是 .p12 私鑰的密碼(用 private_key.p12 私鑰解密時, 要用到該密碼, 需要記錄下 ), 會提示再次輸入檢驗剛才輸入的密碼.
❻ RSA公鑰、私鑰生成,詳細講解
RSA密鑰生成過程
openssl:是一個自由的軟體組織,專注做加密和解密的框架。
genrsa:指定了生成了演算法使用RSA
-out:後面的參數表示生成的key的輸入文件
1024:表示的是生成key的長度,單位位元組(bits)
可以拿著這個文件去數字證書頒發機構(即CA)申請一個數字證書。CA會給你一個新的文件cacert.pem,那才是你的數字證書。(要收費的)
509是一種非常通用的證書格式。
將用上面生成的密鑰privkey.pem和rsacert.csr證書請求文件生成一個數字證書rsacert.crt。這個就是公鑰
![Upload Snip20160323_6.png failed. Please try again.]
在 iOS開發中,公鑰是不能使用base64編碼的,上面的命令是將公鑰的base64編碼字元串轉換成二進制數據
在iOS使用私鑰不能直接使用,需要導出一個p12文件。下面命令就是將私鑰文件導出為p12文件。
執行完上面的這些,我們現在就得到了四個文件
需要在finder中進行搜搜,搜p.p12、reacert.der即可,為了方便查找,可將其導出到別的文件夾中。
註:p.p12 為私鑰 reacert.der 為公鑰