İçeriğe geç
Muhammed Ali
Kocabey

Android'de eID çipi okuma: NFC, APDU ve veri grupları

Bankacılık uygulamalarında kimlik doğrulama uzun süre dışarıdan alınan bir kutuydu: bir kütüphane entegre ediyor, sonucu bekliyordunuz. Onboarding akışında bu kutuyu kurum içinde geliştirdiğimiz bir Android SDK'sı ile değiştirdim. Amaç sadece "çalışan" bir çözüm değildi; nasıl çalıştığını satır satır bilebildiğimiz, hata verdiğinde nereye bakacağımızı bildiğimiz bir SDK'ydı. Bu çalışmanın teknik özetini Çalışmalar sayfamın NFC bölümünde de bulabilirsin.

Bu yazıda kurum içi kaynak kodu anlatmıyorum. Anlattığım şey herkese açık: bir eID çipi Android'de NFC ile nasıl okunur, hangi standartlar devrededir ve bir üretim SDK'sı tasarlarken hangi kararlar işe yarar. Kimlik çiplerinin dünyası kapalı görünür ama aslında iyi belgelenmiş bir standarttır. Zorluk teoride değil, cihaz gerçekliğindedir.

eID çipi neyi barındırır

Çipli kimlik kartları ve pasaportlar ICAO Doc 9303 standardına göre çalışır. Çipin içinde LDS (Logical Data Structure) denilen bir dosya sistemi vardır. Bizi ilgilendiren birkaç dosya:

  • DG1: MRZ verisi. Kartın altındaki makine-okunur satırların dijital hâli (ad, belge numarası, doğum tarihi, son geçerlilik).
  • DG2: Yüz görüntüsü. Yüz eşleştirmenin kaynağı.
  • EF.SOD: Document Security Object. Tüm veri gruplarının hash'lerini ve bunları imzalayan sertifikayı taşır. Doğrulamanın kalbi burasıdır.
  • Diğer gruplar (parmak izi, açık anahtarlar) senaryoya göre devreye girer.

Önemli nokta: veriyi okumak ile ona güvenmek iki ayrı iştir. Çipten DG1'i almak, o kimliğin gerçek olduğunu kanıtlamaz. Kanıt, ayrı bir doğrulama adımından gelir.

Akış: okumadan doğrulamaya

Android tarafında dört aşama var. Her aşama bir öncekine bağlı; biri atlanırsa sonraki anlamsızlaşır.

1. NFC keşfi ve reader mode

Çiple iletişim ISO/IEC 14443 (temassız) üzerinden kurulur. Android'de iki yol vardır: eski foreground dispatch ve modern enableReaderMode. Üretim için reader mode tercih edilir çünkü tarama anında sistemin araya girmesini (ör. başka bir NFC uygulamasının uyanması) engeller ve zamanlamayı sizin kontrolünüze verir. IsoDep bağlantısı açılır, transceive ile ham APDU komutları gidip gelir.

2. Erişim kontrolü: BAC ve PACE

Çip kendini rastgele okutmaz. Önce ondan veriyi okuma yetkiniz olduğunu kanıtlamanız gerekir. İki mekanizma vardır:

  • BAC (Basic Access Control): MRZ'den türetilen anahtarlarla (belge numarası, doğum tarihi, son geçerlilik) bir güvenli kanal kurar. Eski ama yaygın.
  • PACE (Password Authenticated Connection Establishment): Modern belgelerin tercihi. Şifre-tabanlı, daha güçlü kriptografiyle aynı işi daha sağlam yapar.

Pratikte SDK ikisini de desteklemeli ve çipin yeteneğine göre doğru olanı seçmelidir. Erişim kontrolü kurulmadan tek bir veri grubu okunamaz.

3. APDU ile veri gruplarını okumak

Güvenli kanal kurulunca iletişim APDU komutlarıyla ilerler: bir dosyayı seç (SELECT), içeriğini oku (READ BINARY). Veri grupları küçük parçalar hâlinde gelir; SDK bunları birleştirip ayrıştırır. Bu ayrıştırma için jMRTD gibi açık kaynak kütüphaneler iyi bir referanstır; ham baytları LDS yapısına çevirmenin nasıl yapıldığını görmek için değerlidir.

4. Passive Authentication: veriye güvenmek

En kritik adım. EF.SOD içindeki imza, ülkenin sertifika zincirine (CSCA ve Document Signer) karşı doğrulanır. Sonra okunan her veri grubunun hash'i, SOD'daki hash ile karşılaştırılır. İkisi birden geçerse: veri gerçekten o belgeden geldi ve okuma sırasında değiştirilmedi.

Passive Authentication verinin bütünlüğünü ve kaynağını kanıtlar. Çipin kopyalanmadığını kanıtlamaz. Bunun için Active Authentication (DG15 açık anahtarıyla challenge-response) veya Chip Authentication devreye girer. Hangisini uygulayacağınız güvenlik gereksinimine bağlıdır; ama Passive Authentication olmadan hiçbiri anlam taşımaz.

Mimari: okuma, doğrulama ve entegrasyonu ayırmak

Bir eID SDK'sını üç sorumluluğa böldüm ve bu sınırları katı tuttum:

  • Okuma: çip iletişimi, erişim kontrolü, APDU, veri gruplarını baytlardan modele çevirmek.
  • Doğrulama: imza ve hash kontrolleri, sertifika zinciri, güven kararları.
  • Entegrasyon: SDK'nın uygulama akışına bağlanması, callback'ler, ilerleme ve hata bildirimi.

Bu ayrım teorik bir zarafet değil, bakım kararıdır. Okuma katmanı cihaz kaprisleriyle uğraşır; doğrulama katmanı kriptografiyle. İkisini karıştırırsanız, bir NFC zaman aşımını çözerken imza mantığını bozma riskiniz olur. Ayrı tutunca her katmanı bağımsız test edebilir, feature ekiplerinin yalnız temiz bir API görmesini sağlayabilirsiniz.

Bir de gözden kaçan bir katman var: teşhis ve telemetri. Kimlik okuma sahada başarısız olur ve neden başarısız olduğunu bilmezseniz kördünüz. Hangi aşamada koptu (keşif mi, erişim mi, doğrulama mı), hangi cihazda, ne kadar sürede. Bunu baştan tasarlamak, sonradan eklemekten çok daha ucuzdur.

Asıl zorluk: cihaz gerçekliği

Standartlar nettir. Zor olan, yüzlerce farklı Android cihazında aynı çipi güvenilir okutmaktır. Sahadan çıkardığım dersler:

  • Anten konumu her cihazda farklı. Kullanıcı çipi telefonun neresine tutacağını bilmez. İyi bir tarama UX'i (nereye tut, ne kadar bekle, kıpırdatma) başarı oranını doğrudan etkiler.
  • Zaman aşımı ve yeniden deneme kaçınılmaz. Bağlantı okuma ortasında kopar. SDK bunu bekleyip zarifçe toparlamalı, kullanıcıya "baştan başla" dememeli.
  • Hata mesajı bir özelliktir. "Okuma başarısız" işe yaramaz. "Çip bulundu ama doğrulama geçmedi" ile "çipe hiç ulaşılamadı" tamamen farklı sorunlardır ve farklı çözümleri vardır.

Kurum içine almak neyi değiştirdi

Dışarıdan alınan çözüm çalışıyordu ama bir kara kutuydu. Kurum içinde geliştirince üç şey değişti: hata verdiğinde tam olarak hangi aşamada koptuğunu görebiliyorduk, akışı ürünün ihtiyacına göre şekillendirebiliyorduk ve yeni cihaz sorunları çıktığında bir sağlayıcının yol haritasını beklemek zorunda değildik. Modüler yapı sayesinde çip iletişimi, doğrulama ve entegrasyon ayrı ayrı olgunlaşabildi.

eID okuma dışarıdan sihir gibi görünür. Değil. İyi tanımlanmış bir standardın, dürüst bir doğrulama adımının ve cihaz gerçekliğine saygının bileşimidir. Zorluğun büyük kısmı kriptografide değil, o kriptografiyi milyonlarca elde güvenilir çalıştırmaktadır.

BİRLİKTE ÇALIŞALIM

İyi bir problemle başlayalım.

Ekibiniz için bir Android mühendisi arıyorsanız veya bir teknik problemi birlikte değerlendirmek istiyorsanız konuşalım.

30 dakika görüşelimTüm iletişim ve podcast bağlantıları