Updates: Check the release notes for new features and product updates.

Private/public key pairs

Private/public key pairs enable agents and the users' devices to create message hashes specific to conversations with each other. By using private/public key pairs, agents and the Message app can compute shared secrets and securely hash message content, making the content unreadable to Verified SMS and Google.

After you create an agent, you need to create the agent's key pair and update the agent's public key with Verified SMS. Once your agent is running, you need to get users' public keys before you can send them verified messages.

User public keys

When you're ready to send a verified message, you need to get a Verified SMS-enabled recipient's public key before you can create and store the message hash. You can get up to 10,000 public keys in a single API call.

Occasionally, the Messages app rotates public keys, so you need to get a user's public key before sending them any message, even if you've sent verified messages to the user previously. If you create a message hash with an outdated public key, the Messages app generates a hash with the current public key, resulting in a hash mismatch. If Verified SMS can't match message hashes, your message appears as unverified.

The Verified SMS Sample and SDK can get public keys for Verified SMS-enabled users when you store hashes. If you choose to not use the Sample and SDK, the following code gets one or more users' public keys. For formatting and value options, see enabledUserKeys.batchGet.

When a user's phone number isn't enabled for Verified SMS, Verified SMS doesn't return any public keys for that phone number.

curl -X POST "https://verifiedsms.googleapis.com/v1/enabledUserKeys:batchGet" \
  -H "Content-Type: application/json" \
  -H "User-Agent: curl/verified-sms" \
  -H "`oauth2l header --json PATH_TO_SERVICE_ACCOUNT_KEY verifiedsms`" \
  -d "{
    'phoneNumbers': [
      'PHONE_NUMBER',
      'PHONE_NUMBER',
      'PHONE_NUMBER',
    ]
  }"

Agent private/public key pairs

Agents use their private keys and users' public keys during messaging hashing to obfuscate message content, and the Messages app uses users' private keys and agents' public keys. For a Verified SMS agent to function, the agent needs to create a key pair and share its current public key with Verified SMS so that the Message app can access it.

Create an agent's key pair

To create a key pair for your agent, run the following commands in a terminal.

openssl ecparam -name secp384r1 -genkey -outform PEM -noout -out verified-sms-AGENT_NAME-private-key-P-384.pem
openssl pkcs8 -topk8 -nocrypt -in verified-sms-AGENT_NAME-private-key-P-384.pem -outform DER -out verified-sms-AGENT_NAME-private-key-P-384-pkcs8.der
openssl ec -in verified-sms-AGENT_NAME-private-key-P-384.pem -pubout -outform DER -out verified-sms-AGENT_NAME-public-key-P-384.der

The commands generate three files:

  • verified-sms-AGENT_NAME-private-key-P-384.pem is a private key in PEM format that isn't used but is important to keep as a reference.
  • verified-sms-AGENT_NAME-private-key-P-384-pkcs8.der is a private key used by the SDK to create message hashes. Don't share this key with Verified SMS.
  • verified-sms-AGENT_NAME-public-key-P-384.der is a public key used by the Messages app to create message hashes for messages from your agent. Required to create your agent.

Store your private key files somewhere secure but available to your infrastructure. Never share your private keys.

Now that you've created keys for your agent, you need to update your agent's public key with Verified SMS.

Update an agent's public key

You can change your agent's private/public key pair at any time. Whether to comply with security requirements or rotate out a compromised key pair, updating your agent's key is as simple as creating a new key pair and updating your agent's public key with Verified SMS.

Consider updating keys no more than once per week so that all hashes for the three previous weeks remain valid in case of late message delivery.

The following processes and code update an agent's public key. For formatting and value options, see agents.updateKey.

Developer Console

  1. Base64-encode your agent's public key and note the value.
  2. Open the Business Communications Developer Console and sign in with your Verified SMS Google account.
  3. Click your agent.
  4. In the left navigation, click Agent information.
  5. For Agent public key, enter your Base64-encoded public key.
  6. Click Save.

cURL

curl -X PATCH "https://verifiedsms.googleapis.com/v1/agents/AGENT_ID/key" \
  -H "Content-Type: application/json" \
  -H "User-Agent: curl/verified-sms" \
  -H "`oauth2l header --json PATH_TO_SERVICE_ACCOUNT_KEY verifiedsms`" \
  -d "{
    'name': 'AGENT_ID',
    'publicKey': 'BASE64-ENCODED_PUBLIC_KEY'
  }"

Java

  1. In a terminal, set the necessary environment variables.

    export VERIFIED_SMS_PUBLIC_KEY_PATH="PATH_TO_PUBLIC_KEY.DER"
    export VERIFIED_SMS_PRIVATE_KEY_PATH="PATH_TO_PRIVATE_KEY_PKCS8.DER"
    export VERIFIED_SMS_SERVICE_ACCOUNT_PATH="PATH_TO_SERVICE_ACCOUNT_KEY.JSON"
    
  2. Edit and run code based on the following sample.

    String agentId = getEnvVariable("VERIFIED_SMS_AGENT_ID");
    String publicKeyPath = getEnvVariable("VERIFIED_SMS_PUBLIC_KEY_PATH");
    String serviceAccountJson = getEnvVariable("VERIFIED_SMS_SERVICE_ACCOUNT_PATH");
    
    LOGGER.info("Reading credentials/creating client ... ");
    VerifiedSmsServiceClient verifiedSmsServiceClient =
            new VerifiedSmsServiceClient.Builder()
            .setServiceAccountKeyStream(new FileInputStream(serviceAccountJson))
            .build();
    
    LOGGER.info("Reading public key... ");
    byte[] publicKeyBytes = Files.readAllBytes(Paths.get(publicKeyPath));
    
    LOGGER.info("Updating agent's public key in asynchronous way...");
    CountDownLatch latch = new CountDownLatch(1);
    verifiedSmsServiceClient.updateKey(
            agentId,
            publicKeyBytes,
            new VerifiedSmsCompletionCallback() {
                @Override
                public void onSuccess() {
                    LOGGER.info("Updating key completed.");
                    latch.countDown();
                }
    
                @Override
                public void onFailure(Throwable t) {
                    LOGGER.warning("  Updating key failed: " + t);
                    latch.countDown();
                }
            });
    
    latch.await(); // Wait for callback to be completed.
    
    LOGGER.info("Shutting down the service...");
    verifiedSmsServiceClient.shutdown();
    
    This code is an excerpt from the Verified SMS Sample and SDK.

Python

  1. In a terminal, set the necessary environment variables.

    export VERIFIED_SMS_PUBLIC_KEY_PATH="PATH_TO_PUBLIC_KEY.DER"
    export VERIFIED_SMS_PRIVATE_KEY_PATH="PATH_TO_PRIVATE_KEY_PKCS8.DER"
    export VERIFIED_SMS_SERVICE_ACCOUNT_PATH="PATH_TO_SERVICE_ACCOUNT_KEY.JSON"
    
  2. Edit and run code based on the following sample.

    import os
    from verified_sms_client_library.verified_sms_service_client import VerifiedSmsServiceClient
    
    def main():
        # Read environment variables
        agent_id = os.environ['VERIFIED_SMS_AGENT_ID']
        public_key_path = os.environ['VERIFIED_SMS_PUBLIC_KEY_PATH']
        service_account_location = os.environ['VERIFIED_SMS_SERVICE_ACCOUNT_PATH']
    
        # Read the private key file
        with open(public_key_path, mode='rb') as file:
            print('Reading the agent\'s public key ...')
            public_key_as_bytes = file.read()
    
            print('Creating the Verified SMS Api Client ...')
            vsms_service_client = VerifiedSmsServiceClient(service_account_location=service_account_location)
    
            print('Updating agent\'s public key')
            vsms_service_client.update_key(agent_id, public_key_as_bytes)
    
    This code is an excerpt from the Verified SMS Sample and SDK.

Node.js

  1. In a terminal, set the necessary environment variables.

    export VERIFIED_SMS_PUBLIC_KEY_PATH="PATH_TO_PUBLIC_KEY.DER"
    export VERIFIED_SMS_PRIVATE_KEY_PATH="PATH_TO_PRIVATE_KEY_PKCS8.DER"
    export VERIFIED_SMS_SERVICE_ACCOUNT_PATH="PATH_TO_SERVICE_ACCOUNT_KEY.JSON"
    
  2. Edit and run code based on the following sample.

    const fs = require('fs');
    const verifiedSmsServiceClient = require('./lib/verified_sms_client_library/verfied_sms_service_client');
    
    // Read environment variables to run sample
    let agentId = process.env.VERIFIED_SMS_AGENT_ID;
    let publicKeyPath = process.env.VERIFIED_SMS_PUBLIC_KEY_PATH;
    let serviceAccountLocation = process.env.VERIFIED_SMS_SERVICE_ACCOUNT_PATH;
    
    // Convert into types needed for client library
    let serviceAccountAsJson = require(serviceAccountLocation);
    
    console.log('Reading public key...');
    let publicKeyAsBytes = fs.readFileSync(publicKeyPath);
    let publicKey = publicKeyAsBytes.toString('base64');
    
    function updateKey() {
        console.log('Initializing the Verified SMS Service Client...');
        verifiedSmsServiceClient.initWithServiceAccount(serviceAccountAsJson);
        let updateKeyPromise = verifiedSmsServiceClient.updateKey(agentId, publicKey);
    
        console.log('Updating agent\'s public key...');
        updateKeyPromise.then((response) => {
            console.log(response);
        })
        .catch((err) => {
          console.log(err);
        });
    }
    
    module.exports = updateKey;
    
    This code is an excerpt from the Verified SMS Sample and SDK.

Base64-encode an agent's public key

At some point, such as if you update your agent's public key in the Developer Console, you may need to represent a public key as text. To generate a text-based representation of your key, use the base64 command in a terminal.

The following code generates a base64-encoded string of an agent's public key, as generated in Create an agent's key pair.

base64 verified-sms-AGENT_NAME-public-key-P-384.der

Get an agent's public key

If you're unsure which public key is registered with Verified SMS, you can get the agent's current registered public key. If the public key from the key pair you're using with your agent doesn't match the public key registered with Verified SMS, hashes you create and store may not be valid and may result in unverified messages.

The key registered with Verified SMS might not match your public key for two reasons:

  • You're using an old public/private key pair. Locate and use the key pair that matches the public key registered with Verified SMS.
  • You created a new key pair but didn't update the public key with Verified SMS. Update your public key.

When the public keys match, you're ready to begin hashing messages.

The following code gets an agent's public key. For formatting and value options, see agents.getKey.

curl -X GET "https://verifiedsms.googleapis.com/v1/agents/AGENT_ID/key" \
  -H "Content-Type: application/json" \
  -H "User-Agent: curl/verified-sms" \
  -H "`oauth2l header --json PATH_TO_SERVICE_ACCOUNT_KEY verifiedsms`"

Next steps

Now that your agent can fetch user public keys and has a public key registered with Verified SMS, you're ready to configure message hashing.