Creating new eID applications

Redaktsioon seisuga 27. august 2015, kell 22:05 kasutajalt SK (arutelu | kaastöö) (→‎Digital signing)
(erin) ←Vanem redaktsioon | Viimane redaktsiooni (erin) | Uuem redaktsioon→ (erin)
Jump to navigation Jump to search

Creating new eID applications

This section is about creating new eID applications. It would definitely be a good idea to read the general information for developers section first.

Personal identification

EID cards have a certificate for digital personal identification. If the user is able to prove that he or she has access to the secret key of this certificate, we believe that he or she is the owner of the certificate.

Personal identification is performed according to the (simplified) protocol below:

  1. User will present a certificate to the system and claim that he or she is its owner.
  2. The system generates a random one-off number (nonce), which will be given to the user for signing with the personal identification key.
  3. User unlocks the personal identification secret key on the card using the PIN1 code.
  4. The card is given a nonce that it will sign; the result is read from the card and forwarded to the system.
  5. The system checks if the signature can be verified with the public key on the certificate.
  6. The system checks the certificate's validity (see Certificate validity check).

If everything went well, it can be presumed that the user is really the owner of the certificate -- and as the name and the personal identification number of the owner are on the card, the identity of the owner is now known. Although actually it can be someone else who has the certificate owner's card and knows its PIN1, there is no way of verifying this.

Sample code for personal identification can be seen as a separate application and within the Claims use case.

Identification on the web

On the web, personal identification is achieved in the course of a SSL/TLS handshake where the client's certificate is also verified. A thorough description of the protocol is available in Wikipedia, but in short, the procedure is like the one described above, only the signature is not given to a nonce but a hash of all previous messages. As messages contain random numbers, their hash is also random.

Here, attention should also be paid to the certificate validity check in a SSL/TLS session.

In the sample code, personal identification on the web is done on a web form.

SSL/TLS renegotiation error

In 2009, an error was found in the SSL/TLS protocol that made it possible to insert texts chosen by an attacker into connections.[1][2] As a result of this, renegotiation was updated in the SSL/TLS specifications, but these updates were not backwardly compatible.[3] Therefore, older SSL/TLS clients and web browsers are not able to renegotiate with servers that use the updated version.

If a SSL/TLS session is initiated without requesting a certificate, i.e. without identifying the person, renegotiations have to be carried out later to achieve this -- e.g. if the user visits a website using the HTTPS protocol and if he later wants to log in with an ID card, a renegotiation has to be carried out. However, older browsers cannot do this according to the new protocol. If there is a need to do this, two separate connection points have to be created: a first one that performs "pure" SSL/TSL and a second one that requests the user's certificate.

If the server identifying the user is at a separate connection point, when a session is started with it, it will request the user's personal identification certificate right away and there is no need to renegotiate later.

Separate connection points should be on distinct IP addresses or at least use different ports. A separate virtual host is not enough because the SSL/TLS is created first and only then is it decided which virtual host to use.

Identification with mobile ID

Personal identification with mobile ID is carried out as follows:[4][5][6]

  1. An ordinary SSL/TLS session is created without requesting the client's certificate.
  2. User inputs his or her phone number and/or personal identification number and the code of its issuer state. These data are sent to the DigiDocService service using the MobileAuthenticate query.
  3. DigiDocService verifies via the OCSP protocol that the personal identification certificate of the user's mobile ID is valid.
  4. DigiDocService performs the following simultaneously:
    • Sends a personal identification query to the mobile operator (who will forward it to the user's phone);
    • Returns a check code and the user's certificate.
      • Attention: The service returns only the certificate of the person who is being identified -- this does not mean that the user has been authenticated!
  5. The application displays a four-digit personal identification query check code to the user.
  6. The application will now periodically go to DigiDocService to query for the status of the personal identification using the GetMobileAuthenticateStatus query.
    • The status query can also be done synchronously, i.e. DigiDocService keeps the connection open and does not return anything until an answer has come from the mobile phone.
  7. A message about the personal identification query will be displayed on the user's phone
  8. The user makes sure the check code displayed on the phone is the same as the one displayed by the application and inputs mobile ID PIN1.
  9. The challenge issued by the service is signed with the secret key on the SIM card and the result sent to the mobile operator, who will forward it to DigiDocService.
  10. The next time the application queries the service for query status, the service responds that the user has been authenticated and returns the signature.

Usage examples can be seen in the Claims use case (Mobile ID section) and a SK example application can be found here.

Digital signing

Starting from 2015 digital signatures are created in BDOC format. Until the end of 2014 DDOC was used. Formats supported in different DigiDoc libraries can be found here. DigiDocService supports both formats.[7]

Regardless of the format of the signature, the approach is the same with the libraries as well as with DigiDocService:

  1. a container is created,
  2. the signed files are added,
  3. a hash is generated across data,
  4. the hash is signed with the secret keys of the parties,
  5. a validity confirmation is queried for the signatory's certificate (checking the revocation list is not enough, see Digital signing and Certificate validity check) and
  6. the signature and confirmation are added to the container.

When signing in web applications, all pre- and post-signing activities are the same as with local signing, but the signing of the hash (step 4) is done in the client's web browser. A JavaScript library has been created for it with a unified API (application programming interface) that allows different signing plugins to be used similarly, regardless of the user's operation system and browser. More information here.

Upon verifying the signature, one has to make sure that the hashes in the container match the hashes signed, and that the signatures on both hashes and validity confirmations are correct. (For this purpose, the public keys present on the signer's certificate and the validity confirmation issuer's certificate are used.)

For clarity and security, every application with a digital signing function has to meet two requirements:[8]

  1. Before signing, the user must have a chance to get acquainted with the data in a reasonable way.
  2. After signing, the user can check what was signed with his or her signature, i.e. the user has access to the DigiDoc container with the original signed data and signatures.

The digital signing of documents has been demonstrated both as a standalone utility and in a claims presentation use case – both on the web, using DigiDocService or a SWIG wrapper and in a desktop application.

Signature verification is demonstrated in the stand-alone application, the claims application and the claims handling service.

Digital signing with mobile ID

There are two ways for signing documents with mobile ID:[4][5][6]

  1. We send a document to DigiDocService, upon which a new session is initiated where a container containing only this document is created and returned to the submitter of the query. For this, the queries MobileCreateSignature and GetMobileCreateSignatureStatus have to be used. This is good in a situation in which we need DigiDocService for signing only.
  2. We sign the container created during the present session using the queries MobileSign and GetStatusInfo. This approach should be used when the DigiDocService session is also used for performing other operations and signing the container with mobile ID is just one part of it.

In general, signing with a mobile ID is similar to personal identification with a mobile ID, with the following exceptions:

  • MobileAuthenticate and GetMobileAuthenticateStatus are not sent to the service but rather the abovementioned queries.
  • The documents being signed or their hashes are sent to the service and the mobile ID signature is requested to their hash, not to the challenge.
  • The signature is given using the secret digital signing key, not the personal identification key. As a result of this, DigiDocService checks and returns the signing certificate and the user must input PIN2, not PIN1.

As a result of these actions, DigidocService will create a signed container that the application can download. If at first only the hashes of documents to be signed were sent to the service, the additional step of replacing the hashes in the container with the actual documents has to be performed.

Usage examples can be seen in the Claims use case (Mobile ID section) and a SK example application can be found here.


In the context of eID, encryption is carried out according to the principles presented in standard XML Encryption Syntax and Processing to ensure that the classified files are sent to certain addresses. However, DigiDoc applications have a specific approach where before encryption the files are added into a DIGIDOC-XML container, which may be signed but doesn't have to be.

The data are contained in a DDOC-container, which is encrypted using a symmetric algorithm (128-bit key AES) and the result is a CDOC container. The key used for encryption is encrypted using the public keys of the receivers' personal identification certificates and the results are added to the CDOC container. Also, the metadata about encrypted files will be added there so that the user can see what's inside. As metadata is visible to everybody without decrypting the container, it is recommended to use caution and make sure no sensitive information is contained in the metadata.

When receiving the container, the receiver uses the secret key of his/her personal identification certificate to obtain the AES key that will enable decryption of the files.

This kind of encryption can only be used short-term, e.g. for the transportation of data. As the encrypted data can be opened only by people appointed as receivers with their certificates valid at the moment of encryption, this solution is not suitable for long-term archiving -- when expired, certificates on a user's card are replaced by new ones and the key cannot be used anymore.[9] This means that the container is closed forever. Also, it should be remembered that a container that has been encrypted for an ID card cannot be decrypted by the same person with his or her digital ID.

Encryption is supported by the libraries libdigidoc (and therefore also libdigidoccom) and jdigidoc. The service DigiDocService cannot be used for encryption, but it would not be sensible anyway, as the classified data would have to be sent to SK first. Encryption is demonstrated in the claims handling service and decryption in the claims application.

Attention: when creating software that decrypts data, one should keep in mind the padding oracle attack.

Loading certificates from LDAP

For encrypting the transport key with the receiver's public keys, these will have to be obtained first. For this purpose, SK has set up a abbr title="Lightweight Directory Access Protocol">LDAP service that helps to find[10]

  • the certificates of SK's certifiers and valid revocation lists,
  • valid certificates issued to personal identity documents and
  • all issued organisation certificates.

The service is located at The LDAPv3 protocol has to be used for communication,; access is free and without charge.[11] For finding a personal certificate, an exact Common Name (in the form "surname,name,personal identification number") or a personal identification code has to be entered into the query. Searching by pattern is prohibited. For example (the following queries will not return anything, as test certificates are not kept in these catalogue branches -- for testing, you can use your own personal identification number here):

# Linux
ldapsearch -x -h -b ou=Authentication,o=ESTEID,c=EE "(cn=MÄNNIK,MARI-LIIS,47101010033)" userCertificate
ldapsearch -x -h -b ou=Authentication,o=ESTEID,c=EE "(serialNumber=47101010033)" userCertificate

# Windows - if the following queries are entered to Internet Explorer's address bar then
#           the Contacts application will be deployed, where the certificate(s) can be found on the "IDs" tab

The exact catalogue structure can be found in the SK repository.

When submitting a query, it should be kept in mind that one person may have many certificates in LDAP. (e.g. ID card and digital ID). It should also be noted that LDAP is not secure; therefore, it is possible for an attacker to switch the certificate for his own and so the returned certificate should always be checked: who has it been issued to, by whom, etc.

Certificate validity check

Certificate validity should also be checked separately at the issuer; it is not enough to verify the issuing and expiration dates, as the issuer can revoke the certificate before time, suspend it or cancel suspension for any reason.

Note: The following applies to ID card and digital ID only: A mobile ID certificate is verified by DigiDocService and in an SSL/TLS session, the personal identification is done on application level.

There are two ways to check validity:

  • The Certificate Revocation List or CRL, which is a periodically downloadable list of all certificates that have been revoked. Using the revocation lists of AS Sertifitseerimiskeskus is free of charge.
  • Online Certificate Status Protocol or OCSP, which will submit the certificate validity query to an OCSP server (from here on referred to as responder), which answers in real time. Using the OCSP service of AS Sertifitseerimiskeskus is a paid service[12]

Although using revocation lists is free and they are more available (when CRL servers become inaccessible, the last downloaded status is still known), the information in them is not a real time representation of certificate validity. For the latest validity information, the OCSP service should be used, but this is a paid service and if the responder is not accessible, all information about certificates is absent (including that which was valid a few moments ago). For each web service, the requirements should be studied and a decision made on which solution suits best.

Attention: Software developers have sometimes used the LDAP service as a means to verify certificate validity at personal identification. This is a misuse of the service and therefore prohibited, even if it (sometimes) gives correct results. LDAP data transfer is not secure, so the responses can be faked or altered and the LDAP catalogue can contain non-valid certificates.

In a SSL/TLS session

Verification of the validity of the certificate of the ID card or digital ID given by the client in the beginning of a SSL/TLS session is a separate topic, as this has to be done by the web server rather than the application. The present guide will only treat Apache httpd and Microsoft IIS servers, although the guidelines may work with others as well.

If revocation lists are used, everything works fine and web servers are able to use them independently. For server configuration, see the sample configuration.

For using OCSP, there are some additional conditions that are explained in the next chapters.

Application-level OCSP

Although both Apache and IIS have built-in tools for requesting OCSP validity confirmation, they need an OCSP responder certificate to be attached to the response. The latter is required so that the signature on the response can be verified. But adding a certificate is optional and the OCSP service of Sertifitseerimiskeskus does not do this. Therefore, it is not possible to request OCSP validity confirmation by default tools. Support for requesting OCSP validity response needs to be added to the existing session management tools, so that at the beginning of a new session it can be made sure that the certificate submitted by the user is valid.

One way to verify validity is to use the DigiDocService method CheckCertificate, which will return the status of the certificate given as a parameter. This is one of the simplest solutions, but it requires access to the DigiDocService (which is a pay service) and the web application must have tools for communicating with a SOAP server.

It is always possible to use alternative means that can communicate with the OCSP service of Sertifitseerimiskeskus and do not need the assistance of DigiDocService for it; but the responder's certificate will have to be presented manually to them for verifying the response.

NB! The OCSP response must always be verified in applications; otherwise, it is easy for an attacker to fake the validity confirmation! If DigiDocService is used, this will be done in the course of the query; if alternative means are used, this will probably have to be done manually.

Sample code for verifying certificate validity with the DigiDocService can be found in the web form and an alternative using OpenSSL in the sample application.

Authentication OCSP

In addition to the "usual" OCSP service, Sertifitseerimiskeskus also offers authentication OCSP: this is a service designed for logging into systems. Authentication OCSP does not record validity confirmation requests into a security log, so there will be no proof later on about validity at that moment. Also, the pricing structure is different: a fee has to be paid for each separate certificate whose status is queried, not for the amount of queries. Therefore, this is suitable for systems with a small number of users, but not for public web services.[13]

Authentication OCSP returns the certificate of the responder in its responses, so it can be used with Apache and IIS's built-in OCSP validity verification tools. However, this should only be done in case the pricing structure described in the last paragraph is acceptable; as with many unique users, this service may turn out more expensive than ordinary OCSP.

Authentication OCSP also lacks a test service; therefore, while developing/testing, the queries have to be sent to the live responder.

Using the personal data file

No DigiDoc library is able to read the personal data file contained on an ID card. Therefore, this is quite a low level operation that each developer has to carry out manually. As the more important fields in the personal data file (name, personal identification number and the information that can be deducted from it) also exist on the certificate, it should be enough for the application to read the certificate, which is supported by many DigiDoc libraries.

Note: Digital ID does have a personal data file, but only the document number field has been completed in it; the personal identification number consists of empty spaces and all other fields contain one 0-byte.

But if there still is a need to read the personal data file, there are not many ways to do it. The communication with the card either has to be direct or a library must be used that will abstract it to a minimal extent (e.g. OpenSC). However, with the latter there is the problem that such libraries mostly exist for C and using them in e.g. Java or .NET is more complicated than direct communication with the card.

In some certain situations, using eidenv application with the -x key may be enough.

In web applications, the user's personal data cannot be read, as the new web browser plugin does not support this.

Direct communication with the card

For direct communication with the Estonian eID smart cards, the necessary byte sequences have to sent to the card (Application Protocol Data Unit or APDU) and the responses read. The format and meanings of messages have been determined in the ISO/IEC 7816-4 standard, the last version of which can be bought from ISO, but a slightly outdated version is also available for free. The specifics of Estonian eID smart cards have been described in the EstEID card user manual (in Estonian).

As the message format is standardised, it is not very likely that written code would not work with newer cards. The only thing that can happen is that on new cards the location of the personal data file changes or the data contained in it are different from those of older cards. In such situations, the code also using OpenSC or other libraries has to be rewritten and the file location and meanings of fields updated. (Similarly, an eidenv application would have to be rewritten in such a situation, but this would be done by its manager.)

The byte sequence needed for reading the personal data file is as follows (using the T=0 protocol):[14]

00 A4 00 0C          # We choose root folder
00 A4 01 0C 02 EE EE # We choose folder EEEE
00 A4 02 04 02 50 44 # We choose file 5044, which contains personal data
00 B2 XX 04          # We read record XX (see table) from the personal data file
                     # The card responds 61 YY, where YY denotes the number of bytes waiting to be read
00 C0 00 00 YY       # We read YY bytes from the card
                     # Card responds ... 90 00, where ... is the requested data and 90 00 means status OK 
Record number Contents Maximum length in bytes
1 Surname 28
2 Name line 1 15
3 Name line 2 15
4 Gender 1
5 Citizenship 3
6 Date of birth ( 10
7 Personal identification number 11
8 Document number 9
9 Last day of validity ( 10
10 Place of birth 35
11 Issuing date ( 10
12 Type of residence permit 50
13 Notes line 1 50
14 Notes line 2 50
15 Notes line 3 50
16 Notes line 4 50

If a library is used for communicating with the card, the last step may not be necessary. For instance, using javax.smartcardio classes we give the byte sequence 00 B2 XX 04 and get an <ResponseAPDU object in response, whose getData()] method returns the desired data and getSW() returns the status.[15] Therefore, there is no need to manually send the message 00 C0 00 00 YY.

An example of reading personal data can be found in the claims application.