Skip to main content

Integrare EidKit SSO

EidKit SSO este un identity provider OIDC standard. Îl integrezi exact ca Google Sign-In sau Apple Sign-In — un Client ID, un Client Secret, un redirect URI.

Ce primești

  • Client ID și Client Secret — emise de EidKit
  • Issuer URL: https://idp.eidkit.ro
  • Autodiscovery OIDC la https://idp.eidkit.ro/.well-known/openid-configuration
  • Date verificate criptografic de MAI — nu auto-declarate de utilizator

Contactează hello@eidkit.ro pentru a-ți configura clientul.


Scopuri disponibile

ScopeDate returnate
openidsub — pseudonim stabil (SHA-256 al CNP, nu CNP-ul brut)
profilename, given_name, family_name, birthdate
addressaddress.formatted — adresă verificată MAI, nu auto-declarată
cei:documentNumăr, serie, dată expirare, autoritate emitentă
cei:cnpCNP extras server-side din DG1 verificat — nu din payload-ul aplicației
cei:pictureFotografie față (JPEG base64, ~33KB)
cei:signatureImagine semnătură olografă (JPEG base64, ~3.5KB)

Majoritatea clienților au nevoie doar de openid profile. Imaginile sunt opt-in pentru cazuri specifice (ex. asigurări, HR).


Înregistrare și autentificare — același flux

Nu există diferență între login și înregistrare. sub-ul din JWT este un pseudonim stabil și unic per persoană. Prima atingere a cardului creează contul automat.

const { sub, name, given_name, family_name, address } = jwtPayload;

let user = await db.users.findOne({ eidkitSub: sub });

if (!user) {
// Prima autentificare = înregistrare automată
user = await db.users.create({
eidkitSub: sub,
name: name,
givenName: given_name,
familyName: family_name,
address: address?.formatted,
createdAt: new Date(),
});
}

// Autentificările ulterioare = login cu același sub
await session.create({ userId: user.id });

Verificare JWT fără apeluri de rețea

După setup inițial, semnăturile token-urilor pot fi verificate local folosind JWKS-ul public — fără niciun apel către EidKit per request:

GET https://idp.eidkit.ro/.well-known/jwks.json

Cachează cheile publice și verifică semnătura JWT local la fiecare request.


Exemplu JWT — scopes tipice (openid profile address)

{
"sub": "a3f7bc9d...",
"name": "CĂTĂLIN TOMA",
"given_name": "CĂTĂLIN",
"family_name": "TOMA",
"birthdate": "1985-03-15",
"address": {
"formatted": "Str. Exemplu Nr. 1, Timișoara, Timiș"
},
"iss": "https://idp.eidkit.ro",
"aud": "client-id-ul-tau"
}

Gestionarea sesiunii

EidKit emite un ID token o singură dată — nu există refresh tokens în configurația standard. Tu gestionezi sesiunea utilizatorului cu propriul cookie sau sesiune server-side. Dacă ai nevoie de re-verificare (fluxuri de securitate ridicată), utilizatorul atinge cardul din nou.

Token-uri

Folosește ID token-ul — conține tot ce ai nevoie. Access token-ul nu are un API EidKit împotriva căruia să-l folosești.


Garanții de securitate

Spre deosebire de un provider OIDC clasic care emite token-uri pe baza unei parole, EidKit SSO nu emite niciun token dacă oricare din verificările de mai jos eșuează:

VerificareCe garantează
Lanț DSC → CSCA MAICartea de identitate a fost emisă de statul român
Hash DG1 din SODIdentitatea (inclusiv CNP-ul) nu a fost modificată după semnarea de MAI
Hash DG14 din SODCheia publică a cipului (Q_chip) a fost semnată de MAI — nu poate fi substituită
Semnătură ECDSA a cipuluiCardul fizic a fost prezent — nu se poate falsifica fără cip
Challenge server-sideSemnătura este proaspătă — nu poate fi refolosită (anti-replay)
Lanț CE81 → MAI GenPKI Sub-CACheia de autentificare a cipului a fost emisă de MAI
Legătură CA (ECDH, BSI TR-03110)Cipul care a semnat CE81 deține exact cheia Q_chip din identitate — atacul de separare a dovezilor este imposibil

Proba de PIN: Autentificarea activă pe cipul CEI necesită verificarea PIN-ului de autentificare (4 cifre) înainte ca cheia CE81 să poată semna challenge-ul. Semnătura AA în token implică că utilizatorul cunoaște PIN-ul cardului fizic.

Serverul extrage CNP-ul direct din bytes-urile DG1 verificate — nu îl acceptă din payload-ul aplicației.