SecItemAdd ve SecItemCopyMatching, -34018 hata kodunu döndürüyor (errSecMissingEntitlement)


116

Bazen Xcode'dan cihazda bir uygulama çalıştırdığımda, anahtar zincirine erişmeye çalışırdım ancak -34018 hatası nedeniyle başarısız oluyorum. Bu, belgelenmiş anahtar zinciri hata kodlarının hiçbiriyle eşleşmez ve tutarlı bir şekilde çoğaltılamaz. (belki zamanın% 30'unda olur ve neden olduğu benim için net değil). Bu problemde hata ayıklamayı çok zorlaştıran şey, dokümantasyon eksikliğidir. Buna neyin sebep olduğu ve nasıl düzeltileceği hakkında bir fikriniz var mı? Xcode 5 kullanıyorum ve cihazda iOS 7.0.4 çalıştırıyorum.

Burada bununla ilgili açık bir sorun var: https://github.com/soffes/sskeychain/issues/52

DÜZENLEME: İstek başına anahtar zinciri erişim kodu ekleme

SSKeychainKütüphaneyi anahtarlık ile arayüz oluşturmak için kullanıyorum . İşte pasaj.

#define SERVICE @"default"

@implementation SSKeychain (EXT)

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    NSError *error = nil;
    BOOL success = NO;
    if (value) {
        success = [self setPassword:value forService:SERVICE account:key error:&error];
    } else {
        success = [self deletePasswordForService:SERVICE account:key error:&error];
    }
    NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
    if (!success) {
        LogError(@"Unable to set value to keychain %@", error);
    }
    LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil);
    if (value == nil)
        LogWarn(@"Setting keychain %@ to nil!!!", key);
}

+ (NSString *)valueForKey:(NSString *)key {
    NSError *error = nil;
    NSString *value = [self passwordForService:SERVICE account:key error:&error];
    if (error && error.code != errSecItemNotFound) {
        NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error);
        LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error);
    }
    return value;
}

+ (BOOL)removeAllValues {
    LogInfo(@"Completely Reseting Keychain");
    return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) {
        return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]];
    }];
}

@end

Çoğu zaman gayet iyi. Bazen, anahtar zincirine yazamadığım veya anahtar zincirinden okuyamadığım ve kritik onaylama başarısızlığına neden olan iddia başarısızlıklarına rastlarım.


aynı sorunu yaşıyorum ve yeniden oluşturamıyorum ... Apple'ın KeychainItemWrapper sınıfını kullanıyorum. Bazen Google Analytics'ten aynı hata mesajıyla çöker. Google Analytics v3.02 kullanıyorum.
Joey

Ayrıca, AppStore'daki uygulamada sorun yok gibi görünüyor. yalnızca geliştirme sürümü uygulamasında olur.
Joey

2
Uygulama mağazası sürümü için crashlytics'im var ve ne yazık ki, geliştiriciye göre daha az sıklıkta olsa da uygulama mağazasında da görülüyor: /
Tony

3
Anahtar zincirinden uzaklaşmayı düşünüyorum çünkü anahtarlıkta depolanan verilerin bu şekilde rastgele kaybolması, uygulama için neredeyse ölümcül bir hata.
Tony

2
Ayrıca aralıklarla ortaya çıkan bu sorunu da görüyoruz. -34018 durumu dahil secItemCopyMatching'den beklenmedik bir rc aldığımızda bir istisna oluşturuyoruz. Anahtar zincirinden ihtiyacımız olan değeri elde ettiğimizde, onu uygulama belleğinde önbelleğe aldığımız ve ardından anahtar zinciri erişimi olmadan oradan hizmet ettiğimiz bir mekanizma eklemeyi (isteksizce) denedik. Ancak şimdi, onu almak için bir anahtarlık erişiminin bir -34018 ile başarısız olduğu nadir durumlar görüyoruz. Bir -34018'den sonra operasyonu yeniden denemeyi deneyen oldu mu?
Chris Markle

Yanıtlar:


45

iOS 10 / XCode 8 Düzeltme:

KeyChain Yetkisi Ekleyin, Proje ayarlarına gidin-> Yetenekler-> Anahtar Zinciri Paylaşımı-> Anahtar Zinciri Grupları Ekle + Açın

Apple'dan bir cevap:

GÜNCELLEME: Nihayet -34018 hatasını iOS 8.3'te yeniden oluşturabildik. Bu, temel nedeni belirlemenin ve ardından bir düzeltme bulmanın ilk adımıdır.

Her zamanki gibi, bir yayın zaman dilimini taahhüt edemiyoruz, ancak bu birçok geliştiriciyi etkiledi ve gerçekten bu sorunun çözülmesini istiyoruz.

Daha önce, uygulamada küçük bir gecikme eklemeyi önerdim: didFinishLaunchingWithOptions ve applicationDidBecomeActive: bir çözüm olarak anahtar zincirine erişmeden önce. Ancak, bu aslında yardımcı görünmüyor. Bu, şu anda uygulamayı yeniden başlatmaktan başka bilinen bir çözüm olmadığı anlamına gelir.

Sorun bellek baskısıyla ilgili gibi görünüyor, bu nedenle bellek uyarılarını ele alırken daha agresif olmak sorunu hafifletebilir.

https://forums.developer.apple.com/thread/4743#14441

GÜNCELLEME

Tamam, işte son haberler.
Bu, birden çok olası nedeni olan karmaşık bir sorundur:

  • Sorunun bazı örnekleri, yanlış uygulama imzalamadan kaynaklanıyor. Bu durumu kolayca ayırt edebilirsiniz çünkü sorun% 100 tekrarlanabilir.
  • Sorunun bazı örnekleri, iOS'un uygulama geliştirmeyi destekleme biçimindeki bir hatadan kaynaklanıyor (r. 23,991,853). Bu hata ayıklama, işletim sistemindeki başka bir hatanın (r. 23,770,418) etkisini maskelemesi, yani sorunun yalnızca cihaz bellek baskısı altındayken ortaya çıkması nedeniyle karmaşıktı. Bu sorunların iOS 9.3'te çözüldüğüne inanıyoruz.
  • Bu sorunun daha fazla nedeni olabileceğinden şüpheleniyoruz.

Dolayısıyla, iOS 9.3 veya sonraki bir sürümünü çalıştıran bir kullanıcı cihazında (Xcode tarafından konuşulmamış bir cihaz) bu sorunu görürseniz, lütfen bununla ilgili bir hata raporu gönderin. Aygıt sistem günlüğünü hata raporunuza dahil etmeye çalışın (Müşteri aygıtlarıyla uğraşırken bunun yanıltıcı olabileceğini anladım; bir seçenek, müşteriden sistem günlüğünü görüntülemesini sağlayan Apple Configurator'ı yüklemesini istemektir). Ve bir hata bildirirseniz, lütfen sadece kayıt için hata numaranızı gönderin.

Apple adına, bu oldukça korkunç sorunun izini sürmek için gösterdikleri çabadan dolayı herkese teşekkür etmek istiyorum. Paylaş ve Keyfini çıkar

https://forums.developer.apple.com/thread/4743#126088


2
Sorun hala iOS 9.2, iPhone 5S'de yeniden üretiliyor.
DevGansta

1
Görünüşe göre iOS 9.3, bu sorunu bağladığınız ileti dizisindeki Apple'ın en son yanıtına göre çözmelidir . @daidai, cevabınızı bu yeni bilgilerle günceller misiniz?
jf

1
@YoonLee, bunu iOS10'da da görüyorum - ayrıca AWS'nin 2.4.8 SDK'sını kullanıyor. AWSClientContext.m satır 54'te hata tetiklendi. Bunu çözme şansınız var mı?
CharlesA

1
@YoonLee btw, bunu aşağıdaki cevaplardan birini kullanarak çözdüm: 'Hedef yetenekler için
KeyChain

1
@CharlesA Evet, o gün çözdüm. Haklısın. Görünüşe göre 'KeyChain Yetkilendirme açık' sorunu çözüyor. Şaşırtıcı bir şekilde, bu hata her zaman tetiklenmez. Her neyse, şimdi bunu açıyorum.
Yoon Lee

26

Temel olarak, aşağıdakileri test hedefinize bir çalıştırma betiği olarak ekleyerek .xcttest klasörünüzü kodlamanız gerekir.

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

Anahtar zincirimi cihazda test ederken çok sayıda -34018 hatası aldım ve bu onu düzeltmeyi başardı.

Sorun test hedefinizde yoksa muhtemelen çözüm bu değildir.


Bunun test ortamında düzeltildiğini doğruladı. Çalıştırma betiğini gerçek test hedefine eklemem gerekiyordu (örneğin, cihazda çalışan yapı hedefine değil, tüm birim testlerine sahip olanlar). Ayrıca bunun simülatörde değil, yalnızca cihazda bir sorun olduğunu doğruladı.
iwasrobbed

2
Bunu yaptığımda ": kimlik bulunamadı Command / bin / sh, çıkış kodu 1 ile başarısız oldu" mesajı alıyorum? Sanırım $ CODE_SIGN_IDENTITY bende yok. Bunu nasıl düzelttiğim hakkında bir fikrin var mı?
Daniel Coffman

1
@DanielCoffman, hedef ayarlarınıza gitmeli ve Kod İmzalama Kimliği'nde "iOS Geliştiricisi" (veya başka herhangi bir geçerli kimliği) seçmelisiniz. Bu, yapı hatasını düzeltir, ancak en azından benim için Anahtar Zinciri sorununu çözmez. Hala -34018 hata kodunu alıyorum.
Marcin

3
Teşekkürler Marcin. Xcode 6 beta'ya geçtiğimde bu hatayı almaya başladım. Bu konudaki hiçbir öneri çözülmedi. Xcode 5'e geri döndürüldü ve -34018 artık oluşmuyor.
Daniel Coffman

XCode 6.3'ü kullandığımdan beri de bu hatayı ilk kez yaşıyorum.
Vladimír Slavík

13

Kaynak kodunu inceledikten sonra . Anahtar zinciri özelliklerine, kendi sürecinde (uygulama sürecinden ayrı olarak) çalışan bir güvenlik arka plan programı aracılığıyla erişildiğini fark ettim.

Uygulamanız ve güvenlik süreci, XPC adı verilen bir teknoloji aracılığıyla birlikte 'konuşur' .

Gerekirse, securityd, XPC tarafından iyi bilinen launchd komutu ile başlatılır. Muhtemelen arka plan programının Activity Monitor Uygulamasında çalışıp çalışmadığını (tabii ki Simülatörde çalışıyorsa) ve ana işleminin başlatıldığını kontrol edebilirsiniz.

Buradaki tahminim, bilinmeyen herhangi bir nedenden ötürü, güvenlik daemonunun başlatılmaması veya çok yavaş yapması ve kullanmaya çalıştığınızda hazır olmaması olasıdır.

Belki deemon'u nasıl önceden başlatacağınızı düşünebilirsiniz.

Daha kesin olmadığım için özür dilerim. Umarım soruşturmalarınızda bir adım öteye gitmenize yardımcı olur.


2
Bu sorunu yalnızca uygulamam aşağıdaki uygulama temsilcisi yöntemiyle bir Derin bağlantı aracılığıyla yeniden açıldığında alıyorum: - (BOOL) uygulaması: (UIApplication *) uygulama handleOpenURL: (NSURL *) url. Uygulamayı yeni başlatırsam, anahtarlık yazma çalışır ve uygulamayı küçültür ve büyütürsem yine de çalışır. Bu sorun yalnızca derin bağlantıyla yeniden açtığımda ortaya çıkıyor. Projemde yapılandırılmış MyApp.entitlements var (Yetenekler sekmesinde Anahtar Zinciri Paylaşımı) Xcode 7 beta 4
FranticRock

Benim durumum, yalnızca uygulama derin bağlantılı olduğunda ortaya çıkan Alex'inkine benzer. Aksi takdirde iyi çalışır. Uygulama başka bir uygulamadan açıldığında bazı bağlamlar doğru olmayabilir.
CodeBrew

12

Kodumu Xcode 6 beta'da iOS 8 SDK ile oluşturup çalıştırdıktan sonra benzer davranışları gözlemliyorum (Xcode 5 / iOS 7 ile düzgün çalışıyor). Xcode 6'da, iOS Simulator SecItemCopyMatching her zaman -34018 döndürür. Capabilities sekmesinde "Keychain Sharing" i açtıktan sonra çalışmaya başladı.

Ancak başka bir sorunum var. Demo uygulaması tarafından (diğerlerinin yanı sıra) kullanılan statik kitaplık geliştiriyorum. Yukarıdaki çözüm Demo uygulama projesi için çalışıyor, ancak statik kitaplık projemi birim test etmeye çalıştığımda tam olarak aynı hatayı alıyorum. Ve sorun şu ki, statik kitaplık projemde Yetenekler sekmesi yok (çünkü bu bağımsız uygulama değil).

Test hedefinde kod imzalayarak JorgeDeCorte tarafından burada yayınlanan çözümü denedim, ancak benim için çalışmıyor.


8
Ve iOS 8 beta 3'e geri dönelim :)
Mustafa

7
Ve iOS 9.0'a geri dönüyor
Alex Stone

4
Ve şimdi iOS 9.2'ye geri dönelim :-(
Vamos

4
İOS

3
Ve iOS 10 beta 5'e geri dönüyor
Pascal,

6

Uygulamayı başlatırken tüm kesme noktalarını devre dışı bırakmayı deneyin Xcode'dan . Bunları daha sonra etkinleştirebilirsiniz.

(Yukarıdaki geçici çözümlerin hiçbiri benim için işe yaramadı)


Garip. Görünüşe göre bu sorunu benim için de çözüyor! Simülatörde hata ayıklamaya her başladığımda -34018 OSStatus'u deneyimleyebiliyordum.
midori

4

7.1 ve 8.0 çalıştıran simülatörde de aynı sorunu yaşadım. Biraz araştırma yaparken, Apple örnek uygulamasının hedef yetenekleri için KeyChain Sharing'in açık olduğunu fark ettim. Uygulamam için açtım, bu da varsayılan değerlerle bıraktığım bir yetki dosyası oluşturmayla sonuçlandı ve şimdi artık -34018 hatası almıyorum. Bu ideal değil ama KeyChain paylaşım seçeneğini şimdilik yaşayacağım.


4

Bir .xctest paketini kodlamak, bazı durumlarda göründüğü kadar kolay değildir. Esasen JorgeDeCorte, verilen kısa çizginin geliştiricilerin çoğu için yeterli olduğu yanıtında haklıdır Run Script.

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

Ancak anahtar zincirinizde birden fazla sertifikanız olduğunda, aşağıdaki satırda bu başarısız olacaktır.

iPhone Developer: ambiguous (matches "iPhone Developer: Your Name (ABC123DEF45)" and "iPhone Developer: Your Name (123ABC456DE)"

Birden fazla sertifikayla bile doğru sertifikayı almanın bir çözümü bu kısa komut dosyasıdır. Elbette bu ideal değil, ancak bildiğim kadarıyla Xcode'un bulduğu ve .app'ınızı imzalamak için kullandığı sertifikayı alma şansınız yok.

echo "codesign --verify --force --sign \"$CODE_SIGN_IDENTITY\" \"$CODESIGNING_FOLDER_PATH\""
IDENTITIES=`security find-identity -v -s "Code Signing" | grep "iPhone Developer" | awk '{ print $2 }'`

for SHA in $IDENTITIES; do
    codesign --verify --force --sign $SHA "$CODESIGNING_FOLDER_PATH"
    if [ $? -eq 0 ]; then
        echo "Matching identity found: $SHA"
        exit 0
    fi
done;

exit 1

4

Ben de bununla ısırıldım ve diğer geçici çözümlerin hiçbirinde başarılı olamadım. Daha sonra, uygulamamla ilgili olan tümünün yanı sıra tüm joker karakter profillerini de silerek cihazların kendisindeki ön hazırlık profillerimi temizledim (asıl mesele bu gibi görünüyor). Bunu yapmak için, Xcode'daki "Cihazlar" Penceresine gidin ve (bağlı) telefonunuza sağ tıklayın:

"Temel hazırlık profillerini göster" i tıklayın ve ilgili olanları ve özellikle ekip profillerini silin:

yıldız işaretli olanlar dahil. Uygulamayı yeniden yükledikten sonra her şey normale döndü.


Bu, uygulamayı Xcode'dan çalıştırmama ve geliştirme sürecine devam etmeme yardımcı oldu.
salabaha

Bir AdHoc sürümü oluştururken, hangi PP'lerin kullanıldığını kontrol edebilirsiniz. Herhangi bir XC: profili görürseniz, bunları silin ve PP'nizi yenileyin!
dogsgod

Bunun nasıl bir faktör olabileceğini görebiliyorum. Orada ne dağınıklık !! Sonbahar temizliği yapmak
David

3

Bu sorunu çözdüm (sanırım). Cihazımda geçerli bir imza kimliğine sahip olmadığını gösteren bir joker karakter sağlama profilim vardı. Ayrıca uygulamam için geçerli bir temel hazırlık profilim vardı. Joker karakter profilini sildiğimde, -34018 hatalarını almayı bıraktım.

Ayrıca, hedefin Derleme Ayarlarının Kod İmzalama bölümünde listelenen kod imzalama kimliğinin ve ön hazırlık profilinin uygulama için olanla (genel "iPhone Geliştiricisi" değil) aynı olduğundan emin oldum


Buna benzer şekilde benim için düzeltildi. Proje düzeyinde kod imzalamayı Hata Ayıklama için "iPhone Geliştirici" ve Sürüm için "iPhone Dağıtımı" olarak ayarlayın. Daha sonra ana hedef üzerindeki geçersiz kılmaları kaldırdım, böylece aynısını gösterdiler. Daha önce, anahtarlıktaki tasarruf zamanın% 100'ünde başarısız oluyordu. Daha sonra, anahtarlıktaki tasarruf istikrarlı görünüyor.
jowie

2

Ben başlamıştı -34018 çok nadiren benim app (iOS 8.4) hatayı. Biraz araştırmadan sonra, uygulamanın anahtarlıktan çok sık veri istediğinde bu sorunun ortaya çıktığını fark ettim .
Örneğin, benim durumumda, farklı uygulama modüllerinden aynı anda belirli bir anahtar için iki okuma isteğiydi.
Bu değeri bellekte önbelleğe aldığımı düzeltmek için


1

Xcode 6.2, iPhone 6, iOS 8.3 ile bir test cihazında çalışırken aynı sorunu birden yaşıyordum. Açık olmak gerekirse, bu Xcode testlerini çalıştırırken değil, gerçek uygulamayı cihazımda çalıştırırken yaşandı. Simülatörde gayet iyiydi ve uygulamanın kendisi üzerinde çalışırken yakın zamana kadar mükemmeldi.

Burada bulabildiğim tüm önerileri denedim, örneğin cihazımdaki ön hazırlık profillerini kaldırmak (TÜMÜNÜ kaldırdım), projemde Anahtar Zinciri Paylaşımı özelliğini geçici olarak etkinleştirmek (buna gerçekten ihtiyacımız olmasa bile), Xcode'daki geliştirme hesabımın tüm sertifikalar ve ön hazırlık profilleri vb. ile tamamen yenilendiğinden emin olun. Hiçbir şey yardımcı olmadı.

Sonra geçici erişilebilirlik düzeyi değişmiş kSecAttrAccessibleAfterFirstUnlockiçin kSecAttrAccessibleAlwaysThisDeviceOnly, uygulamayı çalıştırdık ve cezayı çalıştı ve Keychain'e yazmayı başardı. Sonra tekrar olarak değiştirdim kSecAttrAccessibleAfterFirstUnlockve sorun "kalıcı olarak" ortadan kalkmış görünüyor.


1

Xcode 8 Beta 3'teki bu hata az önce ısırıldı. Anahtar Zinciri Paylaşımını açmak tek çözüm gibi görünüyor.


1

Ben de aynı sorunu yaşadım. Anahtar Zinciri Paylaşımı'nı kurarak düzeltildi.


1

(bu, OP'nin sorusuna doğrudan bir cevap değildir, ancak başkalarına yardımcı olabilir)

Xcode 7.3.1'den 8.0'a güncellendikten sonra simülatörde sürekli olarak anahtarlık hatası -34018'i almaya başladı.

Daidai'nin cevabından bu ipucunu takiben ,

Sorunun bazı örnekleri, yanlış uygulama imzalamadan kaynaklanıyor. Bu durumu kolayca ayırt edebilirsiniz çünkü sorun% 100 tekrarlanabilir.

Hedefin İmzalama bölümlerinde Temel Hazırlık Profilinin bir şekilde Yok olarak ayarlandığı keşfedildi.

Ancak, Temel Hazırlık Profili alanlarının geçerli değerlere ayarlanması, bu durumda sorunu çözmek için yeterli değildi.

Daha fazla araştırma, Anında Bildirimler yetkisinin de bir hata gösterdiğini gösterdi. "Uygulama Kimliğinize Push Bildirimleri özelliğini ekleyin" yazıyordu. adım tamamlandı, ancak "Yetkiler dosyanıza Anında Bildirimler yetkisini ekleme" adımı tamamlanamadı.

Push Bildirimi sorununu gidermek için "Sorunu Düzelt" e bastıktan sonra, anahtarlık hatası çözüldü.

Bu özel hedef için, "Anahtar Zinciri Paylaşımı" yetkisi daha önce zaten açılmıştı. Anahtar zincirinin kapatılması şimdiye kadar anahtar zinciri hatasının yeniden ortaya çıkmasına neden olmadı, bu nedenle bu durumda gerekli olup olmadığı net değil.


0

İOS 9'da Address Sanitizer'ı kapattım ve cihaz üzerinde çalışmaya başladı.


0

Benim için işe yarayan tek çözüm, önce belirtilen anahtar için sıfır depolamak , ardından yeni değerimi ayrı bir işlemle depolamaktı. Mevcut değerin üzerine yazmaya çalışırsam -34018 hatası nedeniyle başarısız olur. Ama önce nil'i kaydettiğim sürece , güncellenen değer hemen ardından başarıyla saklanacaktır.


0

SecItemDelete API'yi çalıştırırken bugün bu -34018 sorunuyla karşılaştım. Bunu düzeltmek için yaptım: 1. @ k1th çözümünü takip ederek https://stackoverflow.com/a/33085955/889892 2. SecItemDelete'i ana iş parçacığında çalıştırın (Daha önce ana iş parçacığından okunuyordu, bu yüzden bunu sadece silme ile hizalayın) .

Maalesef tekrar geri geliyor :(


0

Projenizin yeteneklerinde Anahtar zinciri paylaşımını açın , sorunu çözmelidir. görüntü açıklamasını buraya girin


0

Benim için ne işe yaradı

  • Anahtar Zinciri Paylaşımı'nı açın.
  • Anahtar zincirini olabildiğince az kullanın ve verileri bellekte, Kullanıcı Tercihlerinde, diskte vb. Önbelleğe alın.
  • Bunlar başarısız olursa, CRUD anahtar zinciri işlemlerini birçok kez yeniden deneyin.
  • Verileri saklamak / silmek / güncellemek için DispatchQueue.sync kullanın.

0

Benim için bu bir uygulama imzalama sorunuydu. Xcode'da sadece doğru imzalama ekibine geçtim ve artık hata oluşmadı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.