簡體   English   中英

Azure IOT Hub - 設備安全令牌

[英]Azure IOT Hub - Device Security Token

所以我們使用MQTT連接設備/服務器。 我使用M2Mqtt庫使用模擬客戶端工作。 我真正掙扎的是如何在代碼中生成密碼字段中使用的簽名

我跟着這個https://azure.microsoft.com/en-us/documentation/articles/iot-hub-sas-tokens/然而我正在圍繞HMAC方面做斗爭。 他們談到的“**簽名關鍵**”是什么? 這是設備共享訪問密鑰嗎? 現在只需讓模擬客戶端在代碼中創建自己的簽名(而不是通過設備資源管理器)是至關重要的,我們甚至擔心我們的現場產品是否能夠計算出這一點(對於現場設備來說,這真的過於復雜)。 除了node.js之外,還有一個我可以關注的C#示例 - 這行是什么意思“hmac.update(toSign);”

有沒有更簡單的方法來驗證設備到服務器? 也許只是使用其共享訪問密鑰?

對不起所有的問題:/可能我只需要一步一步指導什么/何時做URI編碼/ Base64編碼/解碼,HMAC 256等因為我認為文檔遠遠不夠。

“{signature} HMAC-SHA256簽名字符串格式為:{URL-encoded-resourceURI} +”\\ n“+ expiry。重要:密鑰從base64解碼並用作執行HMAC-SHA256計算的密鑰。”

https://azure.microsoft.com/en-us/documentation/articles/iot-hub-sas-tokens/頁面包含一個Node.js函數,該函數根據給定的輸入生成SAS令牌。 根據您的說法,您正在使用令牌來啟用設備以連接到您的IoT Hub,因此Node功能的輸入應為:

  • 資源URI:{IoT hub name} .azure-devices.net / devices / {device id}。
  • 簽名密鑰:{device id}身份的任何對稱密鑰。 您可以從IoT Hub設備標識注冊表獲取此密鑰 - 例如,使用DeviceExplorer工具。
  • 沒有政策名稱。
  • 任何到期時間。

終於搞定了:)

    public static string getSaSToken()
    {
        TimeSpan fromEpochStart = DateTime.UtcNow - new DateTime(1970, 1, 1);
        string expiry = Convert.ToString((int)fromEpochStart.TotalSeconds + 3600);

        string baseAddress = "XYZABCBLAH.azure-devices.net/devices/12345".ToLower();
        string stringToSign = WebUtility.UrlEncode(baseAddress).ToLower() + "\n" + expiry;

        byte[] data = Convert.FromBase64String("y2moreblahblahblah=");
        HMACSHA256 hmac = new HMACSHA256(data);
        byte[] poo = hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign));
        string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        string token = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}",
                        WebUtility.UrlEncode(baseAddress).ToLower(), WebUtility.UrlEncode(signature), expiry);

        return token;
    }

“12345”是我們設備的序列號。 y2z的關鍵....將是我們的串口與其他花哨的基礎64組合(只要它在base64格式,使集線器快樂;))

這將有一天對某人有所幫助:

構建Azure IoT Hub的授權標頭

https://github.com/snobu/Azure-IoT-Hub/blob/master/make-token.sh

#!/usr/bin/env bash
#
# GitHub repo:
#    https://github.com/snobu/Azure-IoT-Hub
#
# Construct authorization header for Azure IoT Hub
#    https://azure.microsoft.com/en-us/documentation/articles/iot-hub-devguide/#security
#
# The security token has the following format:
#    SharedAccessSignature sig={signature-string}&se={expiry}&skn={policyName}&sr={URL-encoded-resourceURI}
#
# Author:
#    Adrian Calinescu (a-adcali@microsoft.com), Twitter: @evilSnobu, github.com/snobu
#
# Many things borrowed from:
#    http://stackoverflow.com/questions/20103258/accessing-azure-blob-storage-using-bash-curl
#
# Prereq:
#    OpenSSL
#    npm install underscore -g (for the tidy JSON colorized output) - OPTIONAL
#    Python 2.6 (Might work with 2.5 too)
#    curl (a build from this century should do)

urlencodesafe() {
    # Use urllib to safely urlencode stuff
    python -c "import urllib, sys; print urllib.quote_plus(sys.argv[1])" $1
}

iothub_name="heresthething"
apiversion="2015-08-15-preview"
req_url="${iothub_name}.azure-devices.net/devices?top=100&api-version=${apiversion}"

sas_key="eU2XXXXXXXXXXXXXXXXXXXXXXXXXXXXX="
sas_name="iothubowner"

authorization="SharedAccessSignature"

# 259200 seconds = 72h (Signature is good for the next 72h)
expiry=$(echo $(date +%s)+259200 | bc)
req_url_encoded=$(urlencodesafe $req_url)
string_to_sign="$req_url_encoded\\n$expiry"

# Create the HMAC signature for the Authorization header
#
# In pseudocode:
#      BASE64_ENCODE(HMAC_SHA256($string_to_sign))
#
# With OpenSSL it's a little more work (StackOverflow thread at the top for details)
decoded_hex_key=$(printf %b "$sas_key" | base64 -d -w0 | xxd -p -c256)
signature=$(printf %b "$string_to_sign" | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$decoded_hex_key" -binary | base64 -w0)

# URLencode computed HMAC signature
sig_urlencoded=$(urlencodesafe $signature)

# Print Authorization header
authorization_header="Authorization: $authorization sr=$req_url_encoded&sig=$sig_urlencoded&se=$expiry&skn=$sas_name"

echo -e "\n$authorization_header\n"

# We're ready to make the GET request against azure-devices.net REST API
curl -s -H "$authorization_header" "https://$req_url" | underscore print --color

echo -e "\n"

以及Azure IoT Hub的示例MQTT用戶/傳遞組合(是的,密碼是殘酷的,包括空格):

https://github.com/Azure/azure-content/blob/master/articles/iot-hub/iot-hub-devguide.md#example

用戶名(DeviceId區分大小寫): iothubname.azure-devices.net/DeviceId

密碼(使用設備資源管理器生成SAS): SharedAccessSignature sr=iothubname.azure-devices.net%2fdevices%2fDeviceId&sig=kPszxZZZZZZZZZZZZZZZZZAhLT%2bV7o%3d&se=1487709501

以下是如何在Java中生成SAS令牌:

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class AzureSasTokenCreator
{

    public static void main(String[] args) throws InvalidKeyException, UnsupportedEncodingException,
                    MalformedURLException, NoSuchAlgorithmException
    {
        String token = generateSasTokenForIotDevice("myiothub.azure-devices.net/devices/mydevice",
                        "ZNILSsz4ke0r5DQ8rfB/PBWf6QqWGV7aaT/iICi9WTc=", 3600);

        System.out.println(token);
    }

    private static String generateSasTokenForIotDevice(String uri, String devicePrimaryKey, int validtySeconds)
                    throws UnsupportedEncodingException, MalformedURLException, NoSuchAlgorithmException,
                    InvalidKeyException
    {
        Date now = new Date();
        Date previousDate = new Date(1970);
        long tokenExpirationTime = ((now.getTime() - previousDate.getTime()) / 1000) + validtySeconds;

        String signature = getSignature(uri, tokenExpirationTime, devicePrimaryKey);

        String token = String.format("SharedAccessSignature sr=%s&sig=%s&se=%s", uri, signature,
                        String.valueOf(tokenExpirationTime));

        return token;
    }

    private static String getSignature(String resourceUri, long expiryTime, String devicePrimaryKey)
                    throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException
    {
        byte[] textToSign = new String(resourceUri + "\n" + expiryTime).getBytes();
        byte[] decodedDeviceKey = Base64.getDecoder().decode(devicePrimaryKey);
        byte[] signature = encryptHmacSha256(textToSign, decodedDeviceKey);
        byte[] encryptedSignature = Base64.getEncoder().encode(signature);
        String encryptedSignatureUtf8 = new String(encryptedSignature, StandardCharsets.UTF_8);

        return URLEncoder.encode(encryptedSignatureUtf8, "utf-8");
    }

    private static byte[] encryptHmacSha256(byte[] textToSign, byte[] key)
                    throws NoSuchAlgorithmException, InvalidKeyException

    {
        SecretKeySpec secretKey = new SecretKeySpec(key, "HmacSHA256");
        Mac hMacSha256 = Mac.getInstance("HmacSHA256");
        hMacSha256.init(secretKey);
        return hMacSha256.doFinal(textToSign);
    }
}

另見: https//github.com/Breitmann/AzureSasTokenCreator

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM