Skip to main content

3 posts tagged with "nfc"

View All Tags

Identity Verification in Romanian iGaming After CEI: What ONJN Operators Need to Know in 2026

· 6 min read
Cătălin Toma
Founder, EidKit

Romania's online gambling market is one of the most regulated in Europe. ONJN has issued over 50 Class I licenses, the channelization rate exceeds 90%, and the fines and license revocations of the past year show the regulator is watching closely.

Since July 2025, every Romanian citizen requesting an identity document receives an Electronic Identity Card (CEI) with an NFC chip. This transition changes one concrete thing in the KYC flow of any ONJN-licensed operator — and not all operators are prepared.


What Has Actually Changed

The old identity card printed the home address on the back. Operators could photograph the document, extract the address via OCR, and use it for the address verification required in the CDD process.

The new CEI no longer prints the address on the front or back. The address exists exclusively on the electronic chip, in the EDATA applet, protected by an encrypted channel and the holder's PIN.

The practical consequence: the classic "photograph the document, extract address via OCR" flow no longer works for any user with a CEI.

And the number of these users grows every day. The government has issued over 1.8 million CEIs so far, with 1.1 million old cards expiring in 2025 alone. By end of 2026, the majority of active users on Romanian iGaming platforms will hold a CEI as their only valid identity document.


The Bonus Abuse Problem — a Vector the CEI Closes

One of the most costly problems for operators is multi-accounting: the same user creating multiple accounts to exploit welcome bonuses, reload offers, and promotions.

Current solutions — email verification, phone number, IP — are easy to circumvent. Video KYC adds friction, but with deepfakes commercially available, it no longer offers the guarantees it did three years ago.

The CEI changes the equation at a fundamental level: one physical card, issued by MAI, cryptographically tied to a single identity. There are no two people with the same CEI. There is no virtual or software-generated CEI. The chip contains a hardware-stored private key that cannot be exported or cloned.

An operator that ties the account to the CEI chip — not to a CNP, not to an email, but to the physical chip — essentially eliminates multi-accounting for all users with CEI.


Video KYC: What It Can and Cannot Do

Current video KYC solutions (Sumsub, Veriff, Onfido, Didit, Qoobiss) work by photographing the document and performing biometric face verification. They are solid solutions for what they do.

But they have structural limits that cannot be resolved through product improvements:

eIDAS assurance level. Video KYC with OCR on a document photo reaches at most Substantial level. The CEI chip with active authentication (PACE + PA + AA) represents the High level — cryptographic proof that the document is authentic, that the chip is not cloned, and that the user physically holds the card.

Home address. Video KYC cannot extract the address from a CEI because it does not read the chip. No video KYC provider can access the EDATA applet. The address must be obtained through other means — a separate attestation, direct DGEP access (available to banks, not everyone), or asking the user to declare it manually.

Deepfake resistance. Authentication with the CEI chip involves no biometrics or video. The user enters the CAN printed on the card and the PIN set at MAI, then touches the card to the phone. There is no attack surface for deepfakes or image synthesis.


What ONJN Requires and Where CEI Sits

Law 129/2019 and ONJN regulations impose clear identification and identity verification obligations on operators for players, including home address verification.

The self-exclusion platform — which ONJN and ICI Bucharest are modernizing through a protocol signed in February 2026 — will use identity card verification, not video KYC. The regulator's signal is clear: the direction is toward document-based identification, not selfie and OCR.

An operator integrating CEI authentication is not just making a technical upgrade. It's getting ahead of future ONJN requirements.


What Integration Looks Like in Practice

EidKit exposes a standard OIDC SSO — the same protocol as "Sign in with Google," implementable in a few hours by any development team.

The user flow:

  1. A QR code appears on the operator's site
  2. The user opens the EidKit app on their phone and scans the QR code
  3. Enters the CAN (6 digits printed on the card) and PIN (4 digits, set at MAI)
  4. Touches the card to the phone — complete authentication in under 15 seconds

The server receives:

  • Name and surname cryptographically verified by MAI
  • CNP cryptographically verified by MAI
  • Home address extracted from the chip (not self-declared)
  • Proof that the chip is authentic and not cloned (Active Authentication)
  • Proof that the user physically holds the card and knows the PIN

Every subsequent authentication — not just onboarding — produces the same guarantees. No session hijacking, no account takeover via password reset, no credential theft.


Cost Per Verification

Video KYC solutions cost between $0.33 (Didit) and $1.85 (Sumsub Compliance) per successful verification. An operator with 10,000 new registrations per month pays between $3,300 and $18,500 monthly just for initial KYC.

EidKit SSO costs €0.25 per successful authentication — with a higher assurance level and verified address included. For recurring authentications — repeated logins of the same user — the cost is identical, making the model favorable for operators with frequently active users.


The CEI Adoption Timeline

Some concrete milestones:

  • July 2025: CEI becomes the only type of identity document issued in Romania
  • August 2025: CEI can be requested at any SPCLEP in the country, regardless of domicile
  • End of 2025: 1.1 million old cards expire
  • December 2026: eIDAS 2.0 deadline for the European digital identity wallet
  • 2027: regulated private operators will be required to accept the EUDI wallet

Every month that passes increases the percentage of iGaming platform users who hold a CEI as their only valid identity document.


If you're an ONJN operator or building for the Romanian iGaming market and want to discuss what a concrete integration looks like, write to us. First integrations benefit from our pilot program.

What It Actually Takes to Integrate the Romanian ID Card Over NFC

· 8 min read
Cătălin Toma
Founder, EidKit

This is the third article in our series on Romania's electronic identity card. The previous articles cover the address problem that's quietly breaking KYC flows and what your electronic ID card can and can't sign.

If you have integrated an electronic passport or another chip-based identity document before, you will enter this project with a reasonable set of assumptions. Most of them are partially wrong for the Romanian CEI.

It is not that the ICAO standards do not apply — they do, as a starting point. The problem is that the CEI is a national identity card with country-specific extensions that appear nowhere in complete public documentation. What follows is a map of the terrain based on complete implementations for both Android and iOS, tested against real CEI cards.


What You Already Know — and What Still Applies

Any ICAO-based electronic identity card uses PACE (Password Authenticated Connection Establishment) to establish a secure channel before any data can be read. The CEI does the same, using the CAN code — 6 digits printed on the front of the card — as the password.

The result of PACE is a Secure Messaging (SM) channel that wraps all subsequent APDU commands. Any command sent raw after the channel is established is rejected by the card — standard behaviour, not specific to the CEI.

Passive authentication works on familiar principles on both platforms: the chip contains a Security Object Document that chains SHA-256 hashes of the data groups up to MAI's CSCA root certificate. The verification looks different depending on the platform, but the principle is the same:

On Android, jMRTD handles SOD parsing. Chain verification is done manually against the CSCA certificate bundled with the SDK:

val sod = SODFile(sodRaw.inputStream())
val dsc = sod.docSigningCertificate
val csca = assets.open("csca_romania.der").use {
CertificateFactory.getInstance("X.509").generateCertificate(it) as X509Certificate
}
dsc.verify(csca.publicKey) // throws if invalid

Passive authentication must always run before trusting any data read from the card. An engineer with ICAO document experience will be comfortable up to this point. This is roughly where the familiar terrain ends.


Where the Assumptions Start to Break

The Chip Has Four Applets, Not One

Standard ICAO travel documents have a relatively predictable applet structure. The CEI does not follow the same pattern. The chip contains four applets with distinct roles:

AppletRole
AID1 / National AppPACE entry point, hosts security parameters
ICAO LDSPhoto, digitised handwritten signature, SOD for passive authentication
EDATAPersonal data: name, CNP, home address
GenPKIKeys and certificates for active authentication and signing

The ESIGN applet exists on the chip and appears in some reference documents. It is not used. Signing goes through GenPKI, via a command different from what you would assume from reading the standards.

Each applet follows its own selection and authentication flow. You do not select an applet and read what you need.

Two Phases, Different Requirements

Reading data from the CEI splits naturally into two phases:

Phase 1 — CAN only: accesses data available without a PIN — the holder's photo, the digitised handwritten signature, and the data needed for passive authentication. This phase uses the standard ICAO applet.

Phase 2 — CAN + 4-digit PIN: accesses the full personal data from the EDATA applet, including the home address — which is no longer printed on the physical card.

The Order of Operations Before PACE Is Not Documented — and Matters

What you must do before PACE depends on what you want to do after PACE, and the rules are asymmetric depending on the usage scenario. Phase 1 requires different preparation from Phase 2 and GenPKI. If the preparation is wrong for the given scenario, failures appear at unexpected points with error codes that do not indicate the real problem.

The situation differs between the two platforms for architectural reasons:

The Android NFC stack starts in MF context — no AID is pre-selected. This is the correct state for Phase 1: PACE works directly in MF context, after which SM SELECT ICAO gives access to DG2/DG7/SOD.

// Phase 1: no pre-selection needed — Android stack starts in MF context
isoDep.timeout = 20_000 // default timeout is insufficient for CEI

val paceResult = ps.doPACE(canKey, paceOid, paceParams, null)
val wrapper = paceResult.wrapper
// all commands from here go through the wrapper

// Phase 2: SELECT AID1 before PACE — chip requires AID1 context for EDATA/GenPKI

The asymmetric pre-PACE preparation behaviour is not documented anywhere — it was discovered by elimination on both platforms.


Data Formats: Where the Romanian Implementation Diverges

DG1 Is Not MRZ

This is where code that works perfectly for passports breaks completely, on both platforms. The identity data returned by the EDATA applet is not in the MRZ format that standard ICAO libraries parse — it is in a Romanian implementation-specific ASN.1 format, with correctly encoded diacritics and differently structured fields:

SEQUENCE (0x30)
[0] (0x80) lastName UTF-8 e.g. "TOMA"
[1] (0x81) firstName UTF-8 e.g. "CĂTĂLIN" (diacritics preserved)
[2] (0x82) sex UTF-8 "M" or "F"
[3] (0x83) dateOfBirth UTF-8 DDMMYYYY
[4] (0x84) cnp UTF-8 13 digits
[5] (0x85) nationality UTF-8 "ROU"

jMRTD's DG1File cannot parse this format. A custom parser is required:

// jMRTD won't help here — Romanian-specific ASN.1 format
val tags = parseContextTags(dg1Bytes) // custom parser
val lastName = tags[0x80]?.toString(Charsets.UTF_8)
val firstName = tags[0x81]?.toString(Charsets.UTF_8) // diacritics are correct
val cnp = tags[0x84]?.toString(Charsets.UTF_8)

The format is not publicly documented — it was determined by direct inspection of bytes returned by the card.

The Two Cryptographic Keys in GenPKI

GenPKI contains two distinct keys, on different elliptic curves, with different internal signing behaviours:

OperationPINInternal behaviour
Active authentication4 digitsKey on secp384r1, reference 0x81
Document signing6 digitsKey on brainpoolP384r1, reference 0x8E

Confusing them produces an incorrect signature with no error message indicating the cause. The behaviour is identical on Android and iOS — this is a chip constraint, not a platform one.


Things That Break Before You Reach Business Logic

The cryptographic provider must be explicitly registered in the correct order before any chip operation. Wrong order produces silent failures:

Security.removeProvider("BC")
Security.insertProviderAt(BouncyCastleProvider(), 1)

Android 13+ changed the API for NFC tag interception. If you support older Android versions, you handle two variants with slightly different behaviour.

PIN counter query does not work in SM mode, on either platform. There is no way to query remaining attempts before sending the actual PIN. You handle SW=63CX in the VERIFY response (X = attempts remaining) and SW=6983 for a blocked card — a detail that directly affects application UX.


We write about the Romanian CEI — its capabilities, its integration challenges, and the regulatory context around it. If a topic here is relevant to something you're building, feel free to reach out.

Your New Romanian ID Card Has Your Address. Your Bank Doesn't Know How to Read It.

· 7 min read
Cătălin Toma
Founder, EidKit

This is the first article in our series on Romania's electronic identity card. The second covers what the 2024 electronic signature law means for the CEI.

Something quietly changed when Romania rolled out its new electronic identity card — the Carte Electronică de Identitate, or CEI. The home address disappeared from the physical card. No more printed street, number, city, county on the back. That information is now stored exclusively on the chip inside the card, readable only via NFC or a card reader.

In theory, this is an upgrade. The address can be updated electronically when you move, without needing to reissue the card. In practice, it has created a slow-motion crisis that is now visibly breaking down.


The Problem in One Sentence

Millions of Romanians now carry an ID card that legally contains their home address — but cannot hand it to a bank teller, notary, or civil servant in a way they can read it.

As of this week, the Romanian government has logged over 300 formal complaints in the "Passport and Identity Card" category alone on its fara-hartie.gov.ro platform. The most reported issue by far: the missing printed address. Banks, notaries, schools, ANAF offices, and local authorities are all asking for a separate adeverință de domiciliu — a paper certificate proving the address that is already, technically, on the document they are holding.

One person described arriving at a notary for a property transaction and being turned away because the CEI "was not sufficient to prove domicile." Another went to open a bank account, same story. A 34-year-old recounted: "I got the electronic ID because I understood it was more modern and secure. Nobody told me I'd need a separate certificate every time I have to prove my address."

This is what happens when infrastructure moves before institutions are ready to use it.


What the Government's Fix Looks Like

To its credit, the government has moved quickly. On March 25, 2026 — two days ago — civil registry offices were instructed to look up applicants' addresses themselves in the national database, rather than conditioning service on a physical document.

Banks have received direct database access to the population registry and, according to the government announcement, no longer need to ask for the certificate.

For notaries, a similar mechanism is being tested.

And for everyone else — citizens who need to show address proof somewhere that doesn't have database access yet — the Ministry of Internal Affairs has launched a mobile app called RoCEIReader. You tap your card, enter the 6-digit CAN code and your 4-digit PIN, and the app reads the address off the chip and lets you save it as a PDF.

It is available for Android. The iOS version is "coming soon."

The shape of this solution

The government's answer to "institutions can't read the chip" is a consumer app for citizens to read the chip themselves and produce a PDF. That PDF is then presented to the institution that couldn't read the chip.

The problem has been partially converted from a technical integration challenge into paperwork — digital paperwork, but paperwork. It works, and it is better than nothing. But it illustrates the gap between what the CEI is — a cryptographically secure NFC smart card with a verified, government-signed dataset — and what most systems are currently prepared to do with it.


The Options for Reading the Address

For anyone building software that needs a verified home address in Romania, the transition has real consequences. The old workflow — ask the user for a scan of their ID card, OCR the address from the back — no longer works. The address is not on the back.

The alternatives, roughly in order of robustness:

Government database lookup Banks have been given direct access to the DGEP population registry. Clean, no NFC required, no user interaction beyond a CNP. Access requires a formal agreement with the government authority and is not available to arbitrary private companies on request.

NFC chip read The card is read directly using the CAN code printed on its front face. This gives you the address as the government has it — cryptographically signed, verifiable against the Ministry's certificate chain, no dependency on a third-party database. The address lives in the card's EDATA applet, behind a PACE secure channel and a 4-digit PIN. Reading it correctly requires handling some Romanian-specific data formats that standard ICAO libraries do not cover out of the box.

User-produced certificate The workaround the government is now facilitating via RoCEIReader. Legally valid. Introduces a manual step for the user, a 6-month validity window on the certificate, and friction at exactly the point where onboarding flows tend to lose people.


The Larger Pattern

The address issue is the most visible symptom, but the CEI is capable of considerably more than any institution has caught up to yet.

The chip contains biometric data, a face photo, and two cryptographic keys backed by MAI-issued certificates. One key is for advanced electronic signatures — under Law 214/2024, a document signed with this certificate carries the same legal weight as a handwritten signature. The other is for active authentication: a challenge-response proof that the chip is genuine and not cloned.

And yet ANAF's own tax filing platform rejects the CEI's signature. It only accepts signatures from separately purchased qualified certificates sold by commercial providers. The card grants you a legally valid signature. The government's own portal won't accept it.

The card is ahead of the ecosystem. The ecosystem is catching up, institution by institution. Banks have caught up on address verification. Notaries are close. ANAF has not caught up on signatures. The same pattern will repeat for every institution that needs to interact with these cards over the next two to three years.


What Reading the Chip Actually Involves

For the technically curious: the CEI chip runs the PACE protocol (Password Authenticated Connection Establishment) using AES-256 to establish a secure channel before anything is readable. After the channel is open, reading personal data requires selecting the correct applet, completing PIN verification, and parsing the response in a Romanian-specific ASN.1 format that is not the same as the ICAO MRZ format most libraries expect.

Passive authentication — verifying that the data on the chip is signed by MAI and hasn't been tampered with — should always run before trusting anything read from the card. It chains from the data groups through the document signing certificate up to the Ministry's CSCA root.

None of this is exotic. But it is specific, and the specifics matter. The card is not something you can integrate with by reading the standard ICAO documentation and adapting a passport reader. The Romanian implementation has its own applet structure, its own data formats, and its own sequence requirements that are not publicly documented in a complete way anywhere.


From July 2025, the CEI became the only identity card model being issued nationally. Every identity document issued in Romania from here forward contains a chip the bearer cannot show to most institutions in a form they can read.

That gap will close gradually. The question for anyone building in this space is how long they are willing to wait for it to close, and whether the interim solution — user-produced PDF certificates of what's already on the card — is acceptable friction for their product.



We write about the Romanian CEI — its capabilities, its integration challenges, and the regulatory context around it. If a topic here is relevant to something you're building, feel free to reach out.