ASA

Cisco ASA Certificate Management for AnyConnect

Cisco ASA Certificate Management for AnyConnect
In: ASA

Certificates on a Cisco ASA serving AnyConnect (Cisco Secure Client) traffic do two related but distinct jobs. First, the ASA presents an identity certificate to the client during the TLS or IKEv2 handshake; the client validates that cert before sending the user's password or session token. Second, optionally, the ASA can require the client to present its own certificate, enabling certificate-based user authentication (no password) or two-factor login (cert + password). Get either side wrong and the connection fails in different and confusing ways. This article walks the full certificate lifecycle on Cisco ASA 9.x: identity cert generation, CA enrollment, client certificate authentication, and verification commands. All output is from a live ASAv 9.23(1) in the PingLabz ASA reference lab.

If you do not yet have an AnyConnect connection profile, start with Cisco ASA AnyConnect SSL VPN Configuration. The certificate setup here drops into the existing trustpoint reference in your tunnel-group / SSL config.

The Trustpoint Concept

Every certificate on the ASA lives inside a trustpoint. A trustpoint binds together:

  • A keypair (RSA or EC).
  • An enrollment method (self, terminal, or URL to a CA).
  • A subject name and FQDN.
  • A CA chain (the issuing CA's cert plus any intermediate CAs).

Trustpoints are referenced everywhere certs are used: ssl trust-point NAME outside binds the trustpoint to the SSL listener; tunnel-group ... ipsec-attributes / ikev2 local-authentication certificate NAME binds it to the IKEv2 listener; crypto ca authenticate NAME imports the CA chain.

Three Common Certificate Paths

PathUse whenTrade-off
Self-signed identity certLab, proof-of-concept, internal-only deployments where every client trusts the ASA cert manually.Clients warn on first connect; cert pinning is brittle.
Enterprise CA (Microsoft AD CS, OpenSSL, etc.)Internal corp deployments with managed clients that have the enterprise root pre-installed.One-time CA bootstrap on the ASA; rotation is easy via SCEP.
Public CA (DigiCert, Sectigo, Let's Encrypt)Production deployments with mixed managed and BYOD clients.Requires public DNS for the gateway FQDN and an annual cost (Let's Encrypt is free but 90-day rotation).

Step 1: Generate a Keypair

Always create a named keypair before the trustpoint. Naming it makes rotation cleaner; you can spin up a new keypair without touching the old one.

ASA-PERIM(config)# domain-name pinglabz.lab
ASA-PERIM(config)# crypto key generate rsa label PINGLABZ-RSA modulus 2048 noconfirm
Keypair generation process begin. Please wait...
The RSA keypairs were successfully generated.

2048-bit RSA is the modern minimum. 4096-bit is overkill and costs handshake CPU. EC keys (group 19 = P-256, group 20 = P-384) give equivalent security with smaller signatures and faster handshakes:

ASA-PERIM(config)# crypto key generate ecdsa label PINGLABZ-EC elliptic-curve 256 noconfirm

Most production deployments use RSA-2048 because client and CA support is universal. EC keys can fail intermittently against older intermediate CAs.

Step 2a: Self-Signed Identity Cert

The fastest way to bring up a working ASA cert. Use only for lab or for "buy us a few days while a real cert is procured."

ASA-PERIM(config)# crypto ca trustpoint PINGLABZ-SELFSIGNED
ASA-PERIM(config-ca-trustpoint)#  enrollment self
ASA-PERIM(config-ca-trustpoint)#  fqdn vpn.pinglabz.lab
ASA-PERIM(config-ca-trustpoint)#  subject-name CN=vpn.pinglabz.lab,O=PingLabz,C=US
ASA-PERIM(config-ca-trustpoint)#  keypair PINGLABZ-RSA
ASA-PERIM(config-ca-trustpoint)#  exit
ASA-PERIM(config)# crypto ca enroll PINGLABZ-SELFSIGNED noconfirm
% The fully-qualified domain name in the certificate will be: vpn.pinglabz.lab

The cert is generated in-place; no external CA is contacted. Default validity is 10 years for self-signed. Bind it to the outside SSL listener:

ASA-PERIM(config)# ssl trust-point PINGLABZ-SELFSIGNED outside

Verify:

ASA-PERIM# show crypto ca certificates
...
Certificate
  Status: Available
  Certificate Serial Number: 69ffc240
  Certificate Usage: General Purpose
  Public Key Type: RSA (2048 bits)
  Signature Algorithm: RSA-SHA256
  Issuer Name:
    unstructuredName=vpn.pinglabz.lab
    C=US
    O=PingLabz
    CN=vpn.pinglabz.lab
  Subject Name:
    unstructuredName=vpn.pinglabz.lab
    C=US
    O=PingLabz
    CN=vpn.pinglabz.lab
  Validity Date:
    start date: 00:37:39 UTC May 10 2026
    end   date: 00:37:39 UTC May 7 2036
  Storage: config
  Associated Trustpoints: PINGLABZ-SELFSIGNED

Self-signed: issuer == subject. Validity ten years. Stored in startup-config so it survives reboots.

Step 2b: CA-Signed Identity Cert

The production path. Three sub-steps: generate CSR, get it signed, import the result.

Generate the CSR

ASA-PERIM(config)# crypto ca trustpoint PINGLABZ-CA-SIGNED
ASA-PERIM(config-ca-trustpoint)#  enrollment terminal
ASA-PERIM(config-ca-trustpoint)#  fqdn vpn.pinglabz.com
ASA-PERIM(config-ca-trustpoint)#  subject-name CN=vpn.pinglabz.com,O=PingLabz,C=US
ASA-PERIM(config-ca-trustpoint)#  keypair PINGLABZ-RSA
ASA-PERIM(config-ca-trustpoint)#  exit
ASA-PERIM(config)# crypto ca enroll PINGLABZ-CA-SIGNED
% Start certificate enrollment ..
% The subject name in the certificate will be: CN=vpn.pinglabz.com,O=PingLabz,C=US
% The fully-qualified domain name in the certificate will be: vpn.pinglabz.com
% Include the device serial number in the subject name? [yes/no]: no

Display Certificate Request to terminal? [yes/no]: yes
-----BEGIN CERTIFICATE REQUEST-----
MIICnzCCAYcCAQAwOjEZMBcGA1UEAwwQdnBuLnBpbmdsYWJ6LmNvbTERMA8GA1UE
... (truncated)
-----END CERTIFICATE REQUEST-----

Copy that CSR into your CA's signing workflow. For Microsoft AD CS, paste it into Request a certificate > advanced certificate request. For Let's Encrypt or a public CA, use their signing portal or DNS-01 / HTTP-01 verification flow.

Import the Issued Cert

Once you have the signed cert PEM, import the issuing CA chain first, then the identity cert:

ASA-PERIM(config)# crypto ca authenticate PINGLABZ-CA-SIGNED
Enter the base 64 encoded CA certificate.
End with the word "quit" on a line by itself
-----BEGIN CERTIFICATE-----
... (paste CA cert PEM)
-----END CERTIFICATE-----
quit
INFO: Certificate has the following attributes:
Fingerprint: ...
Do you accept this certificate? [yes/no]: yes
Trustpoint 'PINGLABZ-CA-SIGNED' is a subordinate CA and holds a non self-signed certificate.
Trustpoint CA certificate accepted.

ASA-PERIM(config)# crypto ca import PINGLABZ-CA-SIGNED certificate
% The fully-qualified domain name in the certificate will be: vpn.pinglabz.com
Enter the base 64 encoded certificate.
End with the word "quit" on a line by itself
-----BEGIN CERTIFICATE-----
... (paste signed identity cert PEM)
-----END CERTIFICATE-----
quit
INFO: Certificate successfully imported

Then bind the trustpoint to the SSL listener and any IKEv2 listener:

ASA-PERIM(config)# ssl trust-point PINGLABZ-CA-SIGNED outside
ASA-PERIM(config)# crypto ikev2 remote-access trustpoint PINGLABZ-CA-SIGNED

Step 3: Client Certificate Authentication (Optional)

To require clients to present their own cert, you need:

  1. A trustpoint holding the client-issuing CA's cert (so the ASA can validate client certs).
  2. A tunnel-group ... general-attributes setting telling the connection profile to demand a client cert.
  3. A certificate-group-map mapping client cert attributes to a tunnel-group.
ASA-PERIM(config)# crypto ca trustpoint CLIENT-CA
ASA-PERIM(config-ca-trustpoint)#  enrollment terminal
ASA-PERIM(config-ca-trustpoint)#  exit
ASA-PERIM(config)# crypto ca authenticate CLIENT-CA
... (paste client-issuing CA cert)

ASA-PERIM(config)# tunnel-group SSL_PROFILE general-attributes
ASA-PERIM(config-tunnel-general)#  authentication certificate

For "cert AND password" two-factor authentication, change to authentication aaa certificate:

ASA-PERIM(config-tunnel-general)#  authentication aaa certificate

To map specific cert attributes (issuer, subject, OU) to a tunnel-group, use a certificate-map:

ASA-PERIM(config)# crypto ca certificate map CONTRACTOR-MAP 10
ASA-PERIM(config-ca-cert-map)#  subject-name attr ou eq Contractors
ASA-PERIM(config-ca-cert-map)#  exit
ASA-PERIM(config)# tunnel-group-map enable rules
ASA-PERIM(config)# tunnel-group-map CONTRACTOR-MAP 10 CONTRACTOR_PROFILE

This says: any client whose cert subject contains "OU=Contractors" lands on the CONTRACTOR_PROFILE tunnel-group, even if they hit the default group-url.

Certificate Rotation

When the identity cert is approaching expiry:

  1. Generate a new keypair under a new label (PINGLABZ-RSA-2027).
  2. Create a new trustpoint that references the new keypair.
  3. Generate a new CSR and have the CA sign it.
  4. Import the new cert into the new trustpoint.
  5. Cut over the SSL listener: ssl trust-point PINGLABZ-CA-SIGNED-2027 outside.
  6. Confirm the new cert is being served (browser inspect, or show ssl).
  7. After a grace period for any clients with the old cert pinned, delete the old trustpoint.

Doing this on a different trustpoint name lets you rollback by re-binding to the old trustpoint, which is critical if the new cert has a problem you didn't catch in pre-prod.

Multiple SSL Trustpoints with SNI

An ASA can present different certs to different clients based on the requested hostname (SNI / Server Name Indication). Bind multiple trustpoints to the same interface, each with a domain-name reference:

ASA-PERIM(config)# ssl trust-point PINGLABZ-CA-SIGNED outside
ASA-PERIM(config)# ssl trust-point PARTNER-CA-SIGNED outside domain partner.pinglabz.com

Now clients hitting vpn.pinglabz.com get the corp cert; clients hitting partner.pinglabz.com get the partner cert. Each domain can have its own tunnel-group via group-url.

Verification Commands

CommandUse
show crypto ca certificatesList all certs in all trustpoints with their dates, key sizes, and trustpoint binding.
show crypto ca trustpointsList trustpoints, their enrollment URL, and which keypair they reference.
show sslSSL/TLS settings + which trustpoint is bound to which interface.
show ssl certificateThe cert currently being served on each SSL listener.
show crypto key mypubkey rsaList RSA keypairs by label, their bit length, and the trustpoint(s) referencing them.
debug crypto caVerbose CA enrollment / authentication tracing. Use during initial bring-up only.

Common Gotchas

  1. FQDN mismatch. The cert's CN or SAN must match the FQDN clients connect to. AnyConnect rejects mismatched certs by default; users see a "certificate validation failure" error.
  2. Missing CA chain on the ASA. When importing a CA-signed cert, you must first authenticate the issuing CA and any intermediate CAs. A missing intermediate produces clients seeing an "unknown issuer" warning even though the root is in their trust store.
  3. Trustpoint not bound to the interface. A trustpoint exists with a perfectly fine cert, but ssl trust-point ... outside still references the old trustpoint. Cert is generated but never served. Fix by reading show ssl output.
  4. Self-signed cert in production. AnyConnect 4.10+ enforces stricter cert validation; users with self-signed certs see warnings on every connect, and modern macOS / Windows builds may simply refuse. Use a real CA-signed cert in production.
  5. Time skew. If the ASA's clock is off (no NTP), the cert validity check at handshake time can fail. Always run NTP. show clock should match real time.

Key Takeaways

ASA certificates live in trustpoints. The trustpoint binds keypair + CA chain + identity cert + subject. Self-signed for lab; CA-signed for production via enrollment terminal CSR flow or SCEP. Bind the trustpoint to the SSL listener (ssl trust-point) and the IKEv2 remote-access listener (crypto ikev2 remote-access trustpoint). For client-cert authentication, add authentication certificate in the tunnel-group and import the client-issuing CA. Always pre-stage cert rotation on a new trustpoint name so rollback is one command away.

For the full Cisco ASA reference, including site-to-site IPsec, NAT, ACLs, failover, and the troubleshooting tools, see the Cisco ASA pillar. For the connection-profile foundation, return to Cisco ASA AnyConnect SSL VPN Configuration; for cert-related troubleshooting, see Troubleshoot AnyConnect Login and Certificate Problems on ASA.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.