Security is a critical concern when deploying and managing IoT devices. Cloud IoT Core offers the following security features:
- Per-device public/private key authentication using JSON Web Tokens (JWTs, RFC 7519).
- This limits the surface area of an attack, because a compromised key would affect only a single device and not the whole fleet.
- JWTs are valid for a limited duration, so any compromised keys will expire.
- Support for RSA or Elliptic Curve algorithms to verify signatures, with enforcement for strong key sizes.
- Support to rotate keys per device by allowing concurrent keys to be registered, and support for expiration time per credential.
- TLS 1.2 connection, using root certificate authorities (required for MQTT).
- Cloud IoT Core API access is controlled by Identity and Access Management (IAM) roles and permissions.
The following diagram summarizes the process for provisioning device credentials. The authenticated "provisioner," who is often the user configuring the device, is assumed to have created a project and a registry, and to have permissions to create devices. The provisioner uses the Cloud IoT Core API, gcloud commands, or the Cloud Platform Console to create a logical device in the cloud.
- The public-private key pair is generated by the provisioner.
- The provisioner creates the device using the Cloud IoT Core API, gcloud commands, or the Cloud Platform Console, specifying the public key just created. This will be used to verify the device's identity.
- The Cloud IoT Core device manager stores the device resource and the public key.
- The device manager responds to the provisioner, indicating that the device was created.
- The private key is stored on the device to use later for authentication. The hardware Trusted Platform Module (TPM) can be used for this step.
Note that the order of steps shown here is not prescriptive. For example, the key can be stored on the device before the device has been registered in Cloud IoT Core.
For information on creating keys, see Creating Key Pairs.
The following diagram summarizes authentication in Cloud IoT Core using MQTT:
- The device prepares a JSON Web Token (JWT), as described in Using JSON Web Tokens. The JWT is signed with the private key from the authentication flow.
- When connecting to the MQTT bridge, the device presents the JWT as the password in the MQTT
CONNECTmessage. The username content is ignored; however, some MQTT client libraries will not send the password unless the username is specified. For best results, set the username to an arbitrary value like
- The MQTT bridge verifies the JWT against the device's public key.
- The MQTT bridge accepts the connection.
- The connection is closed when the JWT expires (after accounting for the allowed clock drift).
Cloud IoT Core uses digital signature–based authentication, for both RSA and Elliptic Curve signed tokens. The following specific algorithms are supported:
RS256(RSASSA-PKCS1-v1_5 using SHA-256 RFC 7518 sec 3.3)
ES256(ECDSA using P-256 and SHA-256 RFC 7518 sec 3.4), defined in OpenSSL as the prime256v1 curve
The RSA algorithm is commonly used and is widely supported by client libraries. However, the generated keys and signatures can be quite large (generally on the order of one to two kilobytes). Additionally, RSA can use a significant amount of resources (both in terms of key length and CPU), which can affect devices that have limited resources.
The Elliptic Curve algorithm is well supported but is not as widely used as RSA. To use Elliptic Curve, you may have to install additional dependencies in your client library. However, the generated keys and signatures are significantly smaller than those generated by RSA, which can be useful for devices with limited resources.
A minimum of 112 bits of security is required by Cloud IoT Core, following NIST recommendations (Section 5.6.2, pages 55-56). This translates to a minimum 2048-bit key size for RS256 (see Table 2 in the NIST recommendations, page 53).
ES256 has a preset level of 128 bits of security (the key size is fixed).
Public key format
When registering the public key for a device, the key must be in one of the following formats:
|RSA_PEM||An RSA public key encoded in base64. Can be used to verify RS256 signatures in JWT tokens (RFC 7518).|
|RSA_X509_PEM||An RSA_PEM key, encoded in base64, wrapped in an X.509v3 certificate (RFC 5280). The certificate can be self-signed, otherwise Cloud IoT Core can optionally compare the device certificate signature against the registry-level certificates to verify the certificate's origin.|
|ES256_PEM||The public key for the ECDSA algorithm (using P-256 and SHA-256), encoded in base64. Can be used to verify JWT tokens with the ES256 algorithm (RFC 7518). This public key is not wrapped in a certificate; this keeps the key size small, which is one of ES256's main advantages.|
|ES256_X509_PEM||An ES256_PEM key, encoded in base64, wrapped in a X.509v3 certificate (RFC 5280). The certificate can be self-signed, otherwise Cloud IoT Core can optionally compare the device certificate signature against the registry-level certificates to verify the certificate's origin.|
For information on creating keys, see Creating Public/Private Key Pairs.
Cloud IoT Core supports multiple active keys (up to 3 per device) to allow for uninterrupted rotation. The service will try to verify JWTs with each of the active keys, and will accept a connection if any active key matches.
The API allows you to define an
expirationTime for each device credential (public key). After it expires, the key will be ignored, but it will not be automatically deleted. A 10-minute clock-skew allowance applies. If no expiration time is specified for a key, it will never expire.
Device security recommendations
The following security recommendations are not enforced by Cloud IoT Core but will help you secure your devices and connections.
- Keep the private key secret.
- Use TLS 1.2 when communicating with
mqtt.2030.ltsapis.googon ports 8883 and 443. To maintain TLS connections:
- Verify that the server certificate is valid using a Google root CA certificate.
- Perform regular security-related firmware updates to keep server certificates up-to-date.
- Read this security note for detailed TLS requirements and future compatibility.
- Each device should have a unique public/private key pair. If multiple devices share a single key and one of those devices is compromised, an attacker could impersonate all of the devices that have been configured with that one key.
- Keep the public key secure when registering it with Cloud IoT Core. If an attacker can tamper with the public key and trick the provisioner into swapping the public key and registering the wrong public key, the attacker will subsequently be able to authenticate on behalf of the device.
- The key pair used to authenticate the device to Cloud IoT Core should not be used for other purposes or protocols.
- Depending on the device's ability to store keys securely, key pairs should be rotated periodically. When practical, all keys should be discarded when the device is reset.
- If your device runs an operating system, make sure you have a way to securely update it. For devices that don't have an operating system, ensure that you can securely update the device's software if security vulnerabilities are discovered after deployment.
- Ensure that you have a way to update root certificates. For more details, see the Google Internet Authority site.
- Ensure that the clock on the device is not tampered with. If the device clock is compromised, a powerful attacker can trick the device into issuing tokens that will be valid in the future, circumventing the expiration time of the token. For best results, use the Google Public NTP Server.