ISO mdoc ayrıntılı: CBOR, COSE, MSO ve bağlantı kurma
Bir ISO/IEC 18013-5 mdoc nasıl kurulur ve doğrulanır; CBOR ve COSE, MSO ve özetler, cihaz imzası, oturum dökümü, QR ve Bluetooth.
Tamga Network 7 dk okuma
mdoc, mobil sürücü belgesi standardı ISO/IEC 18013-5:2021'in tanımladığı mobil belge biçimidir. COSE ile imzalanmış CBOR'dur: kurum, her veri öğesinin özetini ve belge sahibinin cihaz anahtarını listeleyen bir Mobile Security Object (MSO) imzalar; belge sahibi yalnız okuyucunun istediği öğeleri gönderir; bir oturum dökümü (session transcript) üzerine atılan cihaz imzası da yanıtı o tek oturuma bağlar. Tamga kimlik belgesini SD-JWT VC'nin yanında mdoc olarak da verir.
Tamga kimlik belgesini neden iki biçimde veriyor?
26 Eylül 2026'da kabul edilen ADR-0013 üç gerekçe sayar. AB'nin dijital kimlik cüzdanı mimarisi kişi kimlik verisi için mdoc'u zorunlu, SD-JWT VC'yi isteğe bağlı tutar. ISO 18013-5'e göre yüz yüze gösterim mdoc taşır. Karar alındığında Safari'nin Digital Credentials API'si yalnız mdoc kabul ediyordu, Chrome ise iki biçimi de.
Bu karardan çıkan kurallar:
- SD-JWT VC birincil kalır. mdoc aynı belgenin ikinci gösterimidir ve yalnız kimlik belgesi için vardır (
urn:tamga:id:IdentityAttestation:1). Öğrenci belgesi, diploma ve bilet yalnız SD-JWT VC'dir. - Aynı alanlar, aynı geçerlilik, aynı anahtar. mdoc'un
deviceKey'i SD-JWT'nincnf.jwk'sidir. İkinci bir cihaz anahtarı üretilmez. - Ayrı kurum imzaları. SD-JWT için JOSE/ES256, mdoc için
COSE_Sign1/ES256; aynı sertifika zinciri güven listesinde aynı kayda varır. - Tek ihraç, tek durum biti. Belge yanıtındaki her nesne SD-JWT VC'yi ve mdoc'u (base64url
IssuerSigned) birlikte taşır; ikisi de aynı kanıt anahtarına ve aynı durum listesi sırasına bağlıdır. Cüzdan mdoc'u, SD-JWT kopyasıyla karşılaştırmadan saklamaz: aynı kurum sertifikası, aynı alanlar,cnf'ye eşitdeviceKey.

mdoc nasıl kodlanır?
Her şey CBOR'dur (RFC 8949): JSON'la aynı veri modeline bayt dizgileri, etiketler ve tamsayı anahtarlar ekleyen ikili bir kodlama. Burada iki etiket önemli. Etiket 24 "bu bayt dizgisinin içi de kodlanmış CBOR'dur" demektir; imzacının tam o baytları özetlemesini sağlar. SD-JWT'nin disclosure dizgileriyle öğrettiği ders burada da geçerli (SD-JWT VC ayrıntılı). Etiket 0 ise RFC 3339 tarih-saat dizgisini işaretler.
İmzalar COSE ile atılır (RFC 9052), JOSE'nin CBOR karşılığı. COSE_Sign1 dört elemanlı bir dizidir: korumalı başlık, korumasız başlık, yük ve imza. Tamga'nın kurum imzasında korumalı başlıkta {1: -7} (ES256), sertifika zinciri de x5chain'de durur.
ADR-0013 bir birlikte çalışabilirlik notu düşer. Tamga belirlenimci CBOR'u RFC 8949 §4.2.1'e göre (anahtarlar bayt sırasıyla) kodlar; ISO 18013-5:2021 ise RFC 7049'un eski "önce uzunluk" sıralamasına atıf yapar. Özetler, verildiği hâliyle etiket 24 baytları üzerinden alındığı için doğrulama sıralama kuralına bağlı değil; yine de tam uyum için madde açık tutuluyor.
Veri öğesi nedir, özeti nasıl alınır?
Her alan bir IssuerSignedItem'dır: digestID, 16 rastgele bayt, öğe adı ve değerinden oluşan, kodlanıp etiket 24'e sarılmış bir harita. Özeti, bu etiketli baytların SHA-256'sıdır.
24(<< {
"digestID": 1192084209,
"random": h'fe3f2636f3f4a9fa0b315de1f14e8dcd',
"elementIdentifier": "age_over_18",
"elementValue": true
} >>)
Etiketli baytların SHA-256'sı: c2418dcd28b95cc1…Rastgele değer SD-JWT'deki tuzun işini görür: o olmasa age_over_18: true değerinin özeti her belgede aynı olur, tahmin edilebilirdi. digestID öğeyi MSO'daki kaydına bağlar. Tamga digestID'leri 0, 1, 2 diye saymak yerine 31 bit içinde rastgele verir; böylece gösterilen kimlikler, öğe sayısı ya da öğelerin yeri hakkında bir şey söylemez.
Öğeler ad alanlarında (namespace) durur. Tamga'nın kimlik ad alanı tamga.id.1'dir ve öğe adları SD-JWT'deki alan adlarıyla birebir aynıdır: family_name, given_name, birth_date, nationality, personal_administrative_number, document_type, document_number_hash, issuing_country, document_chip_verified, verification_method ve age_over_18. Hepsi seçici paylaşılabilir. Portre öğesi yoktur.
Mobile Security Object'te ne var?
MSO kurumun imzaladığı parçadır. Kodlanır, etiket 24'e sarılır ve kurumun COSE_Sign1'inin (issuerAuth) yükü olur:
{
"version": "1.0",
"digestAlgorithm": "SHA-256",
"docType": "urn:tamga:id:IdentityAttestation:1",
"valueDigests": {
"tamga.id.1": {
692698667: h'9852780268ee6d84…',
1192084209: h'c2418dcd28b95cc1…',
1688544371: h'195cd811675f41a9…',
1708359320: h'd67a4825ac901b31…',
1956174090: h'3dbc0b38db348aef…'
}
},
"deviceKeyInfo": { "deviceKey": { 1: 2, -1: 1, -2: h'…', -3: h'…' } },
"validityInfo": {
"signed": 0("2026-10-08T08:00:00Z"),
"validFrom": 0("2026-10-08T08:00:00Z"),
"validUntil": 0("2028-10-07T08:00:00Z")
},
"status": {
"status_list": { "idx": 48213, "uri": "https://status.tamga.network/3f9a2c" }
}
}Yukarıdaki age_over_18 öğesinin özeti 1192084209 altında saklanan değerdir. deviceKey bir COSE_Key'dir (1: 2 EC2 anahtar, -1: 1 P-256 eğrisi, -2/-3 koordinatlar); SD-JWT'deki cnf.jwk ile aynı açık anahtar. validityInfo.signed, SD-JWT'deki iat'ın yerini tutar: Tamga'nın zamana bağlı güven denetimleri kurumun o anda listede ve yetkili olup olmadığını sorar. status, SD-JWT kopyasıyla aynı Token Status List sırasını gösterir; kimlik belgesini iptal etmek tek bitle iki gösterimi birden iptal eder.
Belge sahibi, mdoc'un verildiği cihaz olduğunu nasıl kanıtlar?
Seçici paylaşım işin kolay kısmı: cüzdan IssuerSigned'ı, nameSpaces'te yalnız onaylanan öğelerle ve dokunulmamış issuerAuth ile gönderir. Gizli öğeler MSO'da özet olarak kalır.
Cihaz bağlama cihaz kimlik doğrulamasından (device authentication) gelir. Cüzdan şunu kurar:
DeviceAuthenticationBytes = 24(<< [
"DeviceAuthentication",
SessionTranscript,
"urn:tamga:id:IdentityAttestation:1",
24(<< {} >>) / DeviceNameSpaces: Tamga profilinde boş /
] >>)ve bunu cihaz anahtarıyla, ayrık yüklü (detached payload) bir COSE_Sign1 olarak imzalar: yük alanı nildir, doğrulayıcı baytları oturumu kendi gördüğü hâliyle yeniden kurar. İmza bir DeviceResponse'un deviceSigned.deviceAuth.deviceSignature alanında gider (version "1.0", documents[0] = {docType, issuerSigned, deviceSigned}). Tamga cihazın imzaladığı veri öğesi kullanmaz; DeviceNameSpaces hep boş haritadır.
Yani her şey SessionTranscript'e bağlı: içine ne girerse yanıt ona bağlanır.
Oturum dökümüne ne girer?
| Kanal | SessionTranscript | Yanıtı neye bağlar |
|---|---|---|
| Yüz yüze (ISO 18013-5, QR + BLE) | [DeviceEngagementBytes, EReaderKeyBytes, null] | iki geçici oturum anahtarına |
| QR ya da bağlantıyla OpenID4VP | [null, null, ["OpenID4VPHandover", sha256(cbor([client_id, nonce, jwkThumbprint, response_uri]))]] | doğrulayıcı kimliği, nonce, şifreleme anahtarı, yanıt adresi |
| DC API ile OpenID4VP | [null, null, ["OpenID4VPDCAPIHandover", sha256(cbor([origin, nonce, jwkThumbprint]))]] | tarayıcı kaynağı (origin), nonce, şifreleme anahtarı |
İki çevrim içi biçim OpenID4VP 1.0 Final'in Ek B.2.6'sından gelir. client_id tam x509_hash:… değeridir; jwkThumbprint, yanıtın şifrelendiği anahtarın RFC 7638 parmak izidir. Bir istekten yakalanan DeviceResponse başka bir istekte geçmez: doğrulayıcı farklı bir döküm kurar ve cihaz imzası tutmaz. Tamga doğrulayıcısı bunu A6 adımında reddeder.
QR ve Bluetooth ile yüz yüze bağlantı nasıl kurulur?

- Cihaz tanıtımı (device engagement). Cüzdan geçici bir P-256 anahtarı (
EDeviceKey) ve rastgele bir BLE hizmet UUID'si üretir;mdoc:ve ardındanDeviceEngagementyapısının base64url hâlini taşıyan bir QR kod gösterir. İçinde kişisel veri yoktur. - Oturum kurulumu. Okuyucu kodu tarar, kendi geçici anahtarını (
EReaderKey) üretir ve oturum anahtarlarını türetir. İki taraf ECDH, ardından tuz olarakSHA-256(SessionTranscriptBytes)ve bilgi dizgileriSKReaderileSKDevicekullanan HKDF-SHA-256 çalıştırır. OkuyucuSessionEstablishment {eReaderKey, data}gönderir;data, SKReader ile şifrelenmişDeviceRequest'tir. - İstek ve onay. Cüzdan isteği çözer, istenen öğeleri gösterir; kişi telefon kilidiyle onaylar ya da reddeder.
- Yanıt. Cüzdan
DeviceResponse'u SKDevice ile şifrelenmiş birSessionDatailetisinde gönderir ve oturumu20durum koduyla kapatır.
{
0: "1.0",
1: [1, 24(<< COSE_Key olarak EDeviceKey >>)], / şifre takımı 1 /
2: [[2, 1, { / BLE, sürüm 1 /
0: true, / peripheral server modu /
1: false, / central client modu /
10: h'…16 baytlık hizmet UUID'si…'
}]]
}Oturum iletileri AES-256-GCM kullanır; 12 baytlık IV, 8 baytlık bir kimlikten (okuyucu için hepsi sıfır, cihaz için …01) ve 1'den başlayan 4 baytlık ileti sayacından oluşur. BLE'de telefon GATT sunucusudur; her ileti parçalara bölünür, devamı varsa parçanın ilk baytı 0x01, son parçada 0x00'dır.
Bugünkü durum: protokol çekirdeği (tanıtım, oturum şifrelemesi, BLE parçalama) @tamga-network/mdoc içinde yazıldı ve test edildi; BLE radyosunu cüzdan uygulaması sağlar. Cihaz testleri sürüyor. NFC kullanılmaz; bağlantı her zaman QR koddan başlar. Okuyucu kimlik doğrulaması henüz yok; bu yüzden cüzdan kişiye okuyucunun doğrulanmadığını söyler. OpenID4VP üzerinden çevrim içi mdoc gösterimi, SD-JWT VC ile aynı istek akışını kullanır.
Doğrulayıcı bir mdoc'u nasıl denetler?
DeviceResponse'u ayrıştırın,docType'ın istenenle aynı olduğunu doğrulayın.issuerAuth'u doğrulayın: yalnız ES256,x5chainimzalı güven listesindeki bir kuruma varmalı; SD-JWT belgeleriyle aynı çapa.- Gösterilen her öğe için etiket 24 baytlarının özetini alın,
valueDigests[ad alanı][digestID]ile karşılaştırın. validityInfo'yu şimdiki zamana göre denetleyin.- Bu isteğin ya da oturumun SessionTranscript'ini kendiniz kurun,
DeviceAuthenticationBytes'ı yeniden oluşturun,deviceSignature'ıdeviceKeyile doğrulayın. - Durum bitini okuyun; sonra SD-JWT VC'deki güven, iptal ve politika katmanlarını aynen çalıştırın.
Sonuç yine üç değerlidir: kabul, ret ya da altyapıya ulaşılamadığında "şu an doğrulanamıyor". Sonuç nesnesinde ham CBOR ya da gösterilmemiş öğe bulunmaz.
Bir OpenID4VP isteğinde mdoc DCQL ile seçilir (OpenID4VP ve DCQL ayrıntılı): format: "mso_mdoc", meta.doctype_value ve [ad alanı, öğe] biçiminde alan yolları:
{
"credentials": [{
"id": "identity",
"format": "mso_mdoc",
"meta": { "doctype_value": "urn:tamga:id:IdentityAttestation:1" },
"claims": [{ "path": ["tamga.id.1", "age_over_18"], "values": [true] }]
}]
}mdoc kimlik belgesi, Tamga'nın sıfır bilgili yaş ispatının da girdisidir; ispat sıradan ES256 imzalı mdoc'lar üzerinde çalışır (ADR-0032). Bu denetim Tamga Verify'da canlıda; işleyişi Tamga'da sıfır bilgi yazısında.
Sık sorulan sorular
mdoc ile mDL aynı şey mi?
Hayır. mDL (mobil sürücü belgesi), mdoc biçimini kullanan belge türlerinden biridir. Tamga kimlik belgesi kendi docType'ı ve ad alanı olan bir mdoc'tur; Tamga'nın "sürücü belgesi bilgisi" belgesi ise yalnız SD-JWT VC'dir, mDL değildir.
digestID'ler neden sıralı değil de rastgele?
Sıralı kimliklerle doğrulayıcı belgede kaç öğe olduğunu ve hangi sıraların saklandığını çıkarabilirdi. 31 bitlik rastgele kimlikler sıra taşımaz.
Tamga mdoc'unu başka bir ISO 18013-5 kütüphanesiyle doğrulayabilir miyim?
Yapılar standart ISO 18013-5 ve OpenID4VP 1.0'dır. İki noktaya bakın: kütüphane etiket 24 baytlarının özetini yeniden kodlamadan, geldiği gibi almalı ve çevrim içi gösterim için OpenID4VP el sıkışmasını desteklemeli.
Kaynaklar
- ISO/IEC 18013-5:2021, Mobile driving licence (mDL) application, ISO
- OpenID for Verifiable Presentations 1.0, Final, 9 Temmuz 2025 (Ek B: ISO mdoc)
- OpenID4VC High Assurance Interoperability Profile 1.0, Final, 24 Aralık 2025
- RFC 8949: Concise Binary Object Representation (CBOR), IETF
- RFC 9052: CBOR Object Signing and Encryption (COSE), IETF
- ADR-0013: Kimlik belgesi için mdoc, Tamga Network belgeleri
@tamga-network/mdoc, Tamga Network belgeleri- OpenID4VP profili (SPEC-PROTO-0002), Tamga Network belgeleri
- Gösterim, Tamga Network belgeleri
İlgili
- Yazı · StandartlarSD-JWT VC ayrıntılı: imza, disclosure ve KB-JWTBir SD-JWT VC bayt bayt nasıl kurulur ve denetlenir; tuzlu özetler, _sd, cnf, KB-JWT ve sd_hash, vct#integrity ve status, Tamga profiliyle.
- Yazı · StandartlarOpenID4VP ve DCQL ayrıntılı: istekten sonucaDoğrulayıcı OpenID4VP 1.0 ile belgeyi nasıl ister ve denetler: x509_hash'li imzalı istek, DCQL, şifreli direct_post.jwt ve A–E doğrulama hattı.
- Yazı · GizlilikTamga'da sıfır bilgi: Longfellow, devreler, güven listesiTamga Network "18 yaş üstü"nü Longfellow sıfır bilgi ispatıyla nasıl doğrular, devreler neden imzalı güven listesinde, bugün ne çalışıyor?
- Yazı · StandartlarOpenID4VCI ayrıntılı: teklif, DPoP, kanıt, 10'lu paketTamga'da OpenID4VCI 1.0 ile belge verme; teklif ve tx_code, PAR ve PKCE, DPoP, nonce ucu, anahtar kanıtları, cüzdan doğrulaması, 10 kopyalık paket.
- Yazı · StandartlarHAIP ve Token Status List: izlenmeden yüksek güvenceHAIP 1.0 neyi sabitler, Tamga onu nasıl uygular; Token Status List belgeyi, kuruma nerede kullanıldığını söylemeden nasıl iptal eder.
Ağın üzerine kurun
Kavramları sıfırdan öğrenin ya da bir kurumun, doğrulayıcının, cüzdanın ya da devletin ağa nasıl katıldığına bakın.