首先最近我們在做一個APP 但是我們數據交互都是明文的=- = 這咋辦勒,傻子也知道加密一下咯。可是加密也有問題 對稱加密的話,人家破解你的應用就能知道了。所以用到了非對稱加密并且每個APP生成不同的RSA密鑰對。
實現再iOS上面實現RSA加密并不難,因為iOS中有openssl 和 系統自帶的 security.framework。我這里選擇了openSSL 因為我比較懶 =- = 發現別人已經寫好了 直接就用了唄。security.framework其實也不錯的,就是我還不知道咋用。
Demo地址
這個是GitHub上面一個人寫好的,實現了OpenSSL 的RSA加密
1.在iOS上 使用OpenSSL 生成的公鑰私鑰編碼是X509的,而我們服務器使用的是.NET的(.NET的編碼是PKCS#8) PS:(←。 ←)我也不知道對不對,這幾天百度的結果是醬紫的,
.NET與java(android)RSA通信 可以參考這個地址,我個人總結的是,JAVA支持集中不同的編碼格式,所以JAVA通信問題不大
2.如何轉換不同的證書
1.先找了如何讓兩個生成的密文一樣,但是發現有paddingPKCS1這種東西肯定不行(宣告失?。?br />2.想辦法生成一個PKCS#8的密鑰對(我試了一些openssl的命令行,可是最終密鑰對要app生成的,所以沒繼續,也宣告失敗了)
3..NET服務端使用openssl解決該問題(可是如果這樣的話 ,android又需要修改,所以宣布放棄了)
4.轉換密鑰對編碼(其實其中我還找了 iOS與Java通信之類的,這里我就不一一闡述了)
這個彎路其實挺長的,我總結了一下是這么幾點,但是歷史一天時間了。。。
主要我就來講一下最后一點吧??隙〞信笥褑栁沂沁@么發現這兩個密鑰對的區別的。
不要著急,我們廣告之后繼續。
首先我建議各位下載一下那個github里面的代碼,這樣容易理解。
當你運行完一次程序,你會發現你的iphone模擬器目錄下面會有 publicKey.pem 和 PRivateKey.pem
我們需要把publicKey交給服務端,這樣他加密的東西,只有我這個privateKey可以解,這些原理我就不多做說明了。
然后我們打開publicKey會是一下
/* This return value based on the key that generated by openssl. -----BEGIN RSA PUBLIC KEY----- MIGHAoGBAOp5TLclpWCaNDzHYPfB26SLmS8vlSXH4PyKopz5OS5Vx994FBQQLwv9 2pIJQsBk09egrL0gbASK1VCwDt0MmaiyrNFl/xaEzB/VOvjoojBUzMMIca9fKmx5 GAzSbSP7we64dhvrziuuNVTuM/e2XSa2skKFHMI0bCq4+pNYhvRhAgED -----END RSA PUBLIC KEY----- */
然后我們看一下源代碼
- (NSString*)publicKeyBase64{ NSFileManager *fm = [NSFileManager defaultManager]; if ([fm fileExistsAtPath:OpenSSLRSAPublicKeyFile]) { NSString *str = [NSString stringWithContentsOfFile:OpenSSLRSAPublicKeyFile encoding:NSUTF8StringEncoding error:nil]; NSData *data = [self publicKeyBitsWithString:[[str componentsSeparatedByString:@"-----"] objectAtIndex:2]]; return [data base64EncodedString]; } return nil;}
這里我們看到OpenSSL將整個證書文件Base64了一下,沒錯,這里確實沒錯。
我起初再這里還繞彎了 我以為是key錯誤了。其實OpenSSL 正確的publicKey轉NSData后 大小一定是162,如果你只是其中那一段(沒有----****----這兩行的話)就是140了。
我同事在查看OpenSSL.NET的源代碼的時候發現了一段轉換過程,然后我看了一下.NET端的代碼,代碼如下
看得懂.net的或者看不懂.NET的應該都可以看的懂很簡單的代碼。
so 我饒了這么大的彎子,你們應該一看就知道了接下來就是處理了,這么讓publicKey變成128-》PKCS#8標準的編碼呢,按照.NET的OpenSSL代碼翻譯下一下
if((unsigned long)[NSData dataWithBase64EncodedString:wrapper.publicKeyBase64].length<162){ NSLog(@"公鑰格式不正確!"); return;}else{ //取出.NET可以使用的 PubKey NSData *keyData=[NSData dataWithBase64EncodedString:wrapper.publicKeyBase64]; NSData * newKeyData =[keyData subdataWithRange:NSMakeRange(29, 128)]; NSLog(@"NewPubKey:%@",[newKeyData base64EncodedString]);}
上面這個就是我的處理過程 =- = 這次的這個RSA的坑是真坑啊,我要是沒看服務端代碼 肯定搞不出來,因為本地加解密都是OK的,唉,所以這件事情告訴我們,看問題必須得從多個方面看,而且不能只是看自己手頭上的可以從多個方面入手尋找資料。不過這次也是因為我會.NET所以我會想到去看一下。
這個坑記錄一下 希望可以幫到大家
這個是前一段時間坑過的一個東西,發現網上都找不到資料 古留下這篇文章...
我也坑過AES 可以看我的個人博客,當然我也會更新到這里來~
新聞熱點
疑難解答