PHP2Shell alert: critical PHP flaws CVE-2026-109618 / 109619 — check your servers and get patched fast
HashTech Systems
EV Charging
Part 7 of 11

OCPP 2.0.1 Security: Profiles, Certificates and Signed Firmware

OCPP 2.0.1 security in practice: security profiles 1 to 3, SignCertificate and CertificateSigned, root certificates, security events and signed firmware.

HashTech Engineering · October 26, 2026 · 5 min read

In OCPP 1.6, security was retrofitted through a separate whitepaper (see 1.6 security profiles). In 2.0.1 it is functional block A and part of the core specification: three security profiles, certificate lifecycle messages, a security event log, and signed firmware in block L. If you build a 2.0.1 CSMS, you are building a small certificate management system too.

The three security profiles

ProfileTransportStation authenticates withCSMS authenticates with
1ws:// (no TLS)HTTP Basic AuthNothing
2wss:// TLSHTTP Basic AuthTLS server certificate
3wss:// TLSTLS client certificateTLS server certificate

Profile 1 is only appropriate inside a trusted network such as a private APN or VPN; the password crosses the wire in clear text. Profile 2 is the common baseline for public networks. Profile 3 removes shared passwords entirely and is required by many tenders and by Plug & Charge deployments. TLS 1.2 or higher is required for profiles 2 and 3.

With Basic Auth, the username is the station identity and the password is the SecurityCtrlr.BasicAuthPassword variable. The current profile is SecurityCtrlr.SecurityProfile. Rotating the password (use case A01) is just a SetVariables on BasicAuthPassword; the station then reconnects with the new value. BasicAuthPassword is write-only, so you can never read it back; store it securely on the CSMS side before sending.

json
[2, "sv-pw-1", "SetVariables", {
  "setVariableData": [
    {
      "attributeValue": "q9V2w7Lr0pXc4Zt8MbN1sEe6Hk3Yj5Ua",
      "component": { "name": "SecurityCtrlr" },
      "variable": { "name": "BasicAuthPassword" }
    }
  ]
}]

Upgrading a security profile (A05)

A station must never silently fall back to a lower security profile. To move from profile 2 to 3: install the CSMS root certificate if needed, get a client certificate onto the station (below), write a new network connection profile with securityProfile: 3 to a spare slot, put it first in NetworkConfigurationPriority, and reset. The mechanics of slots and priority are in part 3. Once a station is running a higher profile, it will refuse network profiles with a lower one.

Certificate types

CertificatePurposeManaged with
Charging Station certificateTLS client certificate for profile 3SignCertificate / CertificateSigned (ChargingStationCertificate)
CSMS rootStation verifies the CSMS server certificateInstallCertificate (CSMSRootCertificate)
Manufacturer rootStation verifies firmware signing certificatesInstallCertificate (ManufacturerRootCertificate)
V2G certificate and V2G/MO rootsISO 15118 (Plug & Charge)SignCertificate (V2GCertificate), InstallCertificate (V2GRootCertificate, MORootCertificate)

Getting a client certificate onto the station

The private key is generated on the station and never leaves it. The station sends a certificate signing request, the CSMS has it signed by the operator's CA, and returns the chain. The CSMS can start this with TriggerMessage (A02), or the station starts it itself when its certificate is about to expire (A03).

json
[2, "tm-1", "TriggerMessage", {
  "requestedMessage": "SignChargingStationCertificate"
}]

[2, "sc-1", "SignCertificate", {
  "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBDzCBtgIBADBUMQswCQYDVQQGEwJHQjEVMBMGA1UECgwMRXhhbXBsZSBDUE8x...\n-----END CERTIFICATE REQUEST-----",
  "certificateType": "ChargingStationCertificate"
}]

[3, "sc-1", {
  "status": "Accepted"
}]

The CSMS answers SignCertificate immediately, then later (after the CA signs) sends CertificateSigned with the PEM chain. The station validates it and responds Accepted or Rejected; it uses the new certificate on the next connection.

json
[2, "cs-1", "CertificateSigned", {
  "certificateChain": "-----BEGIN CERTIFICATE-----\nMIICxjCCAa6gAwIBAgIUQ3...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIC2DCCAcCgAwIBAgIUF1...\n-----END CERTIFICATE-----",
  "certificateType": "ChargingStationCertificate"
}]

[3, "cs-1", {
  "status": "Accepted"
}]

On the CSMS side, check the CSR before signing: its subject must identify the station that sent it and the operator organisation configured in SecurityCtrlr.OrganizationName. Never sign a CSR whose subject names a different station; that is exactly the attack the CSR flow is meant to stop. At connect time with profile 3, verify that the client certificate's subject matches the identity in the WebSocket URL.

Root certificates

InstallCertificate adds a root (Accepted, Rejected or Failed). GetInstalledCertificateIds lists installed certificates by type, returning hash data (hashAlgorithm, issuerNameHash, issuerKeyHash, serialNumber). DeleteCertificate removes one by that hash data (Accepted, Failed, NotFound).

json
[2, "dc-4", "DeleteCertificate", {
  "certificateHashData": {
    "hashAlgorithm": "SHA256",
    "issuerNameHash": "8f3d2c1b0a99e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2918070605040302010",
    "issuerKeyHash": "1a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f809",
    "serialNumber": "4f2a9c"
  }
}]

Security events

The station keeps a security log and reports security-relevant events to the CSMS with SecurityEventNotification (A04). The type is a string; the specification lists standard event names (such as FirmwareUpdated, FailedToAuthenticateAtCsms, CsmsFailedToAuthenticate, SettingSystemTime, StartupOfTheDevice, ResetOrReboot, SecurityLogWasCleared, ReconfigurationOfSecurityParameters, InvalidFirmwareSignature, InvalidCsmsCertificate, TamperDetectionActivated) and marks which are critical, meaning they must be pushed to the CSMS rather than only logged.

json
[2, "sen-77", "SecurityEventNotification", {
  "type": "InvalidCsmsCertificate",
  "timestamp": "2026-10-26T08:59:12.000Z",
  "techInfo": "Server certificate not signed by any installed CSMSRootCertificate"
}]

[3, "sen-77", {}]

Route these into your monitoring and SIEM, not just a database table. TamperDetectionActivated and repeated FailedToAuthenticateAtCsms are actionable. The full security log can be fetched with GetLog using logType SecurityLog; the station uploads it to the URL you provide and reports progress with LogStatusNotification.

Signed firmware updates

UpdateFirmware in 2.0.1 always uses the secure format (use case L01). Besides the download location and retrieveDateTime, it carries the firmware signature and the signingCertificate, which the station checks against its installed manufacturer root.

json
[2, "uf-2026-10", "UpdateFirmware", {
  "requestId": 3101,
  "retries": 3,
  "retryInterval": 600,
  "firmware": {
    "location": "https://firmware.example.com/dc150/4.3.0.bin",
    "retrieveDateTime": "2026-10-27T01:00:00.000Z",
    "installDateTime": "2026-10-27T03:00:00.000Z",
    "signingCertificate": "-----BEGIN CERTIFICATE-----\nMIIB9TCCAZugAwIBAgIUa1...\n-----END CERTIFICATE-----",
    "signature": "MEUCIQDf3k2...base64...=="
  }
}]

[3, "uf-2026-10", {
  "status": "Accepted"
}]

The response is Accepted, Rejected, AcceptedCanceled (accepted, and a previous update in progress was cancelled), InvalidCertificate or RevokedCertificate. Progress then arrives as FirmwareStatusNotification messages carrying the same requestId:

StageStatuses
DownloadDownloadScheduled, Downloading, DownloadPaused, Downloaded, DownloadFailed
VerificationSignatureVerified, InvalidSignature
InstallInstallScheduled, Installing, InstallRebooting, Installed, InstallationFailed, InstallVerificationFailed
OtherIdle

After InstallRebooting, expect a BootNotification with reason FirmwareUpdate and the new firmwareVersion. The rollout is complete when you have seen that boot and, ideally, Installed. An InvalidSignature should also produce an InvalidFirmwareSignature security event; treat it as a security incident, not a failed download. For rollout strategy and diagnostics in general, see firmware and diagnostics in 1.6; the operational advice carries over.

Key takeaways

  • Profile 2 is the realistic minimum on public networks; profile 3 removes shared secrets.
  • Never let a station downgrade; upgrade via a new network profile slot and a reset.
  • Generate keys on the station, verify CSR subjects, and rotate roots before server certificates.
  • Treat security events and invalid firmware signatures as alerts, not logs.

Next: ISO 15118 Plug & Charge, which builds on the same certificate machinery. HashTech's charging work includes hardware onboarding and conformance testing for exactly these flows; see EV charging.

Let's Talk

Ready to build something that lasts?

Whether it's a charging network, an AI rollout, or a core enterprise system — let's talk about what you're building.