Setting up One-time Keys

ENTERPRISE EDITION This is a SignServer Enterprise Edition (EE) feature.

One-time keys and certificates allow you to have a large number of individual signing keys and certificates, despite the often limited storage capabilities of HSMs. One-time keys are created on request and are deleted once the signature has been created.

One-time keys use a specific crypto worker called OneTimeCryptoWorker. The crypto worker references a regular crypto token used to generate the short-lived key-pair. Every time a signer requests a crypto instance from the OneTimeCryptoWorker, a new key-pair is generated and a certificate for the public key is obtained from a CA Connector component.

SignServer allows multiple implementations of the CA component. The following describes how to set up one-time keys either using the Self-Signed CA Connector for testing purposes, or using the EJBCA WS CA Connector that connects to the EJBCA.

    Step 1: Set Up Crypto Worker with Source Crypto Token

    Make sure you have a CryptoWorker with a source PKCS11CryptoToken set up.

    The following shows a source crypto worker CryptoTokenP11 sample configuration pkcs11-crypto.properties:

    Sample source crypto worker configuration
    WORKERGENID1.TYPE=CRYPTO_WORKER
    WORKERGENID1.IMPLEMENTATION_CLASS=org.signserver.server.signers.CryptoWorker
    WORKERGENID1.CRYPTOTOKEN_IMPLEMENTATION_CLASS=org.signserver.server.cryptotokens.PKCS11CryptoToken
     
    # Name for other workers to reference this worker:
    WORKERGENID1.NAME=CryptoTokenP11
     
    # Name of the PKCS#11 shared library to use:
    WORKERGENID1.SHAREDLIBRARYNAME=Utimaco
     
    # HSM slot details
    WORKERGENID1.SLOTLABELTYPE=SLOT_NUMBER
    WORKERGENID1.SLOTLABELVALUE=1
    WORKERGENID1.PIN=foo123
     
    #One key to test activation with is required. If this key does not already exist generate it after the worker has been created.
    WORKERGENID1.DEFAULTKEY=testkey0

    Step 2: Set Up One-time Crypto Worker Referencing the Source Crypto Worker

    Next, set up a OneTimeCryptoWorker referencing the source CryptoWorker. You can choose to test the OneTimeCryptoWorker without an actual CA by setting up the Self-signed CA Connector that generates its own self-signed certificate, or using the EJBCA WS CA Connector that connects to EJBCA using Web Services.

    Self-Signed CA Connector

    The Self-Signed CA Connector generates its own self-signed certificate and is suitable for testing the OneTimeCryptoWorker without requiring a real CA.

    To configure the Self-Signed CA Connector and set up a crypto worker referencing the source crypto worker, do the following:

    1. Add a new worker using the template onetime-crypto.properties. See OneTimeCryptoWorker properties for details.

      Property

      Value

      NAME

      Update as appropriate, for example P11 or P12 and possibly slot.

      CACONNECTOR_IMPLEMENTATION

      org.signserver.module.onetime.caconnector.SelfSignedCAConnector

      CERTSIGNATUREALGORITHM
      SHA256WithRSA

      Example Configuration Sample
      The following shows a sample configuration onetime-crypto.properties for a crypto worker CryptoTokenP11OneTimeSelfSigned:

      Sample Configuration
      WORKERGENID1.TYPE=CRYPTO_WORKER
      WORKERGENID1.IMPLEMENTATION_CLASS=org.signserver.module.onetime.cryptoworker.OneTimeCryptoWorker
      # Name for other workers to reference this worker:
      WORKERGENID1.NAME=CryptoTokenP11OneTimeSelfSigned
      # References a source CryptoToken
      WORKERGENID1.CRYPTOTOKEN=CryptoTokenP11
      # Key generation
      WORKERGENID1.KEYALG=RSA
      WORKERGENID1.KEYSPEC=2048
      # CA Connector: Self-signed demo connector (not using a real CA)
      WORKERGENID1.CACONNECTOR_IMPLEMENTATION=org.signserver.module.onetime.caconnector.SelfSignedCAConnector
       
      # CSR & Certificate Signing
      WORKERGENID1.CERTSIGNATUREALGORITHM=SHA256WithRSA
    2. Check that the status of the worker is ACTIVE, either on the SignServer Admin Web Worker Status page, or in the CLI using the command: ./bin/signserver getstatus brief.

    EJBCA WS CA Connector

    The EJBCA WS CA Connector connects to EJBCA using Web Services.

    To configure the EJBCA WS CA Connector and set up a crypto worker referencing the source crypto worker, do the following:

    1. Add a new worker using the template onetime-crypto.properties and make the following changes. See OneTimeCryptoWorker properties for details.

      Property

      Value

      NAME

      Update as appropriate, for example P11 or P12 and possibly slot.

      CACONNECTOR_IMPLEMENTATION

      Enable the following by removing the comments for the EjbcaWSCAConnector properties:

      • CACONNECTOR_IMPLEMENTATION=org.signserver.module.onetime.caconnector.EjbcaWSCAConnector

      • TRUSTSTORETYPE

      • TRUSTSTOREPATH or TRUSTSTOREVALUE (depending on TRUSTSTORETYPE)

      • TRUSTSTOREPASSWORD

      • TLSCLIENTKEY

      • EJBCAWSURL

      • CANAME

      • ENDENTITYPROFILE

      • CERTIFICATEPROFILE

      • USERNAME_PATTERN

      • SUBJECTDN_PATTERN

      • SUBJECTALTNAME_PATTERN

      • CERTIFICATESTARTTIME

      • CERTIFICATEENDTIME

      CERTSIGNATUREALGORITHM

      SHA256WithRSA

      Example Configuration Sample

      The following shows a sample configuration onetime-crypto.properties for a crypto worker CryptoTokenP11OneTimeEjbcaWS:

      Sample CryptoTokenP11OneTimeEjbcaWS Configuration
      WORKERGENID1.TYPE=CRYPTO_WORKER
       
      WORKERGENID1.IMPLEMENTATION_CLASS=org.signserver.module.onetime.cryptoworker.OneTimeCryptoWorker
       
      # Name for other workers to reference this worker:
      WORKERGENID1.NAME=CryptoTokenP11OneTimeEjbcaWS
       
      # References a source CryptoToken
      WORKERGENID1.CRYPTOTOKEN=CryptoTokenP11
       
      # Key generation
      WORKERGENID1.KEYALG=RSA
      WORKERGENID1.KEYSPEC=2048
       
      # CA Connector: EjbcaWS (using EJBCA through Web Services)
      WORKERGENID1.CACONNECTOR_IMPLEMENTATION=org.signserver.module.onetime.caconnector.EjbcaWSCAConnector
      WORKERGENID1.TRUSTSTORETYPE=JKS
       
      # To trust the TLS certificate of the CA the trust store properties must be configured and contain the issuer (i.e. CA) certificate that issued the TLS server certificate used when connecting to the CA
      WORKERGENID1.TRUSTSTOREPATH=/opt/jboss-eap-6.4-ca/standalone/configuration/keystore/truststore.jks
      WORKERGENID1.TRUSTSTOREPASSWORD=changeit
       
      WORKERGENID1.TLSCLIENTKEY=tls_key
      WORKERGENID1.EJBCAWSURL=https://localhost:9443/ejbca
      WORKERGENID1.ENDENTITYPROFILE=EMPTY
      WORKERGENID1.CERTIFICATEPROFILE=ENDUSER
      WORKERGENID1.USERNAME_PATTERN=onetime-${transactionId}
      WORKERGENID1.SUBJECTDN_PATTERN=CN=User ${username},UID=${transactionId},O=SignServer Testing,C=SE
       
      # CSR & Certificate Signing
      WORKERGENID1.CERTSIGNATUREALGORITHM=SHA256WithRSA
    2. To trust the TLS certificate of the CA, the truststore properties must be configured and contain the issuer (i.e. CA) certificate that issued the TLS server certificate used when connecting to the CA. In some cases you can just point out the path to the truststore.jks from the application server where EJBCA is running.

    3. Create a TLS client key (tls_key).

    4. Generate a Certificate Signing Request (CSR) for the TLS key created in the step above, get the certificate for the CSR, and install the certificate for the key in the token.

    5. Provide Administrator access for the TLS Client certificate under the EJBCA CA Administration section, to enable the TLS client to access the CA resource (Web Service).

    6. Check that the status of the worker is ACTIVE, either on the SignServer Admin Web Worker Status page, or in the CLI using using the command: ./bin/signserver getstatus brief.

    Step 3: Set Up Signer with One-time Key

    Configure a signer (for example the XAdESSigner) to use the following properties of your newly created CryptoWorker.

    Since the user credentials are used in the certificate issuance, the signer needs to use a username or username/password authorizer, see OneTimeCryptoWorker.

    Property

    Change

    CRYPTOTOKEN

    CryptoTokenP11OneTimeSelfSigned
    or
    CryptoTokenP11OneTimeEjbcaWS

    AUTHTYPE

    org.signserver.server.UsernameAuthorizer

    ACCEPT_ALL_USERNAMES

    true

    ALIASSELECTOR

    org.signserver.server.aliasselectors.AuthorizedUsernameAliasSelector

    Example Configuration Sample

    The following shows a sample configuration xadessigner.properties for a CryptoTokenP11OneTimeEjbcaWS:

    Sample XAdESSigner Configuration with One-time Key
    # General properties
    WORKERGENID1.TYPE=PROCESSABLE
    WORKERGENID1.IMPLEMENTATION_CLASS=org.signserver.module.xades.signer.XAdESSigner
    WORKERGENID1.NAME=XAdESSigner
    # Crypto token
    WORKERGENID1.CRYPTOTOKEN=CryptoTokenP11OneTimeEjbcaWS
    # Using one key-pair in the above crypto token
    WORKERGENID1.DEFAULTKEY=tls_key
     
    # Properties related to User Authentication & Alias selector as username will be part of Subject DN and Alias selector will be used to select key alias based on logged user name.
    WORKERGENID1.AUTHTYPE=org.signserver.server.UsernameAuthorizer
    WORKERGENID1.ACCEPT_ALL_USERNAMES=true
    WORKERGENID1.ALIASSELECTOR=org.signserver.server.aliasselectors.AuthorizedUsernameAliasSelector
    WORKERGENID1.SIGNATUREALGORITHM=SHA256withRSA
     
    WORKERGENID1.XADESFORM = BES
    WORKERGENID1.INCLUDE_CERTIFICATE_LEVELS=1
    WORKERGENID1.COMMITMENT_TYPES = NONE

    Step 4: Test and Verify Signing with One-time Keys

    You can now test to sign using SignClient or test the performance using the stresstest tool.

    Test Signing with SignClient

    To test signing using the SignServer CLI SignClient, run the following:

    bin/signclient signdocument -workername XAdESSigner -data "<xml/>" -username user1 -password password
     
    bin/signclient signdocument -workername CMSSigner -infile "input.txt" -username user1 -password password -outfile "output.p7s"
     
    bin/signclient signdocument -workername JArchiveSigner -infile "HelloJar.jar" -username user1 -password password -outfile "HelloSignedJar.jar"

    Note that a new certificate with a new key is used every time.

    Signature Verification

    • To verify the CMS Signature through OpenSSL, run the following:

      openssl cms -verify -in output.p7s -inform DER -content input.txt -CAfile cacert.pem > /dev/null
    • To verify the code signature with jarsigner, run the following:

      jarsigner -verify -strict HelloJar_Signed.jar -certs

    Performance Test using Stresstest Tool

    To run a performance test using the stresstest tool, run the following:

    bin/stresstest -testsuite DocumentSigner1 -threads 20 -processurl http://localhost:8080/signserver/process -worker XAdESSigner -data "<root/>" -userprefix user -usersuffixmin 1 -usersuffixmax 500

    To prevent memory leaks when generating a high number of keys, do not enable the crypto token caching (cryptotoken.keystorecache) in conf/cesecore.properties.

    For more information on using the stresstest tool, see Stresstest CLI.