Kimliğinizi Kanıtlayın, Gizliliğinizi Koruyun · Prove Your Identity, Protect Your Privacy
VerifyBlind kimlik doğrulama (PoP Mode — Proof of Personhood) için iOS SDK'sı.
Android sdk-android ile bire bir protokol ve kripto paritesinde Swift port'u.
Bağımlılık yok — yalnızca Apple framework'leri (
Foundation,CryptoKit,Security,UIKit). Dağıtım: Swift Package Manager.
Xcode → File ▸ Add Package Dependencies… → bu repo URL'si.
Ya da Package.swift:
dependencies: [
.package(url: "https://github.com/<org>/sdk-ios.git", from: "2.0.0")
]Minimum dağıtım hedefi: iOS 13.
import VerifyBlind
let sdk = VerifyBlindSDK(
config: VerifyBlindConfig(
partnerBackendUrl: "https://partner.example.com/api/auth",
generateEndpoint: "generate"
// verifyblindAppLinkBase / verifyblindApiUrl üretim varsayılanlarını kullanır
)
)
// 1) Akışı başlat (Universal Link otomatik açılır)
let result = try await sdk.startAuthentication(
validations: ["age_over": 18]
)
// 2) Kullanıcı VerifyBlind app'inde onayladıktan sonra sonucu poll et
// (UI tarafında periyodik çağır; nil = henüz beklemede)
if let data = try await sdk.checkVerificationResult(nonce: result.nonce) {
print("Doğrulandı:", data)
}İptal durumunda checkVerificationResult bir VerifyBlindError fırlatır
(code == .userCancelled, cancelReason ile sebep kodu).
Kendi uygulamanızdan VerifyBlind'ı açtığınızda bir returnUrl geçin; VerifyBlind işlem bitince
(başarı veya iptal) kullanıcıyı uygulamanıza geri getirir:
let result = try await sdk.startAuthentication(
validations: ["user_id": true],
returnUrl: "verifyblinddemo://callback" // uygulamanızın özel şeması
)VerifyBlind bitişte verifyblinddemo://callback?nonce={nonce}&status=success (ya da status=cancelled)
açar → uygulamanız öne gelir; ardından checkVerificationResult ile sonucu poll edin.
İki zorunlu adım:
- Şemayı Partner Portal → Ayarlar → Uygulama Geri-Dönüş Şeması'na kaydedin (ör.
verifyblinddemo). VerifyBlind yalnızca şeması kayıtlı değerle eşleşen return URL'i açar (fail-closed → açık-yönlendirme önlemi). Boş bırakılırsa geri dönüş kapalıdır. - Şemayı uygulamanızın
Info.plist'ineCFBundleURLTypesaltında ekleyin veonOpenURLile karşılayın.
QR (cihazlar-arası) akışlarda
returnUrlyok sayılır — geri dönülecek çağıran uygulama yoktur.
- Cihazda ephemeral RSA-OAEP-2048 keypair üretilir (yazılım anahtarı).
- Public key SPKI (Base64) olarak partner backend proxy'ye
{ public_key, validations }gönderilir →{ nonce }. pk_hash = SHA256(publicKeyBase64)(lowercase hex).- Universal Link açılır:
https://app.verifyblind.com/request?nonce=...&pk_hash=... - Relay
GET /api/pop/result/{nonce}poll edilir; şifreli yanıt lokalde çözülür:enc_key: RSA-OAEP-SHA256/MGF1-SHA256 ile sarılı (base64) AES anahtarıblob:IV(12) + Ciphertext + Tag(16)AES-GCM-128
validations içinde user_id: true isterseniz, çözülen yanıtta (checkVerificationResult) üç kod birden döner — üçünü de saklayın:
| Alan | Anlam |
|---|---|
user_id |
Ulusal-no bazlı kimlik (TCKN yoksa boş). Partner'a özel HMAC. |
nsbd_id |
Biyografik kişi kodu; ad ve doğum tarihi değişmediği sürece kişinin kartları arasında sabit. Olasılıksal ipucu — tek başına sert dedup kararı vermeyin. Kayabileceği durumlar: isim değişikliği (ör. evlilik) ve uzun isimlerin kimlik kartı ↔ pasaport arasında farklı kırpılması (MRZ kırpması ICAO 9303'te ihraççı takdirindedir). Sert karar için doc_id kullanın. |
doc_id |
Belge kodu; aynı doc_id = aynı fiziksel belge = aynı kişi (sert sinyal). |
Üçü de partner'a özeldir (başka partner ile eşleştirilemez) ve TCKN'ye döndürülemez. Üçünü birlikte saklamak, bir ülke ulusal kimlik numarasını sonradan kaldırsa/eklese veya kullanıcı kartını yenilese bile aynı kişiyi tanımanızı sağlar.
- SPKI vs PKCS#1: iOS
SecKeyCopyExternalRepresentationPKCS#1 döndürür; SDK bunu ASN.1 SPKI header'ı ile sarar (Crypto/SPKI.swift). Aksi haldepk_hashAndroid/Web ile tutmaz ve enclave çözemez. - Secure Enclave kullanılmaz: Secure Enclave RSA desteklemez (yalnızca EC P-256); bu yüzden ephemeral RSA anahtarı yazılımda üretilir — Android tarafıyla aynı.
- Universal Link:
app.verifyblind.comüzerinde geçerli birapple-app-site-associationdosyası ve VerifyBlind iOS uygulamasında Associated Domains yetkisi gerekir; aksi haldestartAuthenticationSafari'ye düşer.- Sertifika pinning:certificatePins(OkHttp formatısha256/BASE64) yalnızca partner backend'e uygulanır; relay pinlenmez (Android paritesi). RSA ve EC P-256 sunucu anahtarları desteklenir.
swift testTests/VerifyBlindTests/CryptoParityTests.swift SPKI sarmalını ve uçtan uca hybrid decrypt
yolunu doğrular.
The iOS SDK for VerifyBlind identity verification (PoP Mode — Proof of Personhood). A Swift port at
exact protocol and crypto parity with the Android sdk-android.
No dependencies — only Apple frameworks (
Foundation,CryptoKit,Security,UIKit). Distribution: Swift Package Manager.
Xcode → File ▸ Add Package Dependencies… → this repo's URL.
Or in Package.swift:
dependencies: [
.package(url: "https://github.com/<org>/sdk-ios.git", from: "2.0.0")
]Minimum deployment target: iOS 13.
import VerifyBlind
let sdk = VerifyBlindSDK(
config: VerifyBlindConfig(
partnerBackendUrl: "https://partner.example.com/api/auth",
generateEndpoint: "generate"
// verifyblindAppLinkBase / verifyblindApiUrl use the production defaults
)
)
// 1) Start the flow (the Universal Link opens automatically)
let result = try await sdk.startAuthentication(
validations: ["age_over": 18]
)
// 2) After the user confirms in the VerifyBlind app, poll for the result
// (call periodically from the UI; nil = still pending)
if let data = try await sdk.checkVerificationResult(nonce: result.nonce) {
print("Verified:", data)
}On cancellation, checkVerificationResult throws a VerifyBlindError
(code == .userCancelled, with the reason in cancelReason).
When you launch VerifyBlind from your own app, pass a returnUrl so VerifyBlind brings the user back
to your app when the flow ends (success or cancel):
let result = try await sdk.startAuthentication(
validations: ["user_id": true],
returnUrl: "verifyblinddemo://callback" // your app's custom scheme
)When done, VerifyBlind opens verifyblinddemo://callback?nonce={nonce}&status=success (or
status=cancelled), foregrounding your app; then resume polling with checkVerificationResult.
Two required steps:
- Register the scheme in Partner Portal → Settings → App Return Scheme (e.g.
verifyblinddemo). VerifyBlind only opens a return URL whose scheme matches your registered value (fail-closed — prevents open-redirect). Leaving it empty disables app return. - Declare the scheme under
CFBundleURLTypesin your app'sInfo.plistand handle it inonOpenURL.
QR (cross-device) flows ignore
returnUrl— there is no caller app to return to.
- An ephemeral RSA-OAEP-2048 keypair is generated on the device (software key).
- The public key is sent as SPKI (Base64) to the partner backend proxy as
{ public_key, validations }→{ nonce }. pk_hash = SHA256(publicKeyBase64)(lowercase hex).- The Universal Link opens:
https://app.verifyblind.com/request?nonce=...&pk_hash=... - The relay's
GET /api/pop/result/{nonce}is polled; the encrypted response is decrypted locally:enc_key: an AES key wrapped with RSA-OAEP-SHA256/MGF1-SHA256 (base64)blob:IV(12) + Ciphertext + Tag(16)AES-GCM-128
If you request user_id: true inside validations, the decrypted response (checkVerificationResult)
returns three codes at once — store all three:
| Field | Meaning |
|---|---|
user_id |
National-number-based identity (empty if there is no national number). Partner-specific HMAC. |
nsbd_id |
Biographic person code; stable across a person's cards as long as name and date of birth do not change. Probabilistic hint — don't make a hard dedup decision on it alone. It can drift on a name change (e.g. marriage) or when a long name is truncated differently on an ID card vs a passport (MRZ truncation is at the issuer's discretion under ICAO 9303). Use doc_id for hard decisions. |
doc_id |
Document code; the same doc_id = the same physical document = the same person (hard signal). |
All three are partner-specific (cannot be correlated with another partner) and cannot be reversed to a national ID number. Storing all three lets you recognize the same person even if a country later removes or adds a national ID number, or the user renews their card.
- SPKI vs PKCS#1: iOS
SecKeyCopyExternalRepresentationreturns PKCS#1; the SDK wraps it with an ASN.1 SPKI header (Crypto/SPKI.swift). Otherwisepk_hashwon't match Android/Web and the enclave cannot decrypt. - Secure Enclave is not used: the Secure Enclave doesn't support RSA (only EC P-256), so the ephemeral RSA key is generated in software — same as on Android.
- Universal Link: requires a valid
apple-app-site-associationfile onapp.verifyblind.comand the Associated Domains entitlement in the VerifyBlind iOS app; otherwisestartAuthenticationfalls back to Safari. - Certificate pinning:
certificatePins(OkHttp formatsha256/BASE64) applies only to the partner backend; the relay is not pinned (Android parity). RSA and EC P-256 server keys are supported.
swift testTests/VerifyBlindTests/CryptoParityTests.swift verifies the SPKI wrapping and the end-to-end hybrid
decrypt path.