ECC Specifics
ECC policies give equivalent or stronger security than the RSA-based profiles with much shorter key lengths, which makes them well suited for resource-constrained and modern deployments. This page documents only the ECC-specific configuration. For the general picture read Security first.
Supported curves
Each row corresponds to one SecurityPolicy. The presence of a check mark means that backend can register the policy given a matching certificate and private key.
OPC UA Policy |
Curve |
OpenSSL |
mbedTLS ≥ 3.0 |
|---|---|---|---|
|
NIST P-256 (prime256v1) |
✓ |
✓ |
|
NIST P-384 (secp384r1) |
✓ |
✓ |
|
Brainpool P-256r1 |
✓ |
✓ |
|
Brainpool P-384r1 |
✓ |
✓ |
|
Curve25519 (Ed25519) |
✓ |
✗ |
|
Curve448 (Ed448) |
✓ |
✗ |
Curve25519 and Curve448 require OpenSSL ≥ 3.0. The NIST and Brainpool curves require mbedTLS ≥ 3.0 or OpenSSL ≥ 3.0. See Crypto Backends for the build flags.
Certificate requirements
Each ECC policy requires its own certificate and private key, and the key must match the curve. A single certificate cannot be shared across different curves. RSA and ECC policies can coexist on the same server. Each carries its own key pair.
X.509 extensions to set when creating an ECC certificate:
Key Usage –
keyAgreementis required (for ECDH key exchange). The recommended set for ECDSA curves is:digitalSignature, nonRepudiation, keyAgreement, keyCertSign
RSA certificates use
keyEnciphermentinstead.SubjectAltName – must include at least
URI:<ApplicationUri>andDNS:<hostname>(orIP:...).
Generating ECC certificates
There are three ways to obtain an ECC certificate for use with open62541.
1. ``UA_CreateCertificate`` (built-in, recommended for development)
Pass key-type = "EC" and the desired ecc-curve value in the
key-value map. Supported curves: prime256v1, secp384r1,
brainpoolP256r1, brainpoolP384r1, ed25519, ed448 (last
two require OpenSSL).
UA_KeyValueMap *kvm = UA_KeyValueMap_new();
UA_UInt16 expiresIn = 365;
UA_KeyValueMap_setScalar(kvm, UA_QUALIFIEDNAME(0, "expires-in-days"),
&expiresIn, &UA_TYPES[UA_TYPES_UINT16]);
UA_String keyType = UA_STRING_STATIC("EC");
UA_KeyValueMap_setScalar(kvm, UA_QUALIFIEDNAME(0, "key-type"),
&keyType, &UA_TYPES[UA_TYPES_STRING]);
UA_String curve = UA_STRING_STATIC("prime256v1");
UA_KeyValueMap_setScalar(kvm, UA_QUALIFIEDNAME(0, "ecc-curve"),
&curve, &UA_TYPES[UA_TYPES_STRING]);
UA_ByteString privateKey = UA_BYTESTRING_NULL;
UA_ByteString certificate = UA_BYTESTRING_NULL;
UA_CreateCertificate(UA_Log_Stdout, subject, lenSubject,
subjectAltName, lenSubjectAltName,
UA_CERTIFICATEFORMAT_DER, kvm,
&privateKey, &certificate);
UA_KeyValueMap_delete(kvm);
2. OpenSSL CLI (production, full control)
ECDSA curves (P-256, P-384, Brainpool):
openssl ecparam -name prime256v1 -genkey -noout -out server_nistP256.key.pem
openssl req -new -x509 -key server_nistP256.key.pem \
-out server_nistP256.cert.pem -days 3650 -sha256 \
-subj "/C=DE/O=MyOrg/CN=OPC-UA-Server" \
-addext "subjectAltName=URI:urn:my.app:server,DNS:localhost,IP:127.0.0.1" \
-addext "basicConstraints=critical,CA:FALSE" \
-addext "keyUsage=critical,digitalSignature,nonRepudiation,keyAgreement" \
-addext "extendedKeyUsage=serverAuth,clientAuth"
openssl x509 -in server_nistP256.cert.pem -outform DER -out server_nistP256.cert.der
openssl pkey -in server_nistP256.key.pem -outform DER -out server_nistP256.key.der
Use -sha384 and prime256v1 replaced with secp384r1 or
brainpoolP256r1 / brainpoolP384r1 accordingly.
EdDSA curves (Curve25519, Curve448):
openssl genpkey -algorithm ed25519 -out server_curve25519.key.pem
openssl req -new -x509 -key server_curve25519.key.pem \
-out server_curve25519.cert.pem -days 3650 \
-subj "/C=DE/O=MyOrg/CN=OPC-UA-Server" \
-addext "subjectAltName=URI:urn:my.app:server,DNS:localhost,IP:127.0.0.1" \
-addext "basicConstraints=critical,CA:FALSE" \
-addext "keyUsage=critical,digitalSignature,nonRepudiation,keyAgreement" \
-addext "extendedKeyUsage=serverAuth,clientAuth"
openssl x509 -in server_curve25519.cert.pem -outform DER -out server_curve25519.cert.der
openssl pkey -in server_curve25519.key.pem -outform DER -out server_curve25519.key.der
Replace ed25519 with ed448 for Curve448.
3. ``tools/certs/create_self-signed.py`` (development helper)
# Single ECC certificate
python3 tools/certs/create_self-signed.py /tmp/certs --ecc prime256v1
# All supported ECC curves at once
python3 tools/certs/create_self-signed.py /tmp/certs --ecc-all
The --ecc-all mode produces DER files named
server_c_<curve>.cert.der / server_c_<curve>.key.der ready for
--ecc-cert-dir.