Reputation: 1
I have a recent issue with DPS registration requests, giving me error " {"Message":"{"errorCode":401002,"message":"The specified SAS token has an invalid signature. It does not match either the primary or secondary key.","trackingId":"E377D48366F943E189A5FEA744D89D95-G2:-TimeStamp:2025-01-03T14:15:03.453324531Z","timestampUtc":"2025-01-03T14:15:03.453324531Z","info":null}","ExceptionMessage":""}".
I have two different IoT Hub in different environments, and my devices are running IoT Edge with group enrollments symmetric keys, but Azure Identidy daemon seems to only be able to register in one of the DPS environments. For this other one, I have that error. I already tried to regenerate the keys. It has been working for many months now, but all of a sudden it doesn't work anymore in that environment. And I can't remember changing anything in the setup.
Thanks for helping
Upvotes: 0
Views: 65
Reputation: 1
After being provided some help with the Azure support team, it appears that the error came from DPS not being able to communicate with the linked IoT Hub. That link was broken, but no flag is given on the DPS so I had no chance to find the issue.
The user friendly way of recovering this is to delete the link from the DPS tab, and recreate it. With Azure CLI, here's how to update the iot hub connection string registered by DPS:
az iot dps update --name MyExampleDps --set properties.iotHubs[0].connectionString="HostName=MyExampleHub-2.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=NewTokenValue"
(Taken from documentation https://learn.microsoft.com/en-us/azure/iot-dps/how-to-manage-linked-iot-hubs?tabs=cli#update-keys-for-linked-iot-hubs )
Upvotes: 0
Reputation: 3639
The error indicates that the SAS token signature used for authenticating with the Azure Device Provisioning Service (DPS) is either invalid or expired.
Below is the code to generate a SAS token:
public static async Task Main(string[] args)
{
Parameters parameters = null;
ParserResult<Parameters> parserResult = Parser.Default.ParseArguments<Parameters>(args)
.WithParsed(parsedParams => parameters = parsedParams)
.WithNotParsed(errors => Environment.Exit(1));
Console.WriteLine("Creating SAS credential...");
try
{
TimeSpan tokenValidity = TimeSpan.FromHours(1);
DateTime expiresOn = DateTime.UtcNow.Add(tokenValidity);
// Generate SAS token
string sasToken = GenerateSasToken(
parameters.HostName,
parameters.SharedAccessKey,
parameters.SharedAccessKeyName,
expiresOn
);
AzureSasCredential sasCredential = new AzureSasCredential(sasToken);
ProvisioningServiceClient provisioningServiceClient =
ProvisioningServiceClient.Create(parameters.HostName, sasCredential);
Console.WriteLine("SAS credential successfully created.");
var sample = new ProvisioningRoleBasedAuthenticationSample(provisioningServiceClient);
await sample.RunSampleAsync();
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
}
private static string GenerateSasToken(string resourceUri, string sharedAccessKey, string policyName, DateTime expiresOn)
{
DateTime epochTime = new DateTime(1970, 1, 1);
TimeSpan secondsFromEpochTime = expiresOn.Subtract(epochTime);
long seconds = Convert.ToInt64(secondsFromEpochTime.TotalSeconds, CultureInfo.InvariantCulture);
string expiry = seconds.ToString(CultureInfo.InvariantCulture);
string stringToSign = $"{WebUtility.UrlEncode(resourceUri)}\n{expiry}";
using (HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(sharedAccessKey)))
{
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
string token = $"SharedAccessSignature sr={WebUtility.UrlEncode(resourceUri)}&sig={WebUtility.UrlEncode(signature)}&se={expiry}";
Console.WriteLine("sas token"+token);
if (!string.IsNullOrWhiteSpace(policyName))
{
token += $"&skn={policyName}";
}
return token;
}
}
}
Refer to this link for information on symmetric key attestation with Azure IoT Hub Device Provisioning Service.
Below is to create a new enrollment group:
public async Task CreateEnrollmentGroupAsync()
{
Console.WriteLine("Creating a new enrollment group...");
Attestation attestation = new SymmetricKeyAttestation(null, null); // let the service generate keys
var group = new EnrollmentGroup(s_enrollmentGroupId, attestation);
group = await _provisioningServiceClient.CreateOrUpdateEnrollmentGroupAsync(group);
Console.WriteLine($"Created {group.EnrollmentGroupId}: {JsonConvert.SerializeObject(group)}");
}
Refer to this link for the full code for the
EnrollmentGroup
.Refer to this so for Iot edge with dps
Output:
Upvotes: 0