All SecurityProtocols shall implement the OpenSecureChannel and CloseSecureChannel services defined in OPC 10000-4. These Services specify how to establish a SecureChannel and how to apply security to Messages exchanged over that SecureChannel. The Messages exchanged and the security algorithms applied to them are shown in Figure 10.

SecurityProtocols shall support three SecurityModes: None, Sign and SignAndEncrypt. If the SecurityMode is None then no security is used and the security handshake shown in Figure 10 is not required. However, a SecurityProtocol implementation shall still maintain a logical channel and provide a unique identifier for the SecureChannel. The handshake shown also applies when using Session-less Service invocations, however the CreateSession steps are omitted.

image013.png

Figure 10 – Security handshake when Creating a Session

Each SecurityProtocol mapping specifies exactly how to apply the security algorithms to the Message. A set of security algorithms that shall be used together during a security handshake is called a SecurityPolicy. OPC 10000-7 defines standard SecurityPolicies as parts of the standard Profiles which OPC UA applications are expected to support. OPC 10000-7 also defines a URI for each standard SecurityPolicy. The latest versions of all SecurityPolicies are available in the online Profiles website. OPC 10000-7 defines the link to this website.

A Stack is expected to have built in knowledge of the SecurityPolicies that it supports. Applications specify the SecurityPolicy they wish to use by passing the URI to the Stack.

Table 45 defines the contents of a SecurityPolicy. Each SecurityProtocol mapping specifies how to use each of the parameters in the SecurityPolicy. A SecurityProtocol mapping may not make use of all of the parameters.

Table 45 – SecurityPolicy

Name

Description

PolicyUri

The URI assigned to the SecurityPolicy.

SymmetricSignatureAlgorithm

The symmetric signature algorithm to use.

SymmetricEncryptionAlgorithm

The symmetric encryption algorithm to use.

AsymmetricSignatureAlgorithm

The asymmetric signature algorithm to use.

AsymmetricEncryptionAlgorithm

The asymmetric encryption algorithm to use.

MinAsymmetricKeyLength

The minimum length, in bits, for an asymmetric key.

MaxAsymmetricKeyLength

The maximum length, in bits, for an asymmetric key.

KeyDerivationAlgorithm

The key derivation algorithm to use.

DerivedSignatureKeyLength

The length in bits of the derived key used for Message authentication.

CertificateSignatureAlgorithm

The asymmetric signature algorithm used to sign certificates.

CertificateKeyAlgorithm

The algorithm used to create asymmetric key pairs used with Certificates.

EphemeralKeyAlgorithm

The algorithm used to create asymmetric key pairs used for EphemeralKeys.

SecureChannelNonceLength

The length, in bytes, of the Nonces used when opening a SecureChannel.

IntializationVectorLength

The length, in bits, of the data used to initialize the symmetric algorithm.

SymmetricSignatureLength

The length, in bits, of the symmetric signature.

LegacySequenceNumbers

If TRUE, the 1 024 based SequenceNumber rules apply to the SecurityPolicy;

If FALSE, the 0 based SequenceNumber rules apply. See 6.7.2.4.

The KeyDerivationAlgorithm is used to create the keys used to secure Messages sent over the SecureChannel. The length of the keys used for encryption is implied by the SymmetricEncryptionAlgorithm. The length of the keys used for creating Signatures is specified by the DerivedSignatureKeyLength.

The MinAsymmetricKeyLength and MaxAsymmetricKeyLength are constraints that apply to all Certificates (including Issuers in the chain). In addition, the key length of issued Certificates shall be less than or equal to the key length of the issuer Certificate. See 6.2.6 for information on Certificate chains.

The CertificateKeyAlgorithm and EphemeralKeyAlgorithm are used to generate new asymmetric key pairs used with Certificates and during the SecureChannel handshake. OPC 10000-7 specifies the algorithms that need to be supported for each SecurityPolicy.

The CertificateSignatureAlgorithm applies the Certificate and all Issuer Certificates. If a CertificateSignatureAlgorithm allows for more than one algorithm then the algorithms are listed in order of increasing priority. Each Issuer in a chain shall have an algorithm that is the same or higher priority than any Certificate it issues.

The SecureChannelNonceLength specifies the length of the Nonces exchanged when establishing a SecureChannel (see 6.7.4).

Certificates are digitally signed data structures that contain a Public Key and the identity of a OPC UA Application. All SecurityProtocols use X.509 v3 Certificates (see X.509 v3) encoded using the DER format (see X690). Certificates used by OPC UA applications shall also conform to RFC 5280 which defines a profile for X.509 v3 Certificates when they are used as part of an Internet based application.

The ServerCertificate and ClientCertificate parameters used in the abstract OpenSecureChannel service are instances of the ApplicationInstance Certificate DataType. Clause 6.2.2 describes how to create an X.509 v3 Certificate that can be used as an ApplicationInstance Certificate.

Certificates are also used as form of UserIdentityToken which identifies a user associated with a Session. Clause 6.2.3 describes Certificates used as UserIdentityTokens.

An Application Instance Certificate is a ByteString containing the DER encoded form (see X690) of an X.509 v3 Certificate. This Certificate is issued by certifying authority and identifies an instance of an application running on a single host. The X.509 v3 fields contained in an Application Instance Certificate are described in Table 46. The fields are defined completely in RFC 5280.

Table 46 also provides a mapping from the RFC 5280 terms to the terms used in the abstract definition of an Application Instance Certificate defined in OPC 10000-4.

Table 46 – Application Instance Certificate

Name

OPC 10000-4 Parameter Name

Description

Application Instance Certificate

An X.509 v3 Certificate.

version

version

shall be “V3”

serialNumber

serialNumber

The serial number assigned by the issuer.

signatureAlgorithm

signatureAlgorithm

The algorithm used to sign the Certificate.

signature

signature

The signature created by the Issuer.

issuer

issuer

The distinguished name of the Certificate used to create the signature.

The issuer field is completely described in RFC 5280.

validity

validTo, validFrom

When the Certificate becomes valid and when it expires.

subject

subject

The distinguished name of the application Instance.

The Common Name attribute shall be specified and should be the productName or a suitable equivalent. The Organization Name attribute shall be the name of the Organization that executes the application instance. This organization is usually not the vendor of the application.

Other attributes may be specified.

The subject field is completely described in RFC 5280.

subjectAltName

applicationUri,

hostnames

The alternate names for the application Instance.

Shall include a uniformResourceIdentifier which is equal to the applicationUri. The URI shall be a valid URL (see RFC 3986) or a valid URN (see RFC 8141).

Servers shall specify a partial or a fully qualified dNSName or a static IPAddress which identifies the machine where the application Instance runs. Additional dNSNames may be specified if the machine has multiple names.

The subjectAltName field is completely described in RFC 5280.

publicKey

publicKey

The public key associated with the Certificate.

keyUsage

keyUsage

Specifies how the Certificate key may be used.

For RSA keys, the keyUsage shall include digitalSignature, nonRepudiation, keyEncipherment and dataEncipherment.For ECC keys, the keyUsage shall include digitalSignature.Other keyUsage bits are allowed but not recommended.

Self-signed Certificates shall also include keyCertSign.

extendedKeyUsage

keyUsage

Specifies additional limits on how the Certificate key may be used.

For RSA profiles, the extendedKeyUsage shall specify serverAuth for Servers and shall specify clientAuth for Clients. The extendedKeyUsage should also specify clientAuth for Servers.

For ECC profiles, serverAuth and clientAuth are optional.

Other extendedKeyUsage bits are allowed.

authorityKeyIdentifier

(No mapping)

Provides more information about the key used to sign the Certificate. It shall be specified for Certificates signed by a CA. It should be specified for self-signed Certificates.

basicConstraints

(No mapping)

The basicConstraints field is completely described in RFC 5280.

The cA flag Identifies whether the subject of the Certificate is a CA The pathLength specifies the maximum number of intermediate CAs in valid chains that follow this Certificate.

The basicConstraints extension shall be present and shall not be ignored. The extension shall be validated and marking the extension as critical has no effect. For backward interoperability, any error related to the critical mark produced by software libraries shall be suppressed and logged as a warning.

The cA flag shall be FALSE for any ApplicationInstance Certificate, however, TRUE shall be accepted to ensure backward interoperability when validating ApplicationInstance Certificates, if revocation checks are enabled. If revocation checks are disabled then a Certificate with the cA flag set to TRUE should not be accepted. It should be possible to disable backward interoperability in configuration.

If the cA flag is TRUE for a self-signed ApplicationInstance Certificate, then the pathLength should be 0.

If an application accepts an ApplicationInstance Certificate with cA flag set to TRUE, it shall write a warning to the log.

A User Certificate is a Certificate is issued by certifying authority and identifies a user.

The X.509 v3 fields in a User Certificates with specific requirements are shown in Table 47.

Table 47 – User Certificate

Field

Description

subject

The distinguished name of the User.

The Common Name attribute shall be specified and should be name of the user. The Organization should be provided.

Other attributes may be specified.

The subject field is completely described in RFC 5280.

authorityKeyIdentifier

Provides more information about the key used to sign the Certificate. It shall be specified.

basicConstraints

The basicConstraints field is completely described in RFC 5280.

The cA flag Identifies whether the subject of the Certificate is a CA The pathLength specifies the maximum depth of valid chains that include this Certificate.

The cA flag shall be FALSE for User Certificates.

The pathLength shall not be present.

An Issuer or CA Certificate is an X.509 v3 Certificate that identifies an authority that issues Certificates. An Issuer Certificate may identify a root CA or an intermediate CA. Certificates that identify root CAs are self-signed Certificates. Certificates that identify intermediate CAs are issued by authority identified by an intermediate CA or root CA.

The X.509 v3 fields in Issuer Certificates with specific requirements are shown in Table 48.

Table 48 – Issuer Certificate

Field

Description

subject

The distinguished name of for the authority.

The Common Name attribute shall be specified.

The Organization should be provided.

Other attributes may be specified.

The subject field is completely described in RFC 5280.

authorityKeyIdentifier

Provides more information about the key used to sign the Certificate. It shall be specified.

basicConstraints

The basicConstraints field is completely described in RFC 5280.

The cA flag Identifies whether the subject of the Certificate is a CA The pathLength specifies the maximum depth of valid chains that include this Certificate.

The cA flag shall be TRUE for CA Certificates.

A Certificate Revocation List (CRL) is a ByteString containing the DER encoded form (see X690) of an X.509 v3 CRL. The CRL is issued by certifying authority and contains the serial numbers of the Certificates issued by that authority which are no longer valid. All CRLs shall have the extension defined in Table 46. The extension is defined completely in RFC 5280.

Table 49 – Certificate Revocation List Extensions

Extension

Description

authorityKeyIdentifier

Provides more information about the key used to sign the CRL.

Any X.509 v3 Certificate may be signed by CA which means that validating the signature requires access to the X.509 v3 Certificate belonging to the signing CA. Whenever an application validates a Certificate (see OPC 10000-4) it shall recursively build a chain of Certificates by finding the issuer Certificate, validating the Certificate and then repeat the process for the issuer Certificate. The chain ends with a self-signed Certificate.

The number of CAs used in a system should be small so it is common to install the necessary CAs on each machine with an OPC UA application. However, applications have the option of including a partial or complete chain whenever they pass a Certificate. This includes GetEndpoints, SecureChannel negotiation and during the CreateSession/ActivateSession handshake.

All OPC UA applications shall accept partial or complete chains in any field that contains a DER encoded Certificate.

Chains are stored in a ByteString by simply appending the DER encoded form of the Certificates. The first Certificate shall be the end Certificate followed by its issuer. If the root CA is sent as part of the chain, it is last Certificate appended to the ByteString.

Chains are parsed by extracting the length of each Certificate from the DER encoding. For Certificates with lengths less than 65 535 bytes it is an MSB encoded UInt16 starting at the 3rd byte.

All SecurityProtocols require that system clocks on communicating machines be reasonably synchronized in order to check the expiry times for Certificates or CRLs. In addition, incorrect Timestamps on Data and Events could create interoperability issues.

The Network Time Protocol (NTP) provides a standard way to synchronize a machine clock with a time server on the network. Systems running on a machine with a full featured operating system like Windows or Linux will already support NTP or an equivalent. Devices running embedded operating systems should support NTP.

If a device operating system cannot practically support NTP then an OPC UA application can use the Timestamps in the ResponseHeader (see OPC 10000-4) to synchronize its clock. In this scenario, the OPC UA application will have to know the URL for a Discovery Server on a machine known to have the correct time. The OPC UA application or a separate background utility would call the FindServers Service and set its clock to the time specified in the ResponseHeader. This process will need to be repeated periodically because clocks can drift over time.

Applications should log possible time synchronization errors. For example, Certificates or CRLs with ValidFrom times in the future could indicate a time synchronization issue.

All times in OPC UA are in UTC, however, UTC can include discontinuities due to leap seconds or repeating seconds added to deal with variations in the earth’s orbit and rotation. For this reason, some Servers will use International Atomic Time (TAI) for internal calculations. These Servers shall convert DateTime values to UTC before exchanging them with other applications.

Note: Deprecated in Version 1.05.

JSON Web Token (JWT) UserIdentityTokens can be passed to the Server using the IssuedIdentityToken. The body of the token is a string that contains the JWT as defined in RFC 8259.

Servers that support JWT authentication shall provide a UserTokenPolicy which specifies the Authorization Service which provides the token and the parameters needed to access that service. The parameters are specified by a JSON object specified as the issuerEndpointUrl. The contents of this JSON object are described in Table 51. The general UserTokenPolicy settings for JWT are defined in Table 50.

Table 50 – JWT UserTokenPolicy

Name

Description

tokenType

ISSUEDTOKEN_3

issuedTokenType

http://opcfoundation.org/UA/UserToken#JWT

issuerEndpointUrl

For JWTs this is a JSON object with fields defined in Table 51.

Table 51 – JWT IssuerEndpointUrl Definition

Name

Type

Description

IssuerEndpointUrl

JSON object

Specifies the parameters for a JWT UserIdentityToken.

ua:resourceId

String

The URI identifying the Server to the Authorization Service.

If not specified, the Server’s ApplicationUri is used.

ua:authorityUrl

String

The base URL for the Authorization Service.

This URL may be used to discover additional information about the authority.

This field is equivalent to the “issuer” defined in OpenID-Discovery.

ua:authorityProfileUri

String

The profile that defines the interactions with the authority.

If not specified, the URI is “http://opcfoundation.org/UA/Authorization#OAuth2”.

A set of possible authorities are in the Profile: http://opcfoundation.org/UA-Profile/Security/UserToken/Server/JsonWebToken

ua:tokenEndpoint

String

A path relative to the base URL used to request Access Tokens.

This field is equivalent to the “token_endpoint” defined in OpenID-Discovery.

ua:authorizationEndpoint

String

A path relative to the base URL used to validate user credentials.

This field is equivalent to the “authorization_endpoint” defined in OpenID-Discovery.

ua:requestTypes

JSON array

String

The list of request types supported by the authority.

The possible values are described in 6.5.3.3 to 6.5.3.5.

If not specifed the default is “authorization_code”.

ua:scopes

JSON array

String

A list of Scopes that are understood by the Server.

If not specified, the Client may be able to access any Scope supported by the Authorization Service.

This field is equivalent to the “scopes_supported” defined in OpenID-Discovery.

The OAuth2 Authorization Framework (see RFC 5392) provides a web based mechanism to request claims based Access Tokens from an Authorization Service (AS) that is supported by many major companies providing cloud infrastructure. These Access Tokens are passed to a Server by a Client in a UserIdentityToken as described in OPC 10000-4.

The OpenID Connect specification (see OpenID) builds on the OAuth2 specification by defining the contents of the Access Tokens more strictly.

The OAuth2 specification supports a number of use cases (called ‘flows’) to handle different application requirements. The use cases that are relevant to OPC UA are discussed below.

The JSON Web Token is the Access Token format which this document requires when using OAuth2. The JWT supports signatures using asymmetric cryptography which implies that Servers which accept the Access Token must have access to the Certificate used by the Authorization Service (AS). The OpenID Connect Discovery specification is implemented by many AS products and provides a mechanism to fetch the AS Certificate via an HTTP request. If the AS does not support the discovery specification, then the signing Certificate will have to be provided to the Server when the location of the AS is added to the Server configuration.

Access Tokens expire and all Servers should revoke any privileges granted to the Session when the Access Token expires. If the Server allows for anonymous users, the Server may allow the Session to stay open but treat it as an anonymous user. If the Server does not allow anonymous users, it should close the Session immediately.

Clients know when the Access Token will expire and should request a new Access Token and call ActivateSession before the old Access Token expires.

The JWT format allows the Authorization Service to insert any number of fields. The mandatory fields are defined in RFC 8259. Some additional fields are defined in Table 52 (see RFC 7523).

Table 52 – Access Token Claims

Field

Description

sub

The subject for the token.

Usually the RFC 7523 client_id which identifies the Client.

If returned from an Identity Provider it may be a unique identifier for the user.

aud

The audience for the token.

Usually the RFC 7523 resource_id which identifies the Server or the Server ApplicationUri.

name

A human readable name for the Client application or user.

scp

A list of Scopes granted to the subject.

Scopes apply to the Access Token and restrict how it may be used.

Usually permissions or other restriction which limit access rights.

nonce

A nonce used to mitigate replay attacks.

Shall be the value provided by the Client in the request.

groups

A list of groups which are assigned to the subject.

Usually a list of unique identifiers for specific security groups.

For example, Azure AD user account groups may be returned in this claim.

roles

A list of roles which are assigned to the subject.

Roles apply to the requestor and describe what the requestor can do with the resource.

Roles are list of unique names for roles.known to the Authorization Service.

These values are typically mapped to the Roles defined in OPC 10000-3 using the identity mappings defined in OPC 10000-18.

The authorization code flow is available to Clients which allow interaction with a human user. The Client application displays a window with a web browser which sends an HTTP GET to the Identity Provider. When the human user enters credentials that the Identity Provider validates the Identity Provider returns an authorization code which is passed to the Authorization Service. The Authorization Service validates the code and returns an Access Token to the Client.

The complete flow is described in RFC 5392, 4.1.

A requestType of “authorization_code” in the UserTokenPolicy (see 6.5.2) means the Authorization Service supports the authorization code flow.

The refresh token flow applies when a Client application has access to a refresh token returned in a previous response to an authorization code request. The refresh token allows applications to skip the step that requires human interaction with the Identity Provider. This flow is initiated when the Client sends the refresh token to Authorization Service which validates it and returns an Access Token. A Client that saves the refresh token for later use shall use encryption or other means to ensure the refresh token cannot be accessed by unauthorized parties.

The complete flow is described in RFC 5392, 6.

A requestType is not defined since support for refresh token is determined by checking the response to an authorization code request.

The client credentials flow applies when a Client application cannot prompt a human user for input. This flow requires a secret know to the Authorization Service which the Client application can protect. This flow is initiated when the Client sends the client_secret to Authorization Service which validates it and returns an Access Token.

The complete flow is described in RFC 5392, Clause 4.4.

A requestType of “client_credentials” in the UserTokenPolicy (see 6.5.2) means the Authorization Service supports the client credentials flow.

Note: Deprecated in Version 1.03.

OPC UA Secure Conversation (UASC) allows secure communication using binary encoded Messages.

UASC is designed to operate with different TransportProtocols that may have limited buffer sizes. For this reason, OPC UA Secure Conversation will break OPC UA Messages into several pieces (called ‘MessageChunks’) that are smaller than the buffer size allowed by the TransportProtocol. UASC requires a TransportProtocol buffer size that is at least 8 192 bytes when using RSA based Asymmetric Cryptography This minimum buffer size drops to 1 024 when using ECC based Asymmetric Cryptography (see 6.8) is supported.

All security is applied to individual MessageChunks and not the entire OPC UA Message. A Stack that implements UASC is responsible for verifying the security on each MessageChunk received and reconstructing the original OPC UA Message.

All MessageChunks will have a 4-byte sequence assigned to them. These sequence numbers are used to detect and prevent replay attacks.

UASC requires a TransportProtocol that will preserve the order of MessageChunks, however, a UASC implementation does not necessarily process the Messages in the order that they were received.

The structure of the Message depends on whether the SecurityPolicy requires an algorithm that combines encryption and authentication (e.g. Authenticated Encryption algorithms) used or if it requires separate algorithms for each operation (Unauthenticated Encryption algorithms).

Figure 11 shows the structure of a MessageChunk and how security is applied to the Message when using Unauthenticated Encryption algorithms. For these SecurityPolicies any padding is appended to the message before appending the Signature.

image014.png

Figure 11 – MessageChunk for Unauthenticated Encryption Algorithms

Figure 12 shows the structure of a MessageChunk and how security is applied to the Message when using Authenticated Encryption algorithms. For these SecurityPolicies the Signature is calculated during encryption and appended after the encrypted data. Padding is not needed.

image015.png

Figure 12 – MessageChunk for Authenticated Encryption Algorithms

Every MessageChunk has a Message header with the fields defined in Table 53.

Table 53 – OPC UA Secure Conversation Message Header

Name

Data Type

Description

MessageType

Byte [3]

A three byte ASCII code that identifies the Message type.

The following values are defined at this time:

MSGA Message secured with the keys associated with a channel.

OPN OpenSecureChannel Message.

CLO CloseSecureChannel Message.

IsFinal

Byte

A one byte ASCII code that indicates whether the MessageChunk is the final chunk in a Message.

The following values are defined at this time:

C An intermediate chunk.

F The final chunk.

A The final chunk (used when an error occurred and the Message is aborted).

This field is only meaningful for MessageType of ‘MSG’

This field is always ‘F’ for other MessageTypes.

MessageSize

UInt32

The length of the MessageChunk, in bytes.

The length starts from the beginning of the MessageType field.

SecureChannelId

UInt32

A unique identifier for the SecureChannel assigned by the Server.

If a Server receives a SecureChannelId which it does not recognize it shall return an appropriate transport layer error.

When a Server starts the first SecureChannelId used should be a value that is likely to be unique after each restart. This ensures that a Server restart does not cause previously connected Clients to accidently ‘reuse’ SecureChannels that did not belong to them.

The Message header is followed by a security header which specifies what cryptography operations have been applied to the Message. There are two versions of the security header which depend on the type of security applied to the Message. The security header used for asymmetric algorithms is defined in Table 54. Asymmetric algorithms are used to secure the OpenSecureChannel Messages. PKCS #1 defines a set of asymmetric algorithms that may be used by UASC implementations. The AsymmetricKeyWrapAlgorithm element of the SecurityPolicy structure defined in Table 45 is not used by UASC implementations.

Table 54 – Asymmetric algorithm Security header

Name

Data Type

Description

SecurityPolicyUriLength

Int32

The length of the SecurityPolicyUri in bytes.

This value shall not exceed 255 bytes.

If a URI is not specified this value may be 0 or -1.

Other negative values are invalid.

SecurityPolicyUri

Byte []

The URI of the Security Policy used to secure the Message.

This field is encoded as a UTF-8 string without a null terminator.

SenderCertificateLength

Int32

The length of the SenderCertificate in bytes.

This value shall not exceed MaxSenderCertificateSize bytes.

If a certificate is not specified this value may be 0 or -1.

Other negative values are invalid.

SenderCertificate

Byte []

The X.509 v3 Certificate assigned to the sending application Instance.

This is a DER encoded blob.

The structure of an X.509 v3 Certificate is defined in X.509 v3.

The DER format for a Certificate is defined in X690

This indicates what Private Key was used to sign the MessageChunk.

The Stack shall close the channel and report an error to the application if the SenderCertificate is too large for the buffer size supported by the transport layer.

This field shall be null if the Message is not signed.

If the Certificate is signed by a CA, the DER encoded CA Certificate may be appended after the Certificate in the byte array. If the CA Certificate is also signed by another CA this process is repeated until the entire Certificate chain is in the buffer or if MaxSenderCertificateSize limit is reached (the process stops after the last whole Certificate that can be added without exceeding the MaxSenderCertificateSize limit).

Receivers can extract the Certificates from the byte array by using the Certificate size contained in DER header (see X.509 v3).

Receivers that do not handle Certificate chains shall ignore the extra bytes.

ReceiverCertificateThumbprintLength

Int32

The length of the ReceiverCertificateThumbprint in bytes.

If encrypted, the value of this field is 20 bytes.

If not encrypted the value may be 0 or -1.

Other negative values are invalid.

ReceiverCertificateThumbprint

Byte []

The thumbprint of the X.509 v3 Certificate assigned to the receiving application Instance.

The thumbprint is the CertificateDigest of the DER encoded form of the Certificate.

This indicates what public key was used to encrypt the MessageChunk.

This field shall be null if the Message is not encrypted.

The receiver shall close the communication channel if any of the fields in the security header have invalid lengths.

The SenderCertificate, including any chains, shall be small enough to fit into a single MessageChunk and leave room for at least one byte of body information. The maximum size for the SenderCertificate can be calculated with this formula:

MaxSenderCertificateSize =

MessageChunkSize –

12 - // Header size

4 - // SecurityPolicyUriLength

SecurityPolicyUri -// UTF-8 encoded string

4 - // SenderCertificateLength

4 - // ReceiverCertificateThumbprintLength

20 - // ReceiverCertificateThumbprint

8 - // SequenceHeader size

1 - // Minimum body size

1 - // PaddingSize if present

Padding - // Padding if present

ExtraPadding - // ExtraPadding if present

AsymmetricSignatureSize// If present

The MessageChunkSize depends on the transport protocol but shall be at least 8 192 bytes. The AsymmetricSignatureSize depends on the number of bits in the public key for the SenderCertificate. The Int32FieldLength is the length of an encoded Int32 value and it is always 4 bytes.

The security header used for symmetric algorithms defined in Table 55. Symmetric algorithms are used to secure all Messages other than the OpenSecureChannel Messages. FIPS 197 define symmetric encryption algorithms that UASC implementations may use. FIPS 180- and HMAC define some symmetric signature algorithms.

Table 55 – Symmetric algorithm Security header

Name

Data Type

Description

TokenId

UInt32

A unique identifier for the SecureChannel SecurityToken used to secure the Message.

This identifier is returned by the Server in an OpenSecureChannel response Message. If a Server receives a TokenId which it does not recognize it shall return an appropriate transport layer error.

The security header is always followed by the sequence header which is defined in Table 56. The sequence header ensures that the first encrypted block of every Message sent over a channel will start with different data.

Table 56 – Sequence header

Name

Data Type

Description

SequenceNumber

UInt32

A monotonically increasing sequence number assigned by the sender to each MessageChunk sent over the SecureChannel.

RequestId

UInt32

An identifier assigned by the Client to OPC UA request Message. All MessageChunks for the request and the associated response use the same identifier.

A SequenceNumber may not be reused for any TokenId. The SecurityToken lifetime shall be short enough to ensure that this never happens; however, if it does the receiver shall treat it as a transport error and force a reconnect. The SequenceNumber does not reset when a new TokenId is issued and it shall be incremented by exactly one for each MessageChunk sent.

SecurityPolicies with LegacySequenceNumbers set to TRUE, the SequenceNumber shall monotonically increase for all Messages and shall not wrap around until it is greater than 4 294 966 271 (UInt32.MaxValue – 1 024). The first number after the wrap around shall be less than 1 024.

SecurityPolicies with LegacySequenceNumbers set to FALSE, the SequenceNumber shall start at 0 and monotonically increase for all Messages and shall not wrap around until it is equal to 4 294 967 295 (UInt32.MaxValue). The first number after the wrap around shall be 0.

Some applications will find it takes time to validate the OpenSecureChannel Requests and Responses used to renew a TokenId. In these situations, the receiver may assume the SequenceNumber is correct which allows it to process subsequent messages secured with the existing TokenId before the OpenSecureChannel Message is validated. When processing of the OpenSecureChannel Message completes, the receiver checks the SequenceNumber and closes the SecureChannel if it is incorrect.

The sequence header is followed by the Message body which is encoded with the OPC UA Binary encoding as described in 5.2.9. The body may be split across multiple MessageChunks.

Each MessageChunk when using SecurityPolicies with an Unauthenticated Encryption algorithms have a footer with the fields defined in Table 57.

Table 57 Message Footer for Unauthenticated Encryption Algorithms

Name

Data Type

Description

PaddingSize

Byte

The number of padding bytes (not including the byte for the PaddingSize).

Padding

OctetString

Padding added to the end of the Message to ensure length of the data to encrypt is an integer multiple of the encryption block size.

The value of each byte of the padding is equal to PaddingSize.

ExtraPaddingSize

Byte

The most significant byte of a two-byte integer used to specify the padding size when the key used to encrypt the message chunk is larger than 2 048 bits. This field is omitted if the key length is less than or equal to 2 048 bits.

Signature

OctetString

The signature for the MessageChunk.

The signature includes the headers, all Message data, the PaddingSize and the Padding.

The signature is encoded as sequence of Bytes with a length specified by the SecurityPolicy.

The formula to calculate the amount of padding depends on the amount of data that needs to be sent (called BytesToWrite). The sender shall first calculate the maximum amount of space available in the MessageChunk (called MaxBodySize) using the following formula:

MaxBodySize = PlainTextBlockSize * Floor ((MessageChunkSize – MessageHeaderSize - SecurityHeaderSize – SignatureSize - 1)/CipherTextBlockSize) – SequenceHeaderSize;

The MessageHeaderSize is 12 bytes and the SecurityHeader size depends on whether symmetric or asymmetric cryptography is used. The SequenceHeaderSize is always 8 bytes.

During encryption a block with a size equal to PlainTextBlockSize is processed to produce a block with size equal to CipherTextBlockSize. These values depend on the encryption algorithm and may be the same.

The OPC UA Message can fit into a single chunk if BytesToWrite is less than or equal to the MaxBodySize. In this case the PaddingSize is calculated with this formula:

PaddingSize = PlainTextBlockSize –

((BytesToWrite + SignatureSize + 1) % PlainTextBlockSize);

If the BytesToWrite is greater than MaxBodySize the sender shall write MaxBodySize bytes with a PaddingSize of 0. The remaining BytesToWriteMaxBodySize bytes shall be sent in subsequent MessageChunks.

The PaddingSize and Padding fields are not present if the MessageChunk is not encrypted.

The Signature field is not present if the MessageChunk is not signed.

Each MessageChunk when using SecurityPolicies with an Authenticated Encryption algorithms have a footer with the fields defined in Table 58.

Table 58 Message Footer for Authenticated Encryption Algorithms

Name

Data Type

Description

Signature

OctetString

The signature for the MessageChunk.

The signature includes the headers and all Message data.

The signature is encoded as sequence of Bytes with a length specified by the SecurityPolicy.

MessageChunks are sent as they are encoded. MessageChunks belonging to the same Message shall be sent sequentially. If an error occurs creating a MessageChunk then the sender shall send a final MessageChunk to the receiver that tells the receiver that an error occurred and that it should discard the previous chunks. The sender indicates that the MessageChunk contains an error by setting the IsFinal flag to ‘A’ (for Abort). Table 59 specifies the contents of the Message abort MessageChunk.

Table 59 – OPC UA Secure Conversation Message abort body

Name

Data Type

Description

Error

UInt32

The numeric code for the error.

Possible values are listed in Table 74.

Reason

String

A more verbose description of the error.

This string shall not be more than 4 096 bytes.

A Client shall ignore strings that are longer than this.

Any security related information shall not be returned. This includes any indication of the reason that caused Bad_SecurityChecksFailed to be returned.

The receiver shall check the security on the abort MessageChunk before processing it. If everything is ok, then the receiver shall ignore the Message but shall not close the SecureChannel. The Client shall report the error back to the application as StatusCode for the request. If the Client is the sender, then it shall report the error without waiting for a response from the Server.

Most Messages require a SecureChannel to be established. A Client does this by sending an OpenSecureChannel request to the Server. The Server shall validate the Message and the ClientCertificate and return an OpenSecureChannel response. Some of the parameters defined for the OpenSecureChannel service are specified in the security header (see 6.7.2) instead of the body of the Message. Table 60 lists the parameters that appear in the body of the Message.

Note that OPC 10000-4 is an abstract specification which defines interfaces that can work with any protocol. This document provides a concrete implementation for specific protocols. This document is the normative reference for all protocols and takes precedence if there are differences with OPC 10000-4.

Table 60 – OPC UA Secure Conversation OpenSecureChannel Service

Name

Data Type

Request

RequestHeader

RequestHeader

ClientProtocolVersion

UInt32

RequestType

SecurityTokenRequestType

SecurityMode

MessageSecurityMode

ClientNonce

ByteString

RequestedLifetime

UInt32

Response

ResponseHeader

ResponseHeader

ServerProtocolVersion

UInt32

SecurityToken

ChannelSecurityToken

SecureChannelId

UInt32

TokenId

UInt32

CreatedAt

UtcTime

RevisedLifetime

UInt32

ServerNonce

ByteString

The ClientProtocolVersion and ServerProtocolVersion parameters are not defined in OPC 10000-4 and are added to the Message to allow backward compatibility if OPC UA-SecureConversation needs to be updated in the future.

If OPC UA-SecureConversation is used with the OPC UA-TCP protocol (see 7.1) then the ClientProtocolVersion specified in the OpenSecureChannel Request shall be the same as the ProtocolVersion specified in the Hello Message. In addition, the ServerProtocolVersion specified in the OpenSecureChannel Response shall be the same as the ProtocolVersion specified in the Acknowledge Message. The receiver shall close the channel and report a Bad_ProtocolVersionUnsupported error if there is a mismatch.

The Server shall return an error response as described in OPC 10000-4 if there are any errors with the parameters specified by the Client.

The RevisedLifetime tells the Client when it shall renew the SecurityToken by sending another OpenSecureChannel request. The Client shall continue to accept the old SecurityToken until it expires or it receives a Message from the Server secured with the new SecurityToken. The Client shall send a Messages secured with new SecurityToken as soon as it finishes processing the OpenSecureChannel response. The Client shall close the SecureChannel if the Certificate used to sign the response is not the same as the Certificate used to encrypt the request.

The Server shall accept requests secured with the old SecurityToken until that SecurityToken expires or until it receives a Message from the Client secured with the new SecurityToken. The Server shall reject renew requests if the SenderCertificate is not the same as the one used to create the SecureChannel or if there is a problem decrypting or verifying the signature.

The datatype of the RevisedLifetime is a UInt32 value representing the number of milliseconds instead of the Double (Duration) defined in OPC 10000-4. This optimization is possible because sub-millisecond timeouts are not supported.

The OpenSecureChannel Messages are signed and encrypted if the SecurityMode is not None (even if the SecurityMode is Sign).

The Nonces shall be cryptographic random numbers with a length specified by the SecureChannelNonceLength of the SecurityPolicy.

See OPC 10000-2 for more information on the requirements for random number generators. The OpenSecureChannel Messages are not signed or encrypted if the SecurityMode is None. The Nonces are ignored and should be set to null. The SecureChannelId and the TokenId are still assigned but no security is applied to Messages exchanged via the channel. The SecurityToken shall still be renewed before the RevisedLifetime expires. Receivers shall still ignore invalid or expired TokenIds.

The AuthenticationToken in the RequestHeader shall be set to null.

If an error occurs after the Server has verified Message security it shall return a ServiceFault instead of a OpenSecureChannel response. The ServiceFault Message is described in OPC 10000-4.

If the SecurityMode is not None then the Server shall verify that a SenderCertificate and a ReceiverCertificateThumbprint were specified in the SecurityHeader.

Once the SecureChannel is established the Messages are signed and encrypted with keys derived from the Nonces exchanged in the OpenSecureChannel call. These keys are derived by passing the Nonces to a pseudo-random function (PRF) which produces a sequence of bytes from a set of inputs. A pseudo-random function is represented by the following function declaration:

Byte[] PRF(

Byte[] secret,

Byte[] seed,

Int32 length,

Int32 offset)

Where length is the number of bytes to return and offset is a number of bytes from the beginning of the sequence.

The lengths of the keys that need to be generated depend on the SecurityPolicy used for the channel. The following information is specified by the SecurityPolicy:

  1. SigningKeyLength (from the DerivedSignatureKeyLength);
  2. EncryptingKeyLength (implied by the SymmetricEncryptionAlgorithm);
  3. IntializationVectorLength (from by the IntializationVectorLength).

The pseudo random function requires a secret and a seed. These values are derived from the Nonces exchanged in the OpenSecureChannel request and response. Table 61 specifies how to derive the secrets and seeds when using RSA based SecurityPolicies.

Table 61 – PRF inputs for RSA based SecurityPolicies

Name

Derivation

ClientSecret

The value of the ClientNonce provided in the OpenSecureChannel request.

ClientSeed

The value of the ClientNonce provided in the OpenSecureChannel request.

ServerSecret

The value of the ServerNonce provided in the OpenSecureChannel response.

ServerSeed

The value of the ServerNonce provided in the OpenSecureChannel response.

The parameters passed to the pseudo random function are specified in Table 62.

Table 62 – Cryptography key generation parameters

Key

Secret

Seed

Length

Offset

ClientSigningKey

ServerSecret

ClientSeed

SigningKeyLength

0

ClientEncryptingKey

ServerSecret

ClientSeed

EncryptingKeyLength

SigningKeyLength

ClientInitializationVector

ServerSecret

ClientSeed

IntializationVectorLength

SigningKeyLength+EncryptingKeyLength

ServerSigningKey

ClientSecret

ServerSeed

SigningKeyLength

0

ServerEncryptingKey

ClientSecret

ServerSeed

EncryptingKeyLength

SigningKeyLength

ServerInitializationVector

ClientSecret

ServerSeed

IntializationVectorLength

SigningKeyLength+EncryptingKeyLength

The Client keys are used to secure Messages sent by the Client. The Server keys are used to secure Messages sent by the Server.

The TLS specification defines a pseudo random function called P_HASH which is used for this purpose. The function is iterated until it produces enough data for all of the required keys. The Offset in Table 62 references to the offset from the start of the generated data.

The P_ hash algorithm is defined as follows:

P_HASH(secret, seed) = HMAC_HASH(secret, A(1) + seed) +

HMAC_HASH(secret, A(2) + seed) +

HMAC_HASH(secret, A(3) + seed) + ...

Where A(n) is defined as:

A(0) = seed

A(n) = HMAC_HASH(secret, A(n-1))

+ indicates that the results are appended to previous results.

Where ‘HASH’ is a hash function such as SHA256. The hash function to use depends on the SecurityPolicyUri.

The contents of the MessageChunk shall not be interpreted until the Message is decrypted and the signature and sequence number verified.

If an error occurs during Message verification the receiver shall close the communication channel. If the receiver is the Server, it shall also send a transport error Message before closing the channel. Once the channel is closed the Client shall attempt to re-open the channel and request a new SecurityToken by sending an OpenSecureChannel request. The mechanism for sending transport errors to the Client depends on the communication channel.

The receiver shall first check the SecureChannelId. This value may be 0 if the Message is an OpenSecureChannel request. For other Messages, it shall report a Bad_SecureChannelUnknown error if the SecureChannelId is not recognized. If the Message is an OpenSecureChannel request and the SecureChannelId is not 0 then the SenderCertificate shall be the same as the SenderCertificate used to create the channel.

If the Message is secured with asymmetric algorithms, then the receiver shall verify that it supports the requested SecurityPolicy. If the Message is the response sent to the Client, then the SecurityPolicy shall be the same as the one specified in the request. In the Server, the SecurityPolicy shall be the same as the one used to originally create the SecureChannel.

The receiver shall verify the ReceiverCertificateThumbprint and report a Bad_CertificateInvalid error if it does not recognize it.

The receiver shall check that the Certificate is trusted first and return Bad_SecurityChecksFailed on error. The receiver shall then verify the SenderCertificate using the rules defined in OPC 10000-4. The receiver shall report the appropriate error if Certificate validation fails.

If the Message is secured with symmetric algorithms, then a Bad_SecureChannel TokenUnknown e rror shall be reported if the TokenId refers to a SecurityToken that has expired or is not recognized.

If decryption or signature validation fails, then a Bad_SecurityChecksFailed error is reported. If an implementation allows multiple SecurityModes to be used the receiver shall also verify that the Message was secured properly as required by the SecurityMode specified in the OpenSecureChannel request.

After the security validation is complete the receiver shall verify the RequestId and the SequenceNumber. If these checks fail a Bad_SecurityChecksFailed error is reported. The RequestId only needs to be verified by the Client since only the Client knows if it is valid or not. If the SequenceNumber is not valid, the receiver shall log a Bad_SequenceNumberInvalid error.

At this point the SecureChannel knows it is dealing with an authenticated Message that was not tampered with or resent. This means the SecureChannel can return secured error responses if any further problems are encountered.

Stacks that implement UASC shall have a mechanism to log errors when invalid Messages are discarded. This mechanism is intended for developers, systems integrators and administrators to debug network system configuration issues and to detect attacks on the network.

The OPC UA Secure Conversation (UASC) mechanism described 6.7 is designed for use with asymmetric cryptography algorithms, such as RSA, that allow Public Keys to be used for encryption and for digital signatures. ECC is an asymmetric cryptography algorithm that only supports digital signatures. To accommodate algorithms like ECC, the UASC handshake needs to be modified to allow negotiation of inputs used for key derivation in 6.7.5 without making the keys available to eavesdroppers. This negotiation uses a Diffie Hellman algorithm defined in RFC 8422 and is shown in Figure 13.

image016.png

Figure 13 – ECC Key Negotiation

ApplicationInstance Certificates for ECC have a public-private key pair that are used to create and verify a digital signature. To negotiate the keys needed for the SecureChannel the Client generates a new key pair (JC, KC) and passes the Public Key (JC) in the request. After verifying the signature on the request, the Server generates a new key pair (JS, KS) and returns the Public Key (JS) in the response. The new key pairs are used each time a SecureChannel is negotiated and they are called EphemeralKeys.

ECC public-private key pairs are always based on a specific elliptic curve function which is used for the ECC calculations. Many curves exist, however, ECC cryptography libraries support a finite set of “named curves” to allow for better interoperability. Each OPC UA SecurityPolicy defined in OPC 10000-7 specifies exactly one named curve which is used for the EphemeralKeys.

Each ECC ApplicationInstance Certificate is also based on a named curve. Each SecurityPolicy specifies a list of named curves which are permitted for use in the ApplicationInstance Certificate. This list always includes the named curved used for the EphemeralKey, however, it may allow other named curves. OPC UA applications that support ECC SecurityPolicies will need to support multiple ApplicationInstance Certificates.

ECC Public Keys and digital signatures are the output of an ECC operation. The encoding of these outputs depends on the ECC curve and are described by the SecurityPolicy in OPC 10000-7.

Clause 6.7.4 specifies the contents of the OpenSecureChannel request and response messages. When using an ECC SecurityPolicy the ClientNonce is the Public Key for the Client’s EphemeralKey encoded using the Public Key encoding for the curve. Similarly, the ServerNonce is the Public Key for the Server’s EphemeralKey.

The encoding of the EphemeralKeys depends on the ECC curve used. For NIST and Brainpool curves the EphemeralKey is the x and y coordinate encoded as zero padded big-endian OctetString. For Edwards curves the EphemeralKey format is defined by RFC 7748.

The EphemeralKeys are used to calculate a shared secret by using the Private Key of an EphemeralKey and the Public Key of the peer’s EphemeralKey. The exact algorithm to calculate the shared secret depends on the ECC curve and is defined by the SecurityPolicy. This shared secret is then used to derive key data using the following algorithm from RFC 5869. Note that the algorithm is repeated here for clarity, however, the RFC is the normative source.

Step 1: Calculate Salts

ServerSalt = L | UTF8(opcua-server) | ServerNonce | ClientNonce

ClientSalt = L | UTF8(opcua-client) | ClientNonce | ServerNonce

Where

Step 2: Extract

PRK = HMAC-Hash(Salt, IKM)

Where

  • HMAC uses a Hash function specified by the KeyDerivationAlgorithm;
  • IKM is the x-coordinate of the shared secret;
  • Salt is calculated in Step 1;
  • PRK is a pseudorandom output with length equal to the Hash size.

The encoding of the x-coordinate depends on the ECC curve used. For NIST and Brainpool curves the x-coordinate is encoded as a zero padded big-endian OctetString. For Edwards curves the coordinate format is defined by RFC 7748.

Step 3: Expand

N = ceil(L/HashLen)

T = T(1) | T(2) | T(3) | ... | T(N)

OKM = first L octets of T

where:

T(0) = empty string (zero length)

T(1) = HMAC-Hash(PRK, T(0) | Info | 0x01)

T(2) = HMAC-Hash(PRK, T(1) | Info | 0x02)

T(3) = HMAC-Hash(PRK, T(2) | Info | 0x03)

...

Where

  • HMAC uses a Hash function specified by the KeyDerivationAlgorithm;
  • PRK is the output from Step 1;
  • Info is a sequence of bytes;
  • L is the length of keying material needed;
  • 0x01 is the number 1 encoded as a byte.
  • OKM is the output with length equal to L bytes.

The client keys are extracted from the keying material created with IKM=shared secret, Salt=ClientSalt and Info=ClientSalt as shown in Table 63.

Table 63 – Deriving Client Keys from Keying Material

Name

Offset

Length

ClientSigningKey

0

DerivedSignatureKeyLength

ClientEncryptingKey

DerivedSignatureKeyLength

EncryptionKeyLength

ClientInitializationVector

DerivedSignatureKeyLength + EncryptionKeyLength

InitializationVectorLength

The server keys are extracted from the keying material created with IKM=shared secret, Salt= ServerSalt and Info=ServerSalt as shown in Table 64.

Table 64 – Deriving Server Keys from Keying Material

Name

Offset

Length

ServerSigningKey

0

DerivedSignatureKeyLength

ServerEncryptingKey

DerivedSignatureKeyLength

EncryptionKeyLength

ServerInitializationVector

DerivedSignatureKeyLength + EncryptionKeyLength

InitializationVectorLength

The SymmetricEncryptionAlgorithm for the SecurityPolicy sets the EncryptionKeyLength and EncryptionBlockSize.

When using AuthenticatedEncryption, the SigningKey, EncryptingKey and InitializationVector are always calculated, however, only the EncryptingKey and InitializationVector are used. The only difference between Sign and SignAndEncrypt is the length of encrypted data which is zero when Sign is used. The process of signing and encrypting data with AuthenticatedEncryption is illustrated in Figure 14.

image017.png

Figure 14 – Signing and Encryption with Authenticated Encryption

When using UnauthenticatedEncryption with Sign only the SigningKey needs to be computed, however, the length of the derived key material used to calculate the Salt shall be the same as the length of the derived key material used with SignAndEncrypt. The encryption algorithm is not used and the padding is zero length when using Sign mode. The process of signing and encrypting data with UnauthenticatedEncryption is illustrated in Figure 15.

image018.png

Figure 15 – Signing and Encryption with Unauthenticated Encryption

In addition, a unique InitializationVector is needed for each Message. This value constructed from the ClientInitializationVector or ServerInitializationVector where the first 8 bytes are XORed with the values in Table 65 encoded as described in 5.2.2.2.

Table 65 – Creating a Mask for the Initialization Vector

Name

Bytes

Length

TokenId

4

The TokenId specified in the SecurityHeader of MessageChunk being processed.

It is encoded as a UInt32 as described in 5.2.2.2.

LastSequenceNumber

4

The SequenceNumber specified in the SequenceHeader of last MessageChunk sent in the same direction on the SecureChannel.

The value is 0 to indicate there is no LastSequenceNumber for the first MessageChunk which is always the OpenSecureChannel Message.

It is encoded as a UInt32 as described in 5.2.2.2.

The ClientInitializationVector is used when the Client encrypts the MessageChunk and the ServerInitializationVector is used when the Server encrypts the MessageChunk.

The LastSequenceNumber is the SequenceNumber from the previously sent Message which normally requires the previous Message to be decrypted. If the receiver processes incoming Messages in parallel it can calculate the expected SequenceNumber based on the order in which the encrypted Messages are received.

Once the keys are derived ECC SecureChannels behave the same as RSA SecureChannels.

ActivateSession allows a Client to provide an encrypted UserIdentityToken using a SecurityPolicy specified by a UserTokenPolicy supported by the current Endpoint. With ECC, encryption requires that the Client and Server exchange EphemeralKeys and there is no mechanism in the current CreateSession/ActivateSession handshake to do this. For that reason, EphemeralKeys are returned in the AdditionalHeader field of the ResponseHeader of the CreateSession and ActivateSession responses. An overview of the handshake is shown in Figure 16.

image019.png

Figure 16 – ECC CreateSession/ActivateSession Handshake

The UserTokenPolicies are returned in the GetEndpoints response. A UserTokenPolicy may specify a SecurityPolicyUri that is different than the SecureChannel, however, all UserTokenPolicies in an EndpointDescription shall specify a SecurityPolicyUri that is valid for all Certificates that are valid for SecurityPolicyUri specified in the EndpointDescription. For example, an EndpointDescription providing an ECC SecurityPolicyUri shall not specify RSA SecurityPolicyUris in the UserTokenPolicies.

When a Client calls CreateSession via a SecureChannel based on an ECC SecurityPolicy the Client specifies the SecurityPolicyUri it plans to use for the UserIdentityToken in the RequestHeader. Server returns an EphemeralKey in the ResponseHeader that can be used for the SecurityPolicyUri specified by the Client. If the SecurityPolicyUri is not valid the Server returns a StatusCode in the ResponseHeader instead of an EphemeralKey.

When the Client calls ActivateSession it creates an EccEncryptedSecret (see OPC 10000-4) using the EphemeralKey provided in CreateSession response. The Server always returns a new EphemeralKey in the ResponseHeader which the Client saves for when it calls ActivateSession again. The SecurityPolicyUri passed in CreateSession is used to determine what type of EphemeralKey to return.

The EphemeralKeys may be used for exactly one key negotiation. After that they are discarded. Each time ActivateSession is called the UserIdentityToken is encrypted using the last EphemeralKey returned by the Server. The EphemeralKey is changed even if the Client did not provide an encrypted UserIdentityToken.

If the Client does not provide SecurityPolicyUri in the call to CreateSession it will not be able to use any UserIdentityTokens that require encryption with ECC SecurityProfiles.

OPC 10000-4 defines AdditionalParametersType which is a list of name-value pairs. An instance of this type is passed in the AdditionalHeader field. Instances of the EphemeralKeyType defined in OPC 10000-4 are passed as values in the name-value pair list in the response messages. The names used for the parameters defined for the CreateSession/ActivateSession exchange are defined in Table 66.

Table 66 – Additional Header Key Names

Name

DataType

Description

ECDHPolicyUri

String

Specifies the SecurityPolicyUri used for the EphemeralKeys.

ECDHKey

EphemeralKeyType

Specifies an EphemeralKey.

If the EphemeralKey could not be created a StatusCode indicating the reason for the error is used instead of an instance of EphemeralKeyType.

OPC 10000-4 defines the layout of EccEncryptedSecret structure which is used to protect secrets with ECC SecurityPolicies. Applying security with ECC requires two EphemeralKeys generated by the sender and the receiver which are used create the symmetric keys need for encryption.

6.8.1 defines a mechanism to allows the sender to acquire the receiver EphemeralKey when using a Session. Using the EccEncryptedSecret in other contexts requires a different mechanism.

Once the sender has the receiver EphemeralKey, it creates its own EphemeralKey. The ECC curve and key length for the EphemeralKeys are specified by the SecurityPolicyUri.

The encryption uses the symmetric encryption algorithm specified by the SecurityPolicyUri. The encrypting key and initialization vector are generated by using the EphemeralKeys to create the shared secret and then derive keys using the algorithm defined in 6.8.1. Step 1 is slightly different and defined as follows:

Step 1: Calculate Salt

SecretSalt = L | UTF8(opcua-secret) | SenderPublicKey | ReceiverPublicKey

Where:

  • L is the length of derived key material needed encoded as a 16-bit little endian integer;
  • UTF8(opcua-secret) is the UTF8 encoding of the string literal ‘opcua-secret’;
  • SenderPublicKey and ReceiverPublicKey are from the PolicyHeader;
  • | concatenates sequences of bytes;

Salt is a sequence of bytes.

The encryption keys are extracted from the keying material created with IKM=shared secret, Salt=SecretSalt and Info=SecretSalt as shown in Table 67.

Table 67 – Deriving Keys from Keying Material

Name

Offset

Length

EncryptingKey

0

EncryptionKeyLength

InitializationVector

EncryptionKeyLength

InitializationVectorLength

The EncryptionKeyLength and EncryptionBlockSize are specified by the Symmetric Encryption Algorithm for the SecurityPolicy. The Signature is created with the SigningCertificate and is calculated after encryption. Receivers shall validate the SigningCertificate and signature before decrypting the Secret.