Secure device registration

Devices published on the SmartThings catalog should communicate securely with the platform. Consider how to secure your devices before distributing them to end-users.

Two types of secure registration are supported:

  • X.509 certificate is a digital certificate that uses the widely accepted international X.509 public key infrastructure (PKI) standard to verify that a public key belongs to the user, computer or service identity contained within the certificate.

  • ED25519 is a public-key signature system. ED25519 is an elliptic curve signature scheme that offers better security than ECDSA and DSA and good performance. It may be used for both user and host keys.

Device identity

A device identity consists of the certificate or public key pairs that are unique to the device. These must be generated and stored in the secure element of the device in the manufacturing phase.

The device identity is used when SmartThings Cloud checks that a device is authenticated, and it helps protect your device from unauthorized device control and information leaks.

For certification

For certification review, your device identity should be registered into SmartThings Cloud. Because our certification experts can only test devices with valid device identities in SmartThings Cloud.

You can register the required information of your device identity in the step of certification request as follows:

  1. Go to Publish > Direct-connected Device.
  2. Click + NEW.
  3. Go to the step of setting device information.
  4. In the Device identity type field, select X.509 (Certificate) or ED25519 (Raw public key).
  • X.509 (Certificate) X.509 (Certificate)
  • ED25519 (Raw public key) ED25519 (Raw public key)
  1. Enter the required information for your device identities.
  • If your device uses X.509 certificate, enter the UUID (Universally Unique Identifier) of your device. A UUID can be used to identify a device.
  • If your device uses ED25519 public key, enter a serial number, a public key, and a validation signature for your device.

For publication

To publish certified devices, their device identities should be registered on SmartThings Cloud.

Developer Workspace allows you to register the required information of your device identities in bulk, after certifying your device, as follows:

  1. Go to Publish > Direct-connected Device. You can show your publication requests in the list.
  2. In the list, click the device name for which you want to register its security information. Click the device name
  3. Click Device identity tab. If your device is not certified, Device identity tab isn't shown. Device identity tab
  4. Download and complete the .csv form that corresponds to your device identity type (X.509 or ED25519).
  5. Click + NEW. New
  6. Upload the .csv file including your device identity information.

How to generate validation signatures

If your device uses an ED25519 raw public key, you should register validation signatures with serial numbers and public keys. The validation signature is to validate your public key and private key.

You can get a validation signature using generateValidationSignature() API from this Java program we offer.

Sample code

public class ED25519 {

     /* Generate ED25519 key pairs (private / public key) in hex string form */
    public static KeyPairHex generateKeyPair()
    {
        // Generate Keypair
        KeyPairGenerator keyPairGenerator = new KeyPairGenerator();
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // Convert Private Key to Raw format (32 byte)
        EdDSAPrivateKey privateKey = (EdDSAPrivateKey)keyPair.getPrivate();
        byte[] privateKeyRaw = privateKey.getSeed();

        // Convert Public Key to Raw format (32 byte)
        EdDSAPublicKey publicKey = (EdDSAPublicKey)keyPair.getPublic();
        byte[] publicKeyRaw = publicKey.getAbyte();

        // Convert endian
        byte[] privateKeyRawBigEndian = convertEndian(privateKeyRaw);
        byte[] publicKeyRawBigEndian = convertEndian(publicKeyRaw);

        KeyPairHex keyPairHex = new KeyPairHex(byteArrayToHex(privateKeyRawBigEndian), byteArrayToHex(publicKeyRawBigEndian));

        return keyPairHex;
    }

    /* Generate validation signature with private key and 32 byte message filled with 0 value */
    public static String generateValidationSignature(String privateKeyHex) {

        // 32 byte message filled with 0 value
        // It is used to generate validation signature
        byte[] message = new byte[32];
        for(int i=0;i<message.length;i++)
            message[i] = 0x00;

        String signatureStr = null;

        // Convert private key to little endian byte
        byte[] bigEndianPrivateKey = hexStringToByteArray(privateKeyHex);
        byte[] littleEndianPrivateKey = convertEndian(bigEndianPrivateKey);

        try {
            EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
            Signature sig = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));

            EdDSAPrivateKeySpec privateKeySpec = new EdDSAPrivateKeySpec(littleEndianPrivateKey, spec);
            PrivateKey privateKey = new EdDSAPrivateKey(privateKeySpec);

            // Set private key
            sig.initSign(privateKey);
            // Set 0 value message
            sig.update(message);
            // Generate validation signature
            byte[] signature = sig.sign();

            signatureStr = byteArrayToHex(signature);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }

        return signatureStr;
    }

    /* Verify validation signature with public key and 32 byte message filled with 0 value */
    public static boolean verifyValidationSignature(String publicKeyStr, String signatureStr) {

        // 32 byte message filled with 0 value
        // It is used to verify validation signature
        byte[] message = new byte[32];
        for(int i=0;i<message.length;i++)
            message[i] = 0x00;

        boolean validity = false;

        // Convert public key to little endian byte
        byte[] bigEndianPublicKey = hexStringToByteArray(publicKeyStr);
        byte[] littleEndianPublicKey = convertEndian(bigEndianPublicKey);

        // Convert signature to byte
        byte[] signature = hexStringToByteArray(signatureStr);

        try {
            EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.ED_25519);
            Signature sig = new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));

            EdDSAPublicKeySpec publicKeySpec = new EdDSAPublicKeySpec(littleEndianPublicKey, spec);
            PublicKey publicKey = new EdDSAPublicKey(publicKeySpec);

            // Set public key to verify signature
            sig.initVerify(publicKey);
            // Set 0 value message to verify signature
            sig.update(message);
            // Verify validation signature
            validity = sig.verify(signature);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }

        return validity;
    }
}