In this page
- Introduction
- Example Demo
- Fast track for the impatient
- OpcuaClient
- Properties
- find_endpoints (static method)
- Reading Node Values in OPC UA
- Read a batch of nodes
- Read a node and retrieve its server/source timestamp
- Read a batch of node and retrieve their server/source timestamp
- Read the history of a node
- Reading metas (experimental)
- Subscriptions
- Writing Node Values in OPC UA
- Calling OPC-UA methods
- Error management
- OpcuaSecurityMode
- OpcuaSecurityPolicy
- OpcuaCertificate
- OpcuaCredentials
- Log levels
- Third party licenses
opcua
@library("opcua", "0.0.0");
Introduction
OPC UA, or Open Platform Communications Unified Architecture, is a standardized communication protocol for industrial automation applications. It provides a platform-independent, service-oriented architecture that enables secure and reliable data exchange between various industrial devices and systems. OPC UA is used to facilitate interoperability and communication in industrial environments, allowing different types of machines, sensors, and control systems to seamlessly exchange data regardless of the underlying hardware or software platforms. It ensures compatibility, scalability, and security in distributed systems, making it a preferred choice for implementing Industrial Internet of Things (IIoT) and Industry 4.0 solutions. In that regard, we provide for users of GreyCat, an OPC UA Client allowing the seamless connection to OPC UA devices to retrieve their values, without the need to leave GCL code and use external tools!
Plugin availability
| Platform | Availability |
|---|---|
| arm64-apple | Yes |
| arm64-linux | Yes |
| x64-linux | Yes |
| x64-windows | Yes |
Example Demo
Historian
example/historian/ is a second, optional server, for exercising
historical reads. It serves 10 signals of 1000 points each and caps a HistoryRead
response well below that, so a client has to follow continuation points to read a
full range:
cd example/historian
pnpm install
node server.js
It listens on 4841. Signal count, archive size, sampling interval and the
response cap all live in example/historian/.env; a real environment
variable overrides the file, so OPCUA_PORT=4843 node server.js needs no edit.
Sim_* values are varIndex * 1e6 + pointIndex, which is exactly representable
as a double — so a series that came back complete, ordered, gap-free and from the
right variable can be verified by inspection. Wave_* values are a plausible
process signal instead.
Driving the client by hand
With a server up, greycat serve exposes every OpcuaClient method over HTTP
and serves a console for calling them:
./bin/greycat serve --user=1
Then open http://localhost:8080. Browse the address space, click a node to
select it, and run any method against it — the console shows what the library
actually returned, and how long the call took. The endpoint picker offers the
historian and the test server; set HISTORIAN_URL to point the first entry
somewhere else.
The endpoints are thin wrappers, one per method, in src/api.gcl.
Fast track for the impatient
Reading a single node
@library("opcua", "0.0.0");
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://localhost:4842",
security_mode: OpcuaSecurityMode::SignAndEncrypt,
security_policy: OpcuaSecurityPolicy::Aes128_Sha256_RsaOaep,
certificate: OpcuaCertificate {
allow_self_signed: true,
path: "./opcua/test/key/client_cert.der",
private_key_path: "./opcua/test/key/client_key.der",
},
credentials: OpcuaCredentials { login: "root", password: "opcua" }
};
var result = opcua.read("ns=0;i=2258");
println(result);
println(result is time);
}
This code perform a OPC UA connection to a local server running on port 4842. The connection is password protected and uses signature/encryption with the Aes128_Sha256_RsaOaep policy. We want to read the node i=2258 on namespace 0 (this node is present on all OPC UA servers and store the server timestamp). We also assess the result is a core::time.
Result:
'2025-08-20T06:25:31.783026Z'
true
Read a single node with times
In a similar way, we want to retrieve the content of node ns=0;i=2258, alongside with the server and source times:
@library("opcua", "0.0.0");
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://localhost:4842",
security_mode: OpcuaSecurityMode::SignAndEncrypt,
security_policy: OpcuaSecurityPolicy::Aes128_Sha256_RsaOaep,
certificate: OpcuaCertificate {
allow_self_signed: true,
path: "./opcua/test/key/client_cert.der",
private_key_path: "./opcua/test/key/client_key.der",
},
credentials: OpcuaCredentials { login: "root", password: "opcua" }
};
var result = opcua.read_with_time("ns=0;i=2258");
pprint(result);
}
Result:
OpcuaValueDetails {
value: '2025-08-20T06:26:50.180530Z',
source_time: '2025-08-20T06:26:50Z',
server_time: '2025-08-20T06:26:50Z',
status_code: null
}
Writing a value
Our node ns=1;s=boolean contains a boolean. We’ll update it with a different value:
@library("opcua", "0.0.0");
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://localhost:4842",
security_mode: OpcuaSecurityMode::None,
security_policy: OpcuaSecurityPolicy::None,
};
var value = opcua.read("ns=1;s=boolean");
println("Before: ${value}");
opcua.write("ns=1;s=boolean", !value);
println("After: ${opcua.read("ns=1;s=boolean")}");
opcua.write("ns=1;s=boolean", 42);
}
Result:
false
true
ERROR 2025-08-20T06:28:51.682122Z 1/5.0 project::main
Unsupported GreyCat type (3) for OPCUA type: Boolean
at main (project.gcl:18:38)
At first, the node’s value is false. We update it to true, and the next read confirms that the server stored the new value. If we try to write something incompatible, like 42 instead of a boolean, the server rejects it and a runtime_error is raised.
Writing an array
Node ns=1;s=bool.array stores a boolean array (3 elements). Here’s how we can change its values:
@library("opcua", "0.0.0");
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://localhost:4842",
security_mode: OpcuaSecurityMode::None,
security_policy: OpcuaSecurityPolicy::None,
};
var value = opcua.read("ns=1;s=bool.array");
println("Before: ${value}");
opcua.write("ns=1;s=bool.array", [false, false, true]);
println("After: ${opcua.read("ns=1;s=bool.array")}");
}
Result:
Before: Array{true,false,true}
After: Array{false,false,true}
Calling a method
Our OPC UA server provides two RPC methods:
ns=1;i=62541accepts a single string argument and returns Hello. ns=1;s=IncInt32ArrayValuesaccepts two arguments: an integer array and an increment value. It returns a new array where each element has been increased by the given increment.
@library("opcua", "0.0.0");
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://localhost:4842",
security_mode: OpcuaSecurityMode::SignAndEncrypt,
security_policy: OpcuaSecurityPolicy::Aes128_Sha256_RsaOaep,
certificate: OpcuaCertificate {
allow_self_signed: true,
path: "./opcua/test/key/client_cert.der",
private_key_path: "./opcua/test/key/client_key.der",
},
credentials: OpcuaCredentials { login: "root", password: "opcua" }
};
println(opcua.call("ns=1;i=62541", ["dear GreyCat user!"]));
println(opcua.call("ns=1;s=IncInt32ArrayValues", [[1, 2, 3, 4, 5], 5]));
}
Result:
Hello dear GreyCat user!
Array{6,7,8,9,10}
OpcuaClient
The OpcuaClient type is responsible for establishing a connection to an OPC UA device.
Properties
When instantiating this type, the following properties are available:
url: String: Specifies the hostname or IP address of the OPC UA device.timeout: duration?: (Optional) Response timeout (by default:20s)security_mode: OpcuaSecurityMode: Specifies the OPC UA security mode to be applied to the connection.security_policy: OpcuaSecurityPolicy?: (Optional) Specifies the OPC UA security policy to be applied to the connection, if required.credentials: OpcuaCredentials?: (Optional) Provides credentials for authentication, if necessary.certificate: OpcuaCertificate?: (Optional) Optionally includes a client certificate for authentication purposes.
find_endpoints (static method)
Retrieves the list of available OPC UA endpoints from the server at the specified url. You can optionally filter the endpoints by security_mode and security_policy. Each endpoint provides information needed to establish a secure connection.
Returns an array of OpcuaEndpointDescription objects, each describing an available endpoint.
var results = OpcuaClient::find_endpoints("opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer", null, null);
println(results.size());
pprint(results);
}
6
Array {
OpcuaEndpointDescription {
url: "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
discovery_urls: Array {
"http://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer/discovery",
"opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer"
},
certificate: /** truncated for the example **/,
security_mode: OpcuaSecurityMode::SignAndEncrypt,
security_policy: OpcuaSecurityPolicy::Basic128Rsa15,
user_identity_token_ids: Array {
"0"
},
transport_profile_uri: "http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary",
security_level: 3
},
...
}
Reading Node Values in OPC UA
To read the current value of a specified NodeID, it must be provided in its string representation, following the OPC UA encoding format: ns=<namespaceindex>;<type>=<value>. For example, ns=0;i=2258 or ns=1;s=string.id.
String Representation Format:
ns: Indicates the namespace index of the NodeID.<type>: Represents the type of the NodeID. It can beifor numeric NodeIDs,sfor string NodeIDs,gfor Guid orbfor Opaque/ByteString identifier.<value>: Specifies the value of the NodeID.
Supported OPC UA Types and their mapping in GreyCat
The following table illustrates the OPC UA types supported by GreyCat and their corresponding mappings:
| OPC UA Type | GreyCat mapping |
|---|---|
| Boolean | bool |
| SByte | int |
| Byte | int |
| Int16 | int |
| UInt16 | int |
| Int32 | int |
| UInt32 | int |
| Int64 | int |
| UInt64 | int |
| Float | float |
| Double | float |
| String | String |
| DateTime | time |
| ByteString | String |
| XmlElement | String |
| Guid | String |
| StatusCode | String |
| NodeId | String |
| ExpandedNodeId | String |
| QualifiedName | Tuple<int, String> (namespace id;name) |
| LocalizedText | Tuple<String, String> (locale;value) |
| ExtensionObject | NOT SUPPORTED |
| DataValue | OpcuaValueDetails |
| Variant | applies recursively this conversion table to the value |
| Others | try at best a Map representation |
In GreyCat, OPC UA arrays are mapped directly to GreyCat arrays. If the OPC UA value is a matrix, it’s converted into an array of arrays instead.
Read a single node
opcua.read(nodeId: String):any?
opcua.read("ns=1;s=float"); //12.3456
opcua.read("ns=1;s=unknown node"); //null: node id is unknown
opcua.read("non valid representation"); //runtime exception: Unable to parse the node id
Read a batch of nodes
opcua.read_all(nodeIds: Array<String>): Array<any?>
opcua.read_all(["ns=1;s=int16", "ns=1;s=int32", "ns=1;s=string"]); //Array{32767,2147483647,"DataThings rocks!"};
opcua.read_all(["ns=1;s=int16", "ns=1;s=int32", "non valid", "ns=1;s=string"]); //Array{32767,2147483647,null,"DataThings rocks!"}
Read a node and retrieve its server/source timestamp
opcua.read_with_time(nodeId: String):OpcuaValueDetails?
opcua.read_with_time("ns=1;s=boolean"); //OpcuaValueDetails{value:true,source_time:'2025-08-20T06:42:33Z',server_time:'2025-08-20T06:46:53Z',status_code:null}
Read a batch of node and retrieve their server/source timestamp
opcua.read_all_with_time(nodeId: Array<String>):Array<OpcuaValueDetails?>
opcua.read_all_with_time(["ns=1;s=boolean","ns=1;s=float"]);
Array {
OpcuaValueDetails {
value: false,
source_time: '2025-08-20T06:55:34Z',
server_time: '2025-08-20T06:55:34Z',
status_code: null
},
OpcuaValueDetails {
value: 12.1999998093,
source_time: '2025-08-20T06:55:34Z',
server_time: '2025-08-20T06:55:34Z',
status_code: null
}
}
Read the history of a node
For this to work, the server has to provide historization on the given node.
opcua.read_history(nodeId: String, from: time?, to:time?):Array<OpcuaValueDetails>?
opcua.read_history("ns=1;s=history.uint32", time::parse("2023-07-10T12:00:00Z", null), time::parse("2024-08-11T12:00:00Z", null));
Array {
OpcuaValueDetails {
value: 100,
source_time: '2023-07-11T10:05:32Z',
server_time: '2023-07-11T10:05:32Z',
status_code: null
},
OpcuaValueDetails {
value: 150,
source_time: '2023-07-11T11:05:32Z',
server_time: '2023-07-11T11:05:32Z',
status_code: null
},
OpcuaValueDetails {
value: 200,
source_time: '2023-07-11T12:05:32Z',
server_time: '2023-07-11T12:05:32Z',
status_code: null
}
}
Reading metas (experimental)
OPC-UA metas information are useful to understand the structure of nodes. We store the meta information into a typed object “OpcuaMeta”
type OpcuaMeta{
node_id: String;
node_class: int?;
browse_name: Tuple?;
display_name: Tuple?;
description: Tuple?;
write_mask: int?;
user_write_mask: int?;
is_abstract: bool?;
symetric: bool?;
inverse_name: Tuple?;
contains_no_loops: bool?;
event_notifier: int?;
value: any?;
data_type: String?;
value_rang: int?;
array_dimentions: Array?;
access_level: int?;
user_access_level: int?;
minimum_sampling_interval: float?;
historizing: bool?;
executable: bool?;
user_executable: bool?;
}
Method read_metas
opcua.read_metas(nodesIds: Array<String>): Array<OpcuaMeta?>
Method get_children
opcua.get_children(nodeId: String): Array<OpcuaMeta>
Subscriptions
Subscriptions trigger only when a node’s value changes, so you receive updates only on actual changes. GreyCat must be running in serve mode to handle these OPC UA updates.
Lifetime
A subscription is identified by a name you choose, and it belongs to the library, not to the OpcuaClient that created it. It keeps delivering after that client goes out of scope or is garbage collected. It ends when, and only when:
OpcuaClient::cancel_subscription(name)is called, orclose()is called on the client that created it, which cancels every subscription made from that client, or- the connection to the server is lost — every affected subscription is reported through its
callback_errorand unregistered, or - the process stops.
Because a subscription runs on its own connection, is_connected() keeps reporting the client’s own request/response connection, not the subscription’s. It is false after subscribe() until you issue a read, write or call on the same client.
Names are unique across the process and shared between subscribe() and read_events(), so one name cannot be used for both. Use OpcuaClient::subscriptions() to find a subscription whose client is gone.
subscribe
opcua.subscribe(name: String, nodeIds: Array<String>, callback_data: function, callback_error: function)
Description: Creates a subscription for the specified nodes, registered under name.
Parameters:
- name: a unique name for this subscription. Raises if it is empty or already taken.
- nodeIds: an array of node identifiers to subscribe to.
- callback_data: a function called whenever new data arrives, with the signature:
(name: String, node_id: String, value: OpcuaValueDetails?) - callback_error: a function called on subscription errors, with the signature:
(name: String, error: String)
Failures the call can see for itself — an empty or duplicate name, or a server it cannot connect to — are raised, so try { ... } catch around subscribe() is meaningful. Everything only knowable later — the server rejecting the subscription, node ids that do not parse, the connection dropping — arrives through callback_error.
Example:
fn on_data(name: String, node_id: String, value: OpcuaValueDetails?){
println("${name}/${node_id}: ${value}");
}
fn on_error(name: String, error: String){
println("${name} failed: ${error}");
}
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://localhost:4842",
security_mode: OpcuaSecurityMode::SignAndEncrypt,
security_policy: OpcuaSecurityPolicy::Aes128_Sha256_RsaOaep,
certificate: OpcuaCertificate {
allow_self_signed: true,
path: "./opcua/test/key/client_cert.der",
private_key_path: "./opcua/test/key/client_key.der",
},
credentials: OpcuaCredentials { login: "root", password: "opcua" }
};
opcua.subscribe("strings", Array<String>{"ns=1;s=string"}, project::on_data, project::on_error);
//The subscription outlives `opcua`, so nothing here needs to keep it alive.
//Stop it with OpcuaClient::cancel_subscription("strings") when you are done.
}
Running with greycat serve and changing values on the OPC-UA server:
strings/ns=1;s=string: OpcuaValueDetails{value:"DataThings rocks",source_time:'2025-08-20T07:45:27Z',server_time:'2025-08-20T07:45:27Z',status_code:null}
strings/ns=1;s=string: OpcuaValueDetails{value:"I've just changed the value",source_time:'2025-08-20T07:45:38Z',server_time:'2025-08-20T07:45:38Z',status_code:null}
strings/ns=1;s=string: OpcuaValueDetails{value:"A new value",source_time:'2025-08-20T07:45:47Z',server_time:'2025-08-20T07:45:47Z',status_code:null}
strings/ns=1;s=string: OpcuaValueDetails{value:"42 is the answer",source_time:'2025-08-20T07:45:57Z',server_time:'2025-08-20T07:45:57Z',status_code:null}
read_events
Events are stored in typed objects:
type OpcuaEvent{
"EventId": String;
"EventType": String?;
"Message": Tuple?;
"SourceNode": String;
"SourceName": String;
"Time": time;
"ReceiveTime": time?;
"Severity": int;
"ConditionName": String?;
"ActiveState":Tuple?;
"Retain":bool?;
}
opcua.read_events(name: String, nodeIds: Array<String>, callback_data: function, callback_error: function)
Description: Creates an event-based subscription for the specified nodes, registered under name. Same lifetime and naming rules as subscribe(), including the shared name space: a name used by one cannot be used by the other.
Parameters:
- name: a unique name for this subscription. Raises if it is empty or already taken.
- nodeIds: an array of node identifiers to subscribe to.
- callback_data: a function called whenever a new event arrives, with the signature:
(name: String, node_id: String, event: OpcuaEvent) - callback_error: a function called on subscription errors, with the signature:
(name: String, error: String)
Example:
fn on_data(name: String, node_id: String, event: OpcuaEvent){
println(event);
}
fn on_error(name: String, error: String){
println("${name} failed: ${error}");
}
fn main() {
var opcua = OpcuaClient {
url: "opc.tcp://opcua.demo-this.com:62544/Quickstarts/AlarmConditionServer",
security_mode: OpcuaSecurityMode::None,
security_policy: OpcuaSecurityPolicy::None,
};
opcua.read_events("alarms", Array<String>{"ns=2;s=0:West/Blue"}, project::on_data, project::on_error);
}
Running with greycat serve:
6 ns=2;s=0:West/Red OpcuaEvent{EventId:"0f0d42438be93b46a4da3b00f23d66bf",EventType:"i=10751",Message:Tuple{x:"",y:"The alarm was deactivated by the system."},SourceNode:"ns=2;s=1:Colours/NorthMotor",SourceName:"NorthMotor",Time:'2025-10-29T14:17:22.613960Z',ReceiveTime:'2025-10-29T14:17:22.613960Z',Severity:100,ConditionName:"Green",ActiveState:Tuple{x:"en-US",y:"Inactive"},Retain:false}
6 ns=2;s=0:West/Red OpcuaEvent{EventId:"9b296352c45fdb4bb3ca3994baeab2a1",EventType:"i=9764",Message:Tuple{x:"",y:"The alarm was deactivated by the system."},SourceNode:"ns=2;s=1:Metals/SouthMotor",SourceName:"SouthMotor",Time:'2025-10-29T14:17:22.613960Z',ReceiveTime:'2025-10-29T14:17:22.613960Z',Severity:100,ConditionName:"Gold",ActiveState:Tuple{x:"en-US",y:"Active"},Retain:true}
6 ns=2;s=0:West/Red OpcuaEvent{EventId:"be43df78cd55eb42957d18a0d25b59b1",EventType:"i=9764",Message:Tuple{x:"",y:"The alarm severity has increased."},SourceNode:"ns=2;s=1:Colours/NorthMotor",SourceName:"NorthMotor",Time:'2025-10-29T14:17:24.627501Z',ReceiveTime:'2025-10-29T14:17:24.627501Z',Severity:700,ConditionName:"Red",ActiveState:Tuple{x:"en-US",y:"Active"},Retain:true}
cancel_subscription
OpcuaClient::cancel_subscription(name: String): bool
Description: Cancels the subscription registered under name. Static, so it needs no client — which is the point: the client that created the subscription may be long gone.
Returns true if a subscription of that name was registered. The name is free for reuse as soon as the call returns; the server-side deletion is sent asynchronously afterwards.
if (!OpcuaClient::cancel_subscription("strings")) {
println("nothing was registered under that name");
}
cancel_all_subscriptions
OpcuaClient::cancel_all_subscriptions(): int
Description: Cancels every registered subscription and returns how many there were.
subscriptions
OpcuaClient::subscriptions(): Array<OpcuaSubscriptionInfo>
Description: Lists every registered subscription, in no particular order. Since a subscription outlives the client that created it, this is how you find one again.
type OpcuaSubscriptionInfo {
/// The name passed to subscribe() or read_events()
name: String;
/// Endpoint the subscription is connected to
url: String;
/// Node identifiers being monitored
node_ids: Array<String>;
/// False for a value-change subscription, true for an event/alarm one
events: bool;
/// When subscribe()/read_events() was called
created: time;
}
for (_, info in OpcuaClient::subscriptions()) {
println("${info.name} -> ${info.url} (${info.node_ids.size()} nodes, events=${info.events})");
}
Writing Node Values in OPC UA
In Industry 4.0, the ability to write data back to machines after applying analytics or machine learning is key. It allows proactive maintenance by stopping machines or raising alarms when anomalies are detected. It also enables smarter operations—machines can adjust their behavior autonomously using aggregated data or ML results. Finally, fine-tuning parameters in real time ensures optimal performance and efficiency, adapting quickly to changing production needs or quality requirements.
The OpcuaClient offers a write method to send data to an OPC UA device. To use it, the node must be writable, the OPC UA user needs write permissions, and the value provided must match the node’s data type.
write(nodeId: String, value:any)
The following types can be written on devices:
| OPC UA Type | Expected GreyCat type |
|---|---|
| Boolean | bool |
| SByte | int |
| Byte | int |
| Int16 | int |
| UInt16 | int |
| Int32 | int |
| UInt32 | int |
| Int64 | int |
| UInt64 | int |
| Float | float |
| Double | float |
| String | String |
| DateTime | time |
| ByteString | String |
| XmlElement | String |
| Guid | String |
| StatusCode | int |
| NodeId | String |
| ExpandedNodeId | String |
| QualifiedName | Tuple<int, String> |
| LocalizedText | Tuple<String, String> |
| ExtensionObject | NOT SUPPORTED |
| DataValue | NOT SUPPORTED |
| Variant | NOT SUPPORTED |
| DiagnosticInfo | NOT SUPPORTED |
Calling OPC-UA methods
The call method is used to invoke methods on OPC UA nodes. This method requires two parameters: the OPC UA node identifier and an array of parameters to pass to the method.
opcua.call(nodeId: String, parameters:Array<any>):any?
Error management
Read
You may want to protect the read calls with try{} catch {}. The plugin
will raise runtime exceptions on:
- Unable to read client key and/or certificate
- Unable to connect to the OPC UA server
- OPC UA responses with a StatusCode != Good
- Unable to convert an ExpandedNodeId to a String
- Unsupported OPCUA type
- Unable to parse the node id
Write
You may want to protect the read calls with try{} catch {}. The plugin
will raise runtime exceptions on:
- Unable to read client key and/or certificate
- Unable to connect to the OPC UA server
- OPC UA responses with a StatusCode != Good
- Unsupported OPC UA type for writing
- Unable to find the OPC UA node type
- Unable to serialize the GreyCat value
- Unsupported GreyCat type for a given OPC UA type
- Overflow on OPC UA type
- Unable to parse the node id
OpcuaSecurityMode
In OPC UA, security is an essential aspect to ensure the integrity, confidentiality, and authenticity of data exchange between clients and servers. OPC UA offers several security modes that dictate how communication is secured between parties. Here’s an explanation of the differences between the “None,” “Sign,” and “SignAndEncrypt” security modes:
OpcuaSecurityMode::None
- In this mode, no encryption or digital signatures are applied to the communication.
- Data is transmitted in plaintext, making it vulnerable to interception and tampering.
- This mode is suitable for environments where security is not a concern, such as local testing or isolated networks. However, it should not be used in production environments where data confidentiality and integrity are paramount.
OpcuaSecurityMode::Sign
- In this mode, digital signatures are applied to the communication but encryption is not used.
- Data remains in plaintext, but each message is signed with a cryptographic signature to ensure its integrity and authenticity.
- While this mode provides some level of security by preventing tampering with data, it does not protect data confidentiality. It is suitable for scenarios where data confidentiality is not a requirement, but data integrity and authenticity are important.
OpcuaSecurityMode::SignAndEncrypt
- This mode offers the highest level of security by both signing and encrypting communication.
- Data is encrypted before transmission, ensuring confidentiality, and each message is signed to ensure its integrity and authenticity.
- SignAndEncrypt mode provides comprehensive protection against eavesdropping, tampering, and unauthorized access, making it suitable for environments where data security is critical, such as industrial control systems and IIoT applications.
OpcuaSecurityPolicy
OpcuaSecurityPolicy::Aes128_Sha256_RsaOaep
- This security policy utilizes AES (Advanced Encryption Standard) with a key length of 128 bits for encryption, SHA-256 (Secure Hash Algorithm 256) for hashing, and RSA-OAEP (RSA Optimal Asymmetric Encryption Padding) for asymmetric encryption.
- SHA-256 is a cryptographic hash function that produces a 256-bit (32-byte) hash value, ensuring data integrity.
- RSA-OAEP is an asymmetric encryption scheme based on RSA, providing secure encryption and decryption of data.
OpcuaSecurityPolicy::Aes256_Sha256_RsaPss
- This security policy is similar to Aes128_Sha256_RsaOaep but uses AES with a key length of 256 bits for encryption.
- AES-256 offers stronger encryption compared to AES-128, suitable for environments requiring higher security levels.
OpcuaSecurityPolicy::Basic128Rsa15
- This security policy utilizes Basic128 encryption and RSA with PKCS#1 v1.5 padding for asymmetric encryption.
- Basic128 refers to AES with a key length of 128 bits for encryption, providing basic security measures.
- RSA15 refers to RSA encryption with PKCS#1 v1.5 padding, an older encryption scheme that is less secure than RSA-OAEP.
Attention Since the hash algorithm SHA1 is not considered secure anymore, this Security Policy has been deprecated with the OPC UA Specification Version 1.04.
OpcuaSecurityPolicy::Basic256
- This security policy uses AES with a key length of 256 bits for encryption without specifying the hash and asymmetric encryption algorithms.
- While it provides stronger encryption compared to Basic128, it lacks specificity regarding hashing and asymmetric encryption algorithms.
Attention Since the hash algorithm SHA1 is not considered secure anymore, this Security Policy has been deprecated with the OPC UA Specification Version 1.04.
OpcuaSecurityPolicy::Basic256Sha256
- Similar to Basic256, this security policy uses AES with a key length of 256 bits for encryption.
- Additionally, it specifies SHA-256 for hashing, enhancing data integrity compared to Basic256.
OpcuaSecurityPolicy::None
- This security policy indicates that no security measures are applied to communication.
- It should only be used in environments where security is not a concern, such as local testing or isolated networks.
OpcuaCertificate
The OpcuaCertificate type represents a certificate used for OPC UA connections.
path: String: Specifies the file path to the certificate.private_key_path: String: Specifies the file path to the private key associated with the certificate.application_uri: String?: (Optional) Represents the application URI associated with the certificate.allow_self_signed: bool?: (Optional) Indicates whether self-signed certificates are allowed. Iftrue, self-signed certificates are permitted; iffalseor not specified, they are not allowed.
OpcuaCredentials
The OpcuaCredentials type represents credentials used for authentication in OPC UA connections.
login: String: Specifies the login or username associated with the credentials.password: String: Specifies the password associated with the credentials.
Log levels
| GreyCat Log Level | Open62541 Log Level |
|---|---|
error |
error |
warn |
warn |
trace |
debug |
| all others | off |
Third party licenses
open62541 (https://www.open62541.org/)
This plugin uses internally open62541, an Open Source OPC UA licensed under the MPL v2.0
openssl (https://www.openssl.org/)
open62541 is built with openssl to perform the encryption. Openssl is licensed under Apache-2.0 license.