Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Azure IOT中心-设备安全令牌_C#_Azure_Mqtt_Hmac_Azure Iot Hub - Fatal编程技术网

C# Azure IOT中心-设备安全令牌

C# Azure IOT中心-设备安全令牌,c#,azure,mqtt,hmac,azure-iot-hub,C#,Azure,Mqtt,Hmac,Azure Iot Hub,因此,我们使用MQTT连接设备/服务器。我使用M2Mqtt库的模拟客户机使一切正常工作。我真正需要解决的是如何在代码中生成密码字段中使用的签名 我遵循这一点,但我周围的HMAC方面的事情斗争。他们谈论的“**签名键**”是什么?这是设备共享访问密钥吗?现在,让模拟客户机在代码中创建自己的签名(而不是通过设备浏览器)是非常必要的,这样我们才能担心我们在现场的产品是否能够计算它(发现这对于现场设备来说太复杂了)。除了node.js之外,我还可以在其他地方学习一个C#示例-这一行是什么意思“hmac.

因此,我们使用MQTT连接设备/服务器。我使用M2Mqtt库的模拟客户机使一切正常工作。我真正需要解决的是如何在代码中生成密码字段中使用的签名

我遵循这一点,但我周围的HMAC方面的事情斗争。他们谈论的“**签名键**”是什么?这是设备共享访问密钥吗?现在,让模拟客户机在代码中创建自己的签名(而不是通过设备浏览器)是非常必要的,这样我们才能担心我们在现场的产品是否能够计算它(发现这对于现场设备来说太复杂了)。除了node.js之外,我还可以在其他地方学习一个C#示例-这一行是什么意思“hmac.update(toSign);”

有没有更简单的方法向服务器验证设备?也许只是使用它的共享访问密钥

对于所有的问题,我很抱歉:/可能我只需要一个关于什么/什么时候做URI编码/Base64编码/解码、HMAC 256等的分步指南,因为我认为文档远远不够

“{signature}一个HMAC-SHA256签名字符串,格式为:{URL encoded resourceURI}+”\n“+到期。重要提示:该密钥从base64解码,并用作执行HMAC-SHA256计算的密钥。”

该页面包含一个Node.js函数,该函数根据给定的输入生成SAS令牌。 根据您所说的,您正在使用令牌使设备能够连接到您的物联网集线器,因此节点功能的输入应为:

  • 资源URI:{IoT hub name}.azure devices.net/devices/{device id}
  • 签名密钥:{device id}标识的任何对称密钥。您可以从IoT Hub设备标识注册表获取此密钥-例如,使用该工具
  • 没有策略名称
  • 任何到期时间
该页面包含一个Node.js函数,该函数根据给定的输入生成SAS令牌。 根据您所说的,您正在使用令牌使设备能够连接到您的物联网集线器,因此节点功能的输入应为:

  • 资源URI:{IoT hub name}.azure devices.net/devices/{device id}
  • 签名密钥:{device id}标识的任何对称密钥。您可以从IoT Hub设备标识注册表获取此密钥-例如,使用该工具
  • 没有策略名称
  • 任何到期时间
终于拿到了:)

“12345”是我们设备的序列号。 y2z的关键。。。。将是一个base64系列与其他花式产品的组合(只要它采用base64格式以使中心满意;)

最终获得:)

“12345”是我们设备的序列号。
y2z的关键。。。。将是我们的系列与其他花式产品的base64组合(只要它采用base64格式以使中心满意;)

这将有助于某些人:

为Azure IoT集线器构造授权标头

以及Azure IoT Hub的示例MQTT用户/密码组合(是的,密码很残酷,包含空格):

用户名(DeviceId区分大小写):
IoTubName.azure devices.net/DeviceId


密码(使用设备资源管理器生成SAS):
SharedAccessSignature sr=IoTubName.azure devices.net%2fdevices%2fDeviceId&sig=KPSZXZZZZZZZZZZZZZZZZHAHLT%2bV7o%3d&se=1487709501
总有一天这会对某人有所帮助:

为Azure IoT集线器构造授权标头

以及Azure IoT Hub的示例MQTT用户/密码组合(是的,密码很残酷,包含空格):

用户名(DeviceId区分大小写):
IoTubName.azure devices.net/DeviceId


密码(使用设备资源管理器生成SAS):
SharedAccessSignature sr=IoTubName.azure devices.net%2fdevices%2fDeviceId&sig=KPSZXZZZZZZZZZZZZZZAHLT%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);
    }
}

另请参见:

以下是如何在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);
    }
}

另请参见:

看来我可以使用自定义协议网关来消除签名的复杂性?通过使用我自己的IAuthenticationProvider类???看来我可以使用自定义协议网关来消除签名的复杂性?通过使用我自己的IAAuthenticationProvider类???感谢您的回复。是的,我将花更多的时间将js转换成一个可行的C函数,这样可以帮助固件工程师在设备端生成令牌。可能会有一些问题,关于生成这个的确切步骤。我需要的摘要是更好地解释://使用crypto var decodedPassword=new Buffer(signingKey,'base64')。toString('binary');const hmac=crypto.createHmac('sha256',decodedPassword);hmac.更新(toSign);var base64signature=hmac.digest('base64');var base64UriEncoded=encodeURIComponent(base64signature);谢谢你的回复。是的,我将花更多的时间将js转换成一个可行的C函数,这样可以帮助固件工程师在设备端生成令牌。可能会有一些问题,关于生成这个的确切步骤。我需要的摘要是更好地解释://使用crypto var decodedPassword=new Buffer(signingKey,'base64')。toString('binary');const hmac=crypto.createHmac('sha256',decodedPassword);hmac.更新(toSign);var base64signature=hmac.digest('base64');var base64UriEncoded=encodeURIComponent(base64signature);
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);
    }
}