Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

.NET Fest 2019. Eran Stiller. Create Your Own Serverless PKI with .NET & Azure Key Vault

41 views

Published on

A Public Key Infrastructure (PKI) is the basis of modern system authentication; X.509 certificates are at the core of modern cryptography. Building your own PKI is not for the faint of heart, so we usually buy our certificates from an external Certificate Authority or operate a 3rd-party off-the-shelf PKI.
But what can you do if you need to issue your own certificates while keeping your costs low? What if, for example, you're in the business of manufacturing millions of IoT devices and you need to issue a certificate to each and every one of them? And to top it off - you want to do it in a Serverless manner?
Join me in this session, as we build a Serverless PKI system with Azure Functions & Key-Vault and learn all about Key-Vault's capabilities in regards to X.509 certificates along the way.

Published in: Education
  • Be the first to comment

  • Be the first to like this

.NET Fest 2019. Eran Stiller. Create Your Own Serverless PKI with .NET & Azure Key Vault

  1. 1. Create Your Own Serverless PKI with .NET & Azure Key Vault Eran Stiller Chief Technology Officer erans@codevalue.net @eranstiller https://stiller.blog https://codevalue.net
  2. 2. 2
  3. 3. 3
  4. 4. 4
  5. 5. 5
  6. 6. Agenda ▪ IoT Data Ingestion ▪ PKIs, CAs & Certificates ▪ Building a Serverless CA using .NET ▪ Authoring Certificate Subscribers using .NET ▪ Using the Generated Certificates ▪ Device Provisioning Service & IoT Hub 6
  7. 7. About Eran Eran Stiller ▪ @eranstiller ▪ CTO & Founder at CodeValue ▪ Software architect, consultant and instructor ▪ Microsoft Regional Director & Azure MVP ▪ Founder of Azure Israel Meetup 7
  8. 8. IoT Data Ingestion 9
  9. 9. IoT Data Ingestion 10 Data Ingestion Pipeline Further Big Data Processing IoT Hub Raw Storage (Data Lake) Device Device Device
  10. 10. IoT Data Ingestion 11 Device Device Device Data Ingestion Pipeline Further Big Data Processing IoT Hub Raw Storage (Data Lake) Data Ingestion Pipeline Further Big Data Processing IoT Hub Raw Storage (Data Lake) Device Provisioning Service
  11. 11. Securely Communicating with Devices 12 Confidentiality Authentication Authorization Icons made by Freepik and Eucalyp for www.flaticon.com
  12. 12. Keep It Simple 13
  13. 13. PKIs, CAs & Certs 14
  14. 14. Public Key Infrastructure (PKI) ▪ An umbrella term for the stuff we need in order to: ▪ Issue ▪ Distribute ▪ Store ▪ Use ▪ Verify ▪ Revoke ▪ and otherwise manage and interact with certificates and keys ▪ Don’t build from scratch ▪ Can use an off-the-shelf solution ▪ Can build some parts and rely on others 15
  15. 15. Certificates ▪ A driver’s license for computers and code ▪ Basically, a binding between an identifier (name) and a public key ▪ Usually encoded as X.509 16 Icon made by Becris for www.flaticon.com
  16. 16. Demo Certificate Content 17
  17. 17. Certificates 101 18 Hi there, I’m Alice! Hi Alice, I’m Bob! How do I know you’re really Bob? Here is my Certificate ( + certificate) Prove it to me by decrypting this challenge ( + challenge) There you go ( + decrypted challenge) Continue secure conversation (Optionally – mutual authentication)
  18. 18. Certificate Authority ▪ The entity which issues certificates ▪ Trusted by the Relying Parties ▪ Public trusted root certificates are pre-populated ▪ Various methods to verify identity 19
  19. 19. Building a Serverless CA using .NET 20
  20. 20. The Root Certificate 21
  21. 21. Azure Key Vault ▪ Safeguard cryptographic keys and other secrets ▪ Hardware Security Modules (HSM) as a service ▪ Can be replaced with AWS Certificate Manager ▪ Principles will remain unchanged ▪ Implementation details will defer 22
  22. 22. Scenario Generating a new certificate on a new device 23
  23. 23. Demo Setup Azure Key Vault & Other Resources 24
  24. 24. Generating the Root Certificate on Key Vault 25 var certificateOperation = await client.CreateCertificateAsync( _vaultBaseUrl, _certificateName, new CertificatePolicy( keyProperties: new KeyProperties(false, "RSA", 2048, false), x509CertificateProperties: new X509CertificateProperties( "CN=" + RootSubjectName, keyUsage: new List<string> {X509KeyUsageFlags.KeyCertSign.ToString()}, ekus: new List<string> {"1.3.6.1.5.5.7.3.2", "1.3.6.1.5.5.7.3.1"}), issuerParameters: new IssuerParameters("Self")));
  25. 25. Generating the Root Certificate on Our Machine 26 using var certificateKey = RSA.Create(); var subjectDistinguishedName = new X500DistinguishedName("CN=" + RootSubjectName); var request = new CertificateRequest(subjectDistinguishedName, certificateKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); request.CertificateExtensions.Add( new X509KeyUsageExtension(X509KeyUsageFlags.KeyCertSign, true)); request.CertificateExtensions.Add( new X509BasicConstraintsExtension(true, true, 1, true)); // Additional X509 extensions not shown for brevity var certificate = request.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(1));
  26. 26. Demo Generating the Root Certificate 27
  27. 27. Limiting Root Certificate Access ▪ Use Azure Key Vault Access Policies 28
  28. 28. Auditing Root Certificate Access 29 { "time": "2016-01-05T01:32:01.2691226Z", "resourceId": "/SUBSCRIPTIONS/361DA5D4-A47A-4C79-AFDD- XXXXXXXXXXXX/RESOURCEGROUPS/CONTOSOGROUP/PROVIDERS/MICROSOFT.KEYVAULT/VAULTS/CONTOSOKEYVAU LT", "operationName": "VaultGet", "operationVersion": "2015-06-01", "category": "AuditEvent", "resultType": "Success", "resultSignature": "OK", "resultDescription": "", "durationMs": "78", "callerIpAddress": "104.40.82.76", "correlationId": "", "identity": { "claim": { "http://schemas.microsoft.com/identity/claims/objectidentifier":
  29. 29. 30 "durationMs": "78", "callerIpAddress": "104.40.82.76", "correlationId": "", "identity": { "claim": { "http://schemas.microsoft.com/identity/claims/objectidentifier": "d9da5048-2737-4770-bd64-XXXXXXXXXXXX", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn": "live.com#username@outlook.com", "appid": "1950a258-227b-4e31-a9cf-XXXXXXXXXXXX" } }, "properties": { "clientInfo": "azure-resource-manager/2.0", "requestUri": "https://control-prod- wus.vaultcore.azure.net/subscriptions/361da5d4-a47a-4c79-afdd- XXXXXXXXXXXX/resourcegroups/contosoresourcegroup/providers/Microsoft.KeyVault/vaults/conto sokeyvault?api-version=2015-06-01", "id": "https://contosokeyvault.vault.azure.net/", "httpStatusCode": 200 } }
  30. 30. Sign a Request Using the Root Certificate 31
  31. 31. subject name, public key & access token Sign a Request Using the Root Certificate 32 Device Identity Provider Certificate Authority Key Vault authentication info access token generate CSR generate key pair certificate digest (hash) signed digest signed certificate Store certificate & private key
  32. 32. Generate Certificate Signing Request (CSR) 33 var parameters = new RSAParameters { Modulus = publicKey.Modulus, Exponent = publicKey.Exponent }; var certificateKey = RSA.Create(parameters); var subjectDistinguishedName = new X500DistinguishedName("CN=" + subjectName); var request = new CertificateRequest(subjectDistinguishedName, certificateKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); request.CertificateExtensions.Add( new X509KeyUsageExtension( X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, true)); request.CertificateExtensions.Add( new X509BasicConstraintsExtension(false, true, 0, true)); // Additional X509 not shown for brevity return request;
  33. 33. Sign Certificate with Root Key 34 CertificateRequest request = CreateCertificateRequest(subjectName, certificateKey); byte[] certificateSerialNumber = await _serialNumberGenerator.GenerateSerialAsync(); RSA rsaKeyVault = _keyVaultClient.ToRSA( certificateBundle.KeyIdentifier, issuerCertificate); var generator = X509SignatureGenerator.CreateForRSA( rsaKeyVault, RSASignaturePadding.Pkcs1); var certificate = request.Create( issuerCertificate.SubjectName, generator, DateTime.Today, DateTime.Today.AddYears(1), certificateSerialNumber);
  34. 34. Demo Serverless CA using .NET & Azure Functions 35
  35. 35. Authoring Certificate Subscribers using .NET 36
  36. 36. subject name, public key & access token Sign a Request Using the Root Certificate 37 Device Identity Provider Certificate Authority Key Vault generate CSR certificate digest (hash) signed digest signed certificate Store certificate & private key authentication info access token generate key pair
  37. 37. Getting an Access Token for Azure Functions 39 var auth = await authHelper.AcquireTokenAsync(); // AAD Token var client = new HttpClient { BaseAddress = new Uri(configuration.BaseUrl) }; var request = new {access_token = auth.AccessToken}; var httpContent = ... // JSON serialization var responseMessage = await client.PostAsync(".auth/login/aad", httpContent); var serializedResponse = await responseMessage.Content.ReadAsStringAsync(); dynamic response = JsonConvert.DeserializeObject<dynamic>(serializedResponse); return response.authenticationToken;
  38. 38. Issue Certificate 40 var key = RSA.Create(); var publicParameters = key.ExportParameters(false); var request = new IssueCertificateRequest( subjectName, publicParameters); var httpContent = new StringContent( JsonConvert.SerializeObject(request), Encoding.UTF8, MediaTypeNames.Application.Json);
  39. 39. Issue Certificate (Cont.) 41 var client = new HttpClient {BaseAddress = ...}; client.DefaultRequestHeaders.Add("X-ZUMO-AUTH", accessToken); var responseMessage = await client.PostAsync("api/issueCertificate", httpContent); var serializedResponse = await responseMessage.Content.ReadAsStringAsync(); var response = JsonConvert.DeserializeObject<IssueCertificateResponse>( serializedResponse); var certificate = new X509Certificate2( Convert.FromBase64String(response.Certificate)); return certificate;
  40. 40. Store Certificate With Private Key 42 var certificateWithPrivateKey = certificate.CopyWithPrivateKey(key); var rawCertificate = certificateWithPrivateKey.Export(X509ContentType.Pfx); var persistableCertificate = new X509Certificate2(rawCertificate, string.Empty, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.UserKeySet); var store = new X509Store(StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); store.Add(persistableCertificate);
  41. 41. Demo Certificate Subscribers using .NET 43
  42. 42. Using the Generated Certificates 44
  43. 43. IoT Data Ingestion (Reminder) 45 Device Device Device Data Ingestion Pipeline Further Big Data Processing IoT Hub Raw Storage (Data Lake) Device Provisioning Service
  44. 44. Sending Data Using the Generated Certificate 47 X509Certificate2 certificate = LoadCertificate(configuration.DeviceName); var security = new SecurityProviderX509Certificate(certificate); var transport = new ProvisioningTransportHandlerAmqp( TransportFallbackType.TcpOnly); var provClient = ProvisioningDeviceClient.Create( GlobalDeviceEndpoint, configuration.DpsIdScope, security, transport); DeviceRegistrationResult registrationResult = await provClient.RegisterAsync();
  45. 45. Demo End-to-End Operation 48
  46. 46. Takeaways 50
  47. 47. Takeaways ▪ Certificates are hard, but crucial, to get right ▪ Don’t author an entire PKI from scratch ▪ Customize an existing solution where appropriate ▪ IoT is one scenario where I encountered a need for a custom PKI ▪ Handling certificates with .NET is surprisingly undocumented ▪ With and without Azure Key Vault ▪ Azure Key Vault is a great platform to base a CA on ▪ The sample is just a sample, but is derived from a production system ▪ Can base on it and form your own solution 51
  48. 48. Resources ▪ Source Code ▪ https://github.com/estiller/build-pki-net-azure-sample ▪ NuGet package to integrate Key Vault with .NET Cryptographic Keys ▪ https://github.com/onovotny/RSAKeyVaultProvider ▪ Additional resources ▪ https://smallstep.com/blog/everything-pki.html ▪ https://docs.microsoft.com/en-in/azure/key-vault/certificate-scenarios ▪ https://docs.microsoft.com/en-us/azure/key-vault/key-vault-logging 52
  49. 49. Eran Stiller Chief Technology Officer erans@codevalue.net @eranstiller https://stiller.blog https://codevalue.net

×