Five things changed for Cartão de Cidadão v2 developers. Keys moved from RSA to ECDSA. [...]
For contact-mode operations, updating the middleware is generally enough with no significant integration change. Contactless, however, requires new SDK methods. Anything that verifies signatures or uses the SDK cryptography methods needs attention because of ECDSA, which is where most Cartão de Cidadão v2 developers lose time.
The new Cartão de Cidadão has been issued since June 2024, redesigned for the security and format standards of Regulation (EU) 2019/1157, which had been in application since 2 August 2021 and was replaced by Regulation (EU) 2025/1208 on 9 July 2025. Old cards that are still valid keep working, so your code has to handle both indefinitely rather than migrating from one to the other.
Cartão de Cidadão v2 for developers: what changed from v1?
Why does ECDSA break code that looked algorithm-agnostic?
Because a lot of code is not as agnostic as it reads. It surfaces in four places: a hardcoded algorithm identifier in a signature verification routine written when RSA was the only option, a validation library configured with an allowed algorithm list nobody has revisited, key size assumptions in buffer handling or database column definitions, and test fixtures containing only RSA-signed material.
The fourth costs the most time, because it produces a green build and a failing system. If your test data was captured before mid-2024, it contains no ECDSA cards at all.
What is the CAN, and what is PACE doing?
Two different things, often confused. The Card Access Number is a six-digit code printed in the lower right corner of the new card, and it exists to prevent unauthorised contactless reading. It is not a PIN. It is distinct from the authentication, signature and address PINs, and it is not secret in the same way: anyone holding the card can read it. It proves physical possession, not consent. One implementation detail: when calling C_Login through PKCS#11 in contactless mode with a v2 card, the CAN is passed as the PIN parameter, which nothing in the parameter name suggests.
PACE is the authentication protocol protecting contactless use, described in part 11 of ICAO Document 9303. Access control to the data on the contactless chip is performed through PACE using data read from the document Machine Readable Zone, or optionally, in the case of cards, through the CAN. Security is additionally guaranteed by passive authentication of the datagroups, and chip authentication through Active Authentication and Chip Authentication mechanisms.
One user experience detail worth designing for. The desktop application asks for the CAN on first contactless use and does not ask again for subsequent uses with the same card, with an option not to store it. If you build your own flow, decide deliberately whether you cache the CAN, because the convenience and the security argument point in opposite directions and the decision belongs to your product owner rather than to whoever writes the dialog.
What changes in the certificate chain?
This is the change most likely to reach production undetected, because it depends on which interface your code uses. Chain building becomes your responsibility rather than something the module hands you. Code that assumed a complete chain arrives from the token will fail validation on v2 while continuing to work on v1, which is exactly the pattern that gets diagnosed as a bad card.
And if you fetch intermediates at runtime through AIA, you have introduced a network dependency into a verification path. Decide whether that is acceptable, and if it is not, pre-load and cache them with a plan for updating. The desktop application documentation includes a troubleshooting section on problems with the new trust chain, which is a reasonable signal that this is not a theoretical concern.
What is the shortest migration checklist for Cartão de Cidadão v2 developers?
There is a test mode, and it matters more than it sounds. The SDK documentation refers to configuring one alongside the contactless access section. PIN codes block after three wrong attempts, unblocking requires an in-person visit with the PIN letter, and developers testing signature flows against real cards have blocked them. Find that section before your first signature test, not after.
The sixth item is the only genuinely new development. The first five are a morning of reading your own code followed by fixing what you find, and they are what separates an integration that works on both cards from one that works on the cards your developer happens to own. If you are starting from scratch rather than migrating, our guide on integrating the Citizen Card into private applications covers the ground before this one.


