iOS:關(guān)于iPhone連接X(jué)code時(shí),RSA加密失敗的一點(diǎn)總結(jié)

前言:

前段時(shí)間做RSA加密的時(shí)候,在調(diào)試的過(guò)程中,經(jīng)常失敗,后臺(tái)接收到的加密參數(shù)為空,但是這種不是經(jīng)常發(fā)生,而是隨機(jī)的。經(jīng)過(guò)測(cè)試,發(fā)現(xiàn),這種情況在單獨(dú)使用真機(jī)、模擬器的時(shí)候都不發(fā)生,只有在真機(jī)連接xcode進(jìn)行調(diào)試的時(shí)候才會(huì)發(fā)生。

追蹤:

在筆者打了N多斷點(diǎn)之后,終于找到了問(wèn)題發(fā)生的根源。在RSA加密的類中,有這么一段代碼:

 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 key
 SecKeyRef keyRef = nil;
 status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
    
 if(status != noErr){
  return nil;
 }
 return keyRef;

在模擬器上測(cè)試的時(shí)候:

屏幕快照 2016-04-20 下午3.02.06.png

真機(jī)連接X(jué)code的時(shí)候:

屏幕快照 2016-04-20 下午3.03.43.png

問(wèn)題就出在:

 OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);

stack overflow發(fā)現(xiàn)有的人也遇到了類似的問(wèn)題,現(xiàn)總問(wèn)題結(jié)如下:
*** 1.當(dāng)我在連接著Xcode的真機(jī)設(shè)備上運(yùn)行app的時(shí)候,我試圖獲取鑰匙串,卻由于-34018的錯(cuò)誤導(dǎo)致運(yùn)行失敗。缺乏鑰匙串錯(cuò)誤代碼開(kāi)發(fā)文檔,而且也很難重現(xiàn)此錯(cuò)誤(發(fā)生的概率大概30%,我也不知道為什么發(fā)生)。由于缺乏相關(guān)的文檔,所以調(diào)試這種錯(cuò)誤就變得非常困難。為什么會(huì)出現(xiàn)此錯(cuò)誤,如何解決?xcode5、ios7***

解決方案

方案一:
你不得不通過(guò)在你的test target中添加下面的代碼作為運(yùn)行腳本來(lái)簽名你的 .xcttest文件夾

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

方案二:
在查看源碼 之后,我注意到鑰匙串通過(guò)一種安全進(jìn)程(區(qū)別于app的進(jìn)程)獲取。
app和安全進(jìn)程通過(guò)一項(xiàng)稱之為XPC的技術(shù)進(jìn)行對(duì)話。安全進(jìn)程經(jīng)由XPC的啟動(dòng)命令啟動(dòng)。你可以發(fā)現(xiàn)真機(jī)(模擬器也是如此)app的安全進(jìn)程正在運(yùn)行,它的父進(jìn)程也已經(jīng)啟動(dòng)。
我猜測(cè),有可能某些未知的原因?qū)е?code>安全進(jìn)程啟動(dòng)失敗或者啟動(dòng)太慢,使得你使用它的時(shí)候還沒(méi)有準(zhǔn)備好。
或許,你可以考慮如何重啟安全進(jìn)程。

方案三,來(lái)自蘋果官方回復(fù):

1.我們終于能夠在ios8.3里重現(xiàn)-34018錯(cuò)誤,這是我們查找問(wèn)題根源和修復(fù)問(wèn)題的第一步。

可是,我們并不能給出確切的解決時(shí)間,但是由于已經(jīng)影響了很多的開(kāi)發(fā)者,我們也非常希望盡快解決。

作為變通方案,我建議在在didFinishLaunchingWithOptions 和applicationDidBecomeActive: 兩個(gè)方法之前添加一個(gè)小的延時(shí)給獲取字符串爭(zhēng)取一點(diǎn)時(shí)間。然而,好像并沒(méi)有明顯的作用,這就意味著除了重啟app確實(shí)沒(méi)有更好的解決方法。

這個(gè)問(wèn)題似乎和內(nèi)存壓力也有一定的關(guān)系,在解決這個(gè)問(wèn)題的時(shí)候,要積極處理內(nèi)存警告的問(wèn)題。

更新:
這個(gè)復(fù)雜的問(wèn)題有幾種可能的原因

  • 一些情況下是由于不正確的app簽名造成的,你可以很清楚的辨別這種原因,因?yàn)樗?00%可以重現(xiàn)。
  • 有些情況下這種問(wèn)題的造成是由于iOS支持app開(kāi)發(fā)環(huán)境中的一個(gè)bug
    造成的。由于os中的另一個(gè)bug掩蓋了它的影響,排查這個(gè)問(wèn)題非常困難,這就意味著這個(gè)問(wèn)題在內(nèi)存面臨巨大壓力的時(shí)候會(huì)突然出現(xiàn),我們相信這個(gè)問(wèn)題在ios9.3中已經(jīng)解決。
  • 我們猜測(cè)可能有其他的原因造成了這個(gè)問(wèn)題

所以,如果你在運(yùn)行ios9.3及以后系統(tǒng)的用戶設(shè)備上(未和Xcode鏈接)遇到此問(wèn)題,請(qǐng)記錄此bug并報(bào)告給我們。)

方案四:
我的app(iOS8.4)現(xiàn)在極少遇到 -34018的錯(cuò)誤,在做過(guò)一些調(diào)查之后,我發(fā)現(xiàn)當(dāng)app頻繁的從鑰匙串請(qǐng)求數(shù)據(jù)的時(shí)候就會(huì)造成這種問(wèn)題。例如,在同一時(shí)間,在不同的加載模塊,兩次讀同一個(gè)specific key 的值。為了解決這個(gè)問(wèn)題,我在內(nèi)存中緩存了這個(gè)值。

方案五:
其他的方式對(duì)我都沒(méi)有用,我清空了我設(shè)備上所有的配置文件,以及一些通配符配置文件(這些文件似乎是重點(diǎn)),為了這么做,去window的Devices,然后右擊你的(連接)的iphone:

THffv.png

點(diǎn)擊"Show provisioning profiles"刪除相關(guān)的文件,尤其是team相關(guān)的配置文件包括帶*號(hào)的文件,然后重新導(dǎo)入。
jyQl1.png

方案六:

我在Xcode6.2 、iphone6、ios8.3環(huán)境下,在測(cè)試設(shè)備上也出現(xiàn)這種問(wèn)題。更清楚的說(shuō),在運(yùn)行Xcode tests的時(shí)候這種情況沒(méi)有發(fā)生,在我的真機(jī),模擬器上都是正常的。

以上的方式都對(duì)我無(wú)效。

我臨時(shí)的改變了獲取的方式從
kSecAttrAccessibleAfterFirstUnlock 到kSecAttrAccessibleAlwaysThisDeviceOnly,運(yùn)行app,完美運(yùn)行,且可以寫到鑰匙串,然后我再改回到kSecAttrAccessibleAfterFirstUnlock,問(wèn)題似乎永久性的解決了。

總結(jié):

非常遺憾,筆者這個(gè)問(wèn)題仍舊沒(méi)有解決,希望筆者摘錄的幾種解決方式給大家一點(diǎn)思路。

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

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,319評(píng)論 25 708
  • 前面我們分享了如何通過(guò)主動(dòng)控場(chǎng)來(lái)增加培訓(xùn)場(chǎng)能,但俗話說(shuō)得好,計(jì)劃趕不上變化,培訓(xùn)現(xiàn)場(chǎng)總是會(huì)出現(xiàn)一些我們意想不到的情...
    培訓(xùn)愛(ài)好者閱讀 290評(píng)論 0 0
  • 我曾幻想撐著篙 為旅客擺渡 伴著水鳥(niǎo)、鯽魚(yú)和烏龜 用還算長(zhǎng)的壽命 過(guò)一種悠閑生活 但如今我背著行囊站在泮旁 水上空...
    森林初青閱讀 252評(píng)論 0 0
  • http://mp.weixin.qq.com/s/IDT3R3a50Jvm1l9-7y5DEQ
    老盧120閱讀 146評(píng)論 0 0
  • 在困難,波折中,經(jīng)歷上帝的沉默,是痛苦的,孤獨(dú)的,敢到被拋棄,這是最真實(shí)的感受。產(chǎn)生對(duì)上帝的埋怨都是人非常正常的反...
    UncleTea閱讀 1,361評(píng)論 0 0

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