Info |
---|
This article includes updates for Smart ID 23.10.5 5. |
An encoding description contains the information for the electronic personalization of a card. You import the encoding description from a file. This article describes how you create descriptions on how to handle certificates and keys. This can be used in Smart ID Identity Manager.
...
Element | Description |
---|---|
WriteCertKeyList=true | Triggers to write a certificate-key-list. |
CertKeyList=... | The description key for the input string. (Corresponds to the structure: "<1. cert>,<1. private key>;<2. cert>,<2. private key>;..." without the square brackets, see examples below. You can pass one or multiple certificate-key like that, each base64 encoded.) The base64 encoded certificate is left-handed to the comma separator and the base64 encoded private key (if any, otherwise empty) is right-handed to the comma separator and each pair of certificate-privatekey is terminated by a semicolon. The certificate and private key are both in DER encoded format and then each base64 encoded. |
CertKeyListReturnField=... | The description key where to set the field definition that later gets the list of written certificates. |
CertKeyListMode=... | Sets the mode for reacting on errors when writing the certificate-key-list to the smartcard. Options are:
The certificates are sorted chronologically (newer certificates first), that is, if the card is full (and you did not set "WRITE_ALL"), only some older certificates may be unwritten. |
...
StoreUserCertsOnly is ignored for the WriteCertKeyList use-case and all certs from the list are written.
Delete certificates and other objects
...
Code Block |
---|
[Application_A] CertTempl=AuthenticationCertificateSC CardSerialNumberReturnField=CM_CARD_NUMBER KeyUsage=DigitalSignature,KeyEncipherment ... [Application_B] CertTempl=NonRepudiationCertificateSC CardSerialNumberField=CM_CARD_NUMBER KeyUsage=NonRepudiation ... |
...
KeyUsage attribute is ignored in the key archiving process.
Required configuration in Identity Manager Admin
...
Code Block |
---|
[Fields] P12PASSWORD_A= P12PASSWORD_B= P12CERTIFICATE_A= P12CERTIFICATE_B= ... |
Encoding Description details:
Code Block |
---|
[Description] ... Applicationlist=AB ClearFields= P12PASSWORD_A,P12Certificate_A,P12PASSWORD_B,P12Certificate_B, ... [Application_A] KeyArchivalRequest=true WriteP12Data=true Certificate=P12Certificate_A P12PASSWORD=P12PASSWORD_A CertTempl=PFXEncryptionCert [Application_B] KeyArchivalRequest=true WriteP12Data=true Certificate=P12Certificate_B P12PASSWORD=P12PASSWORD_B CertTempl=PFXEncryptionCert |
...
Element | Description | |
---|---|---|
KeyArchivalRequest=true | Triggers the KeyArchivalRequestPreProcessor which executes the KeyArchival request at the CA. | |
WriteP12DataP12PASSWORD=true | Triggers the WriteP12KeyStoreApplicationCommand which writes P12 certificates to a token/smartcard. Note: This flag is ignored for integrated CA connectors (they get their P12 data via a different mechanism: the client requests the application by ID from the integrated CA connector and receives the P12 data or SKI-encrypted key-pair in the response). | |
Certificate=P12Certificate_A | Mapping for the KeyArchival certificate returned by the server side KeyArchival request at the CA. This is ignored for integrated CA connectors (see above). | |
P12PASSWORD=P12PASSWORD_A | The P12 password used for the KeyArchival request. It is mandatory to set a P12PASSWORD for the KeyArchivalRequest. | |
CertTempl=... | Defines a certificate template name for the KeyArchival request at the CA. | |
ClearFields=... | Remember to set ClearFields=... P12PASSWORD_A | Output field for the generated P12 password. The field name must be P12PASSWORD_x for Application_x . Leave the field mapping empty. Passing in an external password is not supported. |
CertTempl=... | Defines a certificate template name for the KeyArchival request at the CA. | |
ClearFields=... | Remember to set ClearFields=... otherwise the P12 container and the P12 password will be written into the database, or might be written to log file (which is often not wished!) when returning the fields after the encoding is done. |
...
Key archival with Secure Key Injection
Encrypted key pair is transferred from server to client. Secure Key Injection (SKI) will only be supported by CardOS 5.4W14 or later middleware with MiniDriver and CardOS card should be 5.3 or higher.
Prerequisites
The CardOS middleware must be installed on the Identity Manager server
Set EnableSKI=true in the encoding description to activate SKI.
Define like this in the encoding description (in addition to the definition for nonSKI):
Code Block |
---|
[Fields]
.....
Thumbprint=
...
[Application_A]
EnableSKI=true
|
Additional description fields:
Code Block |
---|
[Description]
...
CardOSSkiThumbprintField=Thumbprint
...
[Application_A]
......
ForceSKI=true |
Description of the elements:
...
Element
...
Description
...
EnableSKI=true
...
Enable SKI process execution. SKI is disabled by default.
...
CardOSSkiThumbprintField=Thumbprint
...
Thumbprint will be supplied from Card which was stored earlier. Set the "Read"-attribute in the "Encoding Fields" tab to get the value into your data-Map.
...
ForceSKI=true
If set to true, Identity Manager will perform SKI key archival forcefully, meaning if middleware/card do not support it, the CA connector endpoints will refuse a non-SKI request. This field is optional. SKI card support is checked at client side via smart card driver api.
The ForceSKI flag has priority over the EnableSKI flag. The ForceSKI flag enables forcefully execution of SKI use cases even though the EnableSKI flag is not provided. Here are some use cases:
ForceSKI | EnableSKI | Selected process |
---|---|---|
true | false | SKI |
true | true | SKI |
false | true | SKI |
false | false | Non SKI |
Repackage PKCS#12 file right after KeyArchival request
To support renaming of the friendly name according to a configurable pattern (also with case-sensitivity) and for renaming friendly names of the CA certificates (intermediates and the root) according to the same pattern, inject this PKCS#12 Repackager mechanism into the KeyArchivalRequestPreProcessor:
Code Block |
---|
<bean id="keyArchivalRequestPreProcessor" class="de.vps.act.action.softtoken.KeyArchivalRequestPreProcessor">
...
<property name="pkcs12Repackager" ref="keyStoreRepackager"/>
</bean>
<bean id="keyStoreRepackager" class="de.vps.act.action.softtoken.PKCS12Repackager">
<property name="friendlyNameNamingStrategy" ref="genericNamingStrategy" />
</bean>
<bean id="genericNamingStrategy" class="de.vps.act.action.softtoken.GenericNamingStrategy">
<property name="juelExpressionResolver" ref="juelExpressionResolver" />
<!-- use _!CERT_SERIAL_NUM to configure the naming with the certificate serial number in place -->
<property name="naming" value="§{CN} - _!CERT_SERIAL_NUM" />
<property name="certSerialInHex" value="true" />
<property name="prefix"><null/></property>
<property name="suffix"><null/></property>
</bean> |
Note the value of "naming" - here "§{CN} - _!CERT_SERIAL_NUM", where you can mix Juel-like expressions (here with "§" (paragraph) which is resolved out of the certificates' DN), free text and a special identifier _!CERT_SERIAL_NUM (that is replaced by the real certificate serial number of the certificate).
With the property "certSerialInHex" as boolean flag, you can change the usage of the certificate serial number in the friendly name by applying it in hexadecimal (true) or decimal (false) notation. Prefix and suffix are free text options to be attached in front of the resolved naming or behind, however, there is no resolving inside the pre- and suffix, just in the "naming" string sequence.
Key recovery
Certificates and corresponding private keys are fetched from from the certificate authority (CA). The requested certificates can be provided either as a list of Core Object IDs or CoreObjectDescriptors via the RecoveryCertificateData attribute of encoding description. Thus the certificates to be recovered can either be looked up via Cert: Load Key History List or Processes: Execute Search Task or any other way that can provide either format.
Key recovery without Secure Key Injection
Define like this in the encoding description:
Code Block |
---|
[Fields]
P12CERTIFICATE_A=
P12PASSWORD_A=
RecoveryCertificateData_A= ...
[Application_A]
CertTempl=Recovery
RecoveryTemplate=Recovery
KeyRecoveryRequest=true
Certificate=P12CERTIFICATE_A
P12PASSWORD=P12PASSWORD_A
WriteP12Data=true
RecoveryCertificateData=RecoveryCertificateData_A |
Description of the elements:
...
Element
...
Description
...
RecoveryCertificateData
The field holding the certificates to be recovered, either as a list of CoreObjectDescriptors or as a list of Core Object IDs.
Note |
---|
The name of the field must be RecoveryCertificateData_<ApplicationId> as shown in the example. |
Info |
---|
It is possible - but not recommended - to not map any value to RecoveryCertificateData_<ApplicationId>. In this case, the certificates to be recovered will be taken from the process variable configured in the bean property keyArchivalRequestPreProcessor.coreObjectIDKey (defaults to "Certificate_CoreObjects" but is often overwritten). |
Key recovery with Secure Key Injection
This use case is only supported with CardOS 5.4 middleware or later with MiniDriver and CardOS 5.3 cards.
Define like this in the encoding description:
...
See section PKCS#12 requests with Secure Key Injection.
Repackage PKCS#12 file right after KeyArchival request
To support renaming of the friendly name according to a configurable pattern (also with case-sensitivity) and for renaming friendly names of the CA certificates (intermediates and the root) according to the same pattern, inject this PKCS#12 Repackager mechanism into the KeyArchivalRequestPreProcessor:
Code Block |
---|
<bean id="keyArchivalRequestPreProcessor" class="de.vps.act.action.softtoken.KeyArchivalRequestPreProcessor">
...
<property name="pkcs12Repackager" ref="keyStoreRepackager"/>
</bean>
<bean id="keyStoreRepackager" class="de.vps.act.action.softtoken.PKCS12Repackager">
<property name="friendlyNameNamingStrategy" ref="genericNamingStrategy" />
</bean>
<bean id="genericNamingStrategy" class="de.vps.act.action.softtoken.GenericNamingStrategy">
<property name="juelExpressionResolver" ref="juelExpressionResolver" />
<!-- use _!CERT_SERIAL_NUM to configure the naming with the certificate serial number in place -->
<property name="naming" value="§{CN} - _!CERT_SERIAL_NUM" />
<property name="certSerialInHex" value="true" />
<property name="prefix"><null/></property>
<property name="suffix"><null/></property>
</bean> |
Note the value of "naming" - here "§{CN} - _!CERT_SERIAL_NUM", where you can mix Juel-like expressions (here with "§" (paragraph) which is resolved out of the certificates' DN), free text and a special identifier _!CERT_SERIAL_NUM (that is replaced by the real certificate serial number of the certificate).
With the property "certSerialInHex" as boolean flag, you can change the usage of the certificate serial number in the friendly name by applying it in hexadecimal (true) or decimal (false) notation. Prefix and suffix are free text options to be attached in front of the resolved naming or behind, however, there is no resolving inside the pre- and suffix, just in the "naming" string sequence.
Key recovery
Certificates and corresponding private keys are fetched from from the certificate authority (CA). The requested certificates can be provided either as a list of Core Object IDs or CoreObjectDescriptors via the RecoveryCertificateData attribute of encoding description. Thus the certificates to be recovered can either be looked up via Cert: Load Key History List or Processes: Execute Search Task or any other way that can provide either format.
Key recovery without Secure Key Injection
Define like this in the encoding description:
Code Block |
---|
[Fields]
P12PASSWORD_A=
RecoveryCertificateData_A= ...
[Application_A]
CertTempl=Recovery
RecoveryTemplate=Recovery
KeyRecoveryRequest=true
P12PASSWORD=P12PASSWORD_A
RecoveryCertificateData=RecoveryCertificateData_A |
Description of the elements:
Element | Description | ||||
---|---|---|---|---|---|
KeyRecoveryRequest=true | Enables KeyRecovery at the CA. | ||||
RecoveryTemplate=Recovery | Certificate template for recovery. | ||||
CertTempl=Recovery | Certificate template, must specify the same value as in RecoveryTemplate. | ||||
RecoveryCertificateData | The field holding the certificates to be recovered, either as a list of CoreObjectDescriptors or as a list of Core Object IDs.
| ||||
P12PASSWORD=P12PASSWORD_A | Output field for the generated P12 password. The field name must be P12PASSWORD_x for Application_x . Leave the field mapping empty. Passing in an external password is not supported. |
Key recovery with Secure Key Injection
See section PKCS#12 requests with Secure Key Injection.
PKCS#12 requests with Secure Key Injection
Anchor | ||||
---|---|---|---|---|
|
To prevent eavesdropping during key import onto the card (e.g. during key archival or key recovery), you can enable Secure Key Injection (SKI), which transfers the key through an encrypted channel from the server to the card.
This is supported by the CardOS 5.4W14 middleware or later on CardOS 5.3+ cards.
Prerequisites
The Identity Manager server must be running on Microsoft Windows.
The required CardOS middleware (including Minidriver) must be installed on the Identity Manager server.
Define like this in the encoding description (in addition to the definition for non-SKI):
Code Block |
---|
[Fields]
Thumbprint=
...
[Description]
CardOSSkiThumbprintField=Thumbprint
...
[Application_A]
EnableSKI=true
ForceSKI=true
... |
Description of the elements:
Element | Description |
---|
RecoveryCertificateData
The field holding the certificates to be recovered, either as a list of CoreObjectDescriptors or as a list of Core Object IDs.
Note |
---|
The name of the field must be RecoveryCertificateData_<ApplicationId> as shown in the example. |
Info |
---|
It is possible - but not recommended - to not map any value to RecoveryCertificateData_<ApplicationId>. In this case, the certificates to be recovered will be taken from the process variable configured in the bean property keyArchivalRequestPreProcessor.coreObjectIDKey (defaults to "Certificate_CoreObjects" but is often overwritten). |
CardOSSkiThumbprintField=Thumbprint
Used to read the Card thumbprint value and hold into this field. The card must be initialized and thumbprint value should be available into the card.
Enforce Secure Key Injection for PKCS#12 requests
Enforce Secure Key Injection for PKCS#12 requests
For applications that require a CA-supplied key-pair to be written to the card, key-pair transfer can be enforced via Secure Key Injection (SKI) to prevent eavesdropping by a malicious client. For SKI to work, the CardOS middleware must also be installed on the Identity Manager server. By default, when SKI is not supported, the client may fall back to a less secure non-SKI request.
Define like this in the encoding description:
Code Block |
---|
...
[Application_A]
ForceSKI=true
... |
If the ForceSKI flag is set, then non-SKI PKCS#12 endpoints of the integrated CA connector will refuse to process the application requested by the client and the CA request will be blocked.
Note
...
integrated CA connectors are required for SKI
...
EnableSKI=true | Enable support of SKI for key import (defaults to false). If the card supports it, SKI will be used to increase security. |
CardOSSkiThumbprintField=Thumbprint | Thumbprint will be supplied from Card which was stored earlier. Set the "Read"-attribute in the "Encoding Fields" tab to get the value into your data-Map. |
ForceSKI=true | Enforce use of SKI for key import (defaults to false). If the ForceSKI flag is set, then non-SKI PKCS#12 endpoints of the CA connector will refuse to process the application requested by the client and the CA request will be blocked. |
The ForceSKI flag has priority over the EnableSKI flag. The ForceSKI flag enables forcefully execution of SKI use cases even though the EnableSKI flag is not set. Here are some use cases:
ForceSKI | EnableSKI | Selected process |
---|---|---|
true | false (default) | SKI |
true | true | SKI |
false (default) | true | SKI |
false (default) | false (default) | Non-SKI |
Note:
The client does not supply the ForceSKI flag to the server for this check (the server already knows it), so it cannot be manipulated by a malicious client attempting a downgrade attack
this flag of course only makes sense in an SKI-enabled setup with integrated CA connector, the proper cards, middleware (currently only CardOS 5.
4+), etc.Key pair generation and discovery
...
Description of the elements:
Element | Description |
---|---|
UseExistingKeyPair=1 | Triggers the key pair discovery. |
PubKeyReturnField=... | Defines the field in which to store the discovered public key. You must also define the field in the |
ObjectCriteria=... | See the description above concerning the 4 parameters. Note! Use single quotes (not double quotes) to enclose the value of the attribute. |
Skip writing CA certificates
If you would like to just write user certificates without intermediate certificates and without a root certificate to the smartcard, you can add an encoding property to your certificte applicationcertificate application:
Define like this in the encoding description:
...
Element | Description |
---|---|
StoreUserCertOnly=true | Triggers writing only user certificates without intermediate certificates and without a root certificate. |
Note |
---|
The StoreUserCertOnly option may be used only inside an application that writes a certificate ( |
...
for example defining CertTempl=xyz). |
Object labels
The label (CKA_LABEL value) for certificates, public and private keys using the default template, is generated using the CN from the DN followed by a white space and a two digit counter that starts by 01. The CN is limited to 36 characters. Doing so, the complete value is never longer than 39 characters. The reason for that is that CSPs in Windows have issues with longer values.
...
Note |
---|
You can also specify LabelTemplate=skip which will instruct IDM not to set any label attribute. This is required e.g. , for example, for certain TCOS cards. |
Corresponding to this definition, the default label template is:
labeltemplate=limitedname=36,blank=1,certcounter
The content of the every type of LabelTemplate can also be concatenated using the fields in the Fields section of the encoding description, using an expression language based on the exclamation mark. See https://docs.spring.io/spring-framework/reference/core/expressions.html for details.
Examples:
Code Block |
---|
// Just provide the whole via a field: LabelTemplate=!{FIELD_NAME} // Or concatenate different parts: LabelTemplate=fixtext=!{FIELD_NAME} // The language has a sophisticated syntax and tuff like this also work: LabelTemplate=fix!{'text=Bla,snr'} // -> fixtext=Bla,snr -> Bla123B4 // Or really complex stuff: LabelTemplate=fixtext=!{MODEL.contains('4') ? 'EF.C.ICC.EX' + CERT_INDEX + '.RSA : 'Ex. Certificate ' + CERT_INDEX} |
...
A certificates' SubjectKeyIdentifier is defined in the x509 extensions section, as seen in this image:
...
This SubjectKeyIdentifier is then taken for CKA_ID generation with the following generation rules:
Byte is an encoding identifier. Generally DER encoding is preferred, represented by the byte sequence 04h.
Byte is the length of the SubjectKeyIdentifier (here 6 bytes, therefore 06h).
The following Bytes are the SubjectKeyIdentifier bytes.
The resulting CKA_ID (8 bytes length) then is: 0406014B2ADD5F66 (=example)
Apply extra attributes
To change the default sets used by the JPKIEncoder, define like this in the encoding description:
...
AttributesCertOpt=CKA_ALWAYS_AUTHENTICATE=TRUE,CKA_CERTIFICATE_CATEGORY=1,CKA_START_DATE,CKA_HASH_OF_SUBJECT_PUBLIC_KEY
Attribute | Data type | Value (as appearing in the dsc file) |
---|---|---|
CKA_DERIVE | CK_BBOOL | TRUE | FALSE |
CKA_LOCAL | CK_BBOOL | TRUE | FALSE |
CKA_MODIFIABLE | CK_BBOOL | TRUE | FALSE |
CKA_ENCRYPT | CK_BBOOL | TRUE | FALSE |
CKA_VERIFY | CK_BBOOL | TRUE | FALSE |
CKA_VERIFY_RECOVER | CK_BBOOL | TRUE | FALSE |
CKA_WRAP | CK_BBOOL | TRUE | FALSE |
CKA_TRUSTED | CK_BBOOL | TRUE | FALSE |
CKA_SENSITIVE | CK_BBOOL | TRUE | FALSE |
CKA_DECRYPT | CK_BBOOL | TRUE | FALSE |
CKA_SIGN | CK_BBOOL | TRUE | FALSE |
CKA_SIGN_RECOVER | CK_BBOOL | TRUE | FALSE |
CKA_UNWRAP | CK_BBOOL | TRUE | FALSE |
CKA_EXTRACTABLE | CK_BBOOL | TRUE | FALSE |
CKA_ALWAYS_SENSITIVE | CK_BBOOL | TRUE | FALSE |
CKA_NEVER_EXTRACTABLE | CK_BBOOL | TRUE | FALSE |
CKA_PRIVATE | CK_BBOOL | TRUE | FALSE |
CKA_TRUSTED | CK_BBOOL | TRUE | FALSE |
CKA_WRAP_WITH_TRUSTED | CK_BBOOL | TRUE | FALSE |
CKA_ALWAYS_AUTHENTICATE | CK_BBOOL | TRUE | FALSE |
CKA_CERTIFICATE_CATEGORY | CK_ULONG | Categorization of the certificate: 0 = unspecified (default value), 1 = token user, 2 = authority, 3 = other entity |
CKA_START_DATE | CK_DATE | Implicit. Start date for the certificate, taken from the certificate that was encoded. |
CKA_END_DATE | CK_DATE | Implicit. End date for the certificate, taken from the certificate that was encoded. |
CKA_HASH_OF_SUBJECT_PUBLIC_KEY | Byte array | Implicit. SHA-1 hash of the subject public key, automatically calculated from the certificate that was encoded. |
CKA_HASH_OF_ISSUER_PUBLIC_KEY | Byte array | Implicit. SHA-1 hash of the issuer public key, automatically calculated from the certificate that was encoded. |
CKA_CHECK_VALUE | Byte array | Implicit. First three bytes of the SHA-1 hash of the certificate’s attribute CKA_VALUE, automatically calculated from the certificate that was encoded |
...