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_X509certificate_.net Core 3.0 - Fatal编程技术网

C# Azure IoT中心对其他设备的未经授权访问

C# Azure IoT中心对其他设备的未经授权访问,c#,azure,x509certificate,.net-core-3.0,C#,Azure,X509certificate,.net Core 3.0,我在尝试使用x509证书通过DPS向IoT集线器注册第二台设备时遇到问题。我的根证书颁发机构存在并在DPS和IoT集线器(通过openssl生成)上验证。至于客户端证书,我将在应用程序启动后(如果to不存在)在下面的代码中生成它。困扰我的是,每个设备都正确地注册到Azure DPS,但只有第一个设备获得授权和注册。可能是我在客户端证书创建过程中所做的某件事把它搞砸了吗?此外,在设备注册到IoT集线器期间,此行中也会发现错误: DeviceRegistrationResult result = a

我在尝试使用x509证书通过DPS向IoT集线器注册第二台设备时遇到问题。我的根证书颁发机构存在并在DPS和IoT集线器(通过openssl生成)上验证。至于客户端证书,我将在应用程序启动后(如果to不存在)在下面的代码中生成它。困扰我的是,每个设备都正确地注册到Azure DPS,但只有第一个设备获得授权和注册。可能是我在客户端证书创建过程中所做的某件事把它搞砸了吗?此外,在设备注册到IoT集线器期间,此行中也会发现错误:

DeviceRegistrationResult result = await provisioningDeviceClient.RegisterAsync().ConfigureAwait(false);
添加的错误:

2019/12/16 09:37:38.309 |错误|尝试启动服务时发现错误设备未能在物联网中心注册:设备未能正确设置:AMQP传输异常| Tidel.DeviceAgent.DeviceAgent |

客户端证书生成

        X509Certificate2 caRootCertificate;
        X509Store caStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
        caStore.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

        X509Certificate2Collection signerCollection = (X509Certificate2Collection)caStore.Certificates.Find(X509FindType.FindByIssuerName, "CERTNAME", true);

        caStore.Close();

        if (signerCollection.Count != 0)
        {
            caRootCertificate = signerCollection[0];

            using (var rsa = RSA.Create())
            {
                rsa.KeySize = 2048;

                var clientCertificateRequest = new CertificateRequest($"CN={_writableOptions.Value.RegistrationId}", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

                clientCertificateRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));

                var issuerSubjectKey = caRootCertificate.Extensions["Subject Key Identifier"].RawData;
                var segment = new ArraySegment<byte>(issuerSubjectKey, 2, issuerSubjectKey.Length - 2);
                var authorityKeyIdentifier = new byte[segment.Count + 4];

                authorityKeyIdentifier[0] = 0x30;
                authorityKeyIdentifier[1] = 0x16;
                authorityKeyIdentifier[2] = 0x80;
                authorityKeyIdentifier[3] = 0x14; 
                segment.CopyTo(authorityKeyIdentifier, 4);
                clientCertificateRequest.CertificateExtensions.Add(new X509Extension("2.5.29.35", authorityKeyIdentifier, false));


                var sanBuilder = new SubjectAlternativeNameBuilder();
                sanBuilder.AddDnsName(_writableOptions.Value.RegistrationId);
                var sanExtension = sanBuilder.Build();
                clientCertificateRequest.CertificateExtensions.Add(sanExtension);

                clientCertificateRequest.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid("1.3.6.1.5.5.7.3.2") }, false));
                clientCertificateRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(clientCertificateRequest.PublicKey, false));

                var notBefore = DateTimeOffset.UtcNow.AddDays(-1);

                if (notBefore < caRootCertificate.NotBefore)
                {
                    notBefore = new DateTimeOffset(caRootCertificate.NotBefore);
                }

                var notAfter = DateTimeOffset.UtcNow.AddDays(365);

                if (notAfter > caRootCertificate.NotAfter)
                {
                    notAfter = new DateTimeOffset(caRootCertificate.NotAfter);
                }

                var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                var unixTime = Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds);
                var serial = BitConverter.GetBytes(unixTime);

                using (var cert = clientCertificateRequest.Create(caRootCertificate, notBefore, notAfter, serial))
                {
                    X509Certificate2 client = cert.CopyWithPrivateKey(rsa);

                    return await Task.FromResult(client);
                }
            }
        }
        else
        {
            throw new FileNotFoundException($"Could not find a root certificate.");
        }
设备注册到物联网中心

using (var certificatePassword = new X509Certificate2(certificate.GetRawCertData(), _writableOptions.Value.CertPass))
{
    using (var security = new SecurityProviderX509Certificate(certificatePassword))
    {
        using (var transport = new ProvisioningTransportHandlerAmqp(TransportFallbackType.TcpOnly))
        {
            ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.Create(_writableOptions.Value.AzureEndpoint, _writableOptions.Value.IdScope, security, transport);
            DeviceRegistrationResult result = await provisioningDeviceClient.RegisterAsync().ConfigureAwait(false);
            IAuthenticationMethod authenticationMethod = new DeviceAuthenticationWithX509Certificate(result.DeviceId, certificate);
            DeviceClient deviceClient = DeviceClient.Create(result.AssignedHub, authenticationMethod, TransportType.Amqp_Tcp_Only);

            return await Task.FromResult(deviceClient);
       }
     }
}

我解决了这个问题。在存储中生成证书时,我使用FindByIssuerName查找证书

X509Certificate2Collection signerCollection = (X509Certificate2Collection)caStore.Certificates.Find(X509FindType.FindByIssuerName, "CERTNAME", true);
经过进一步调查,商店中有两个名称完全相同的证书。问题:MMC管理单元仅显示一个证书。环顾四周后,有人建议在某个地方对商店运行storerepair命令。运行storerepair命令后,我可以在MMC中看到这两个证书,并且能够删除有问题的证书,从而防止检测到有效的证书

Windows版本:Windows Embedded 8.1 Industry Pro

X509Certificate2Collection signerCollection = (X509Certificate2Collection)caStore.Certificates.Find(X509FindType.FindByIssuerName, "CERTNAME", true);