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

前言:

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

追蹤:

在筆者打了N多斷點(diǎ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;

在模擬器上測試的時候:

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

真機(jī)連接Xcode的時候:

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

問題就出在:

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

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

解決方案

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

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

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

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

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

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

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

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

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

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

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

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

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

THffv.png

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

方案六:

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

以上的方式都對我無效。

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

總結(jié):

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

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

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

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