• Build2019,  Microsoft

    Build 2019 Session: AI and the Cloud Vision

    AI and the Cloud Vision- I’m not 100% I understand many humans, but I’m still learing:

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    5 industries that are getting disrupted by Computer Vision on Cloud and on Edge

    Join developers and industry experts at Microsoft Build to explore the latest developer tools and technologies. #MSBuild

    Source: 5 industries that are getting disrupted by Computer Vision on Cloud and on Edge

  • Build2019,  Microsoft

    Build 2019 Session: The look back on C#

    Interesting step back as we move forward with C#. It’s good to know where and how it came from:

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    ‘Look Back’ on C#

    Join developers and industry experts at Microsoft Build to explore the latest developer tools and technologies. #MSBuild

    Source: ‘Look Back’ on C#

  • Build2019,  Microsoft

    Build 2019 Session: Iot News and Futures

    What’s not to like about IoT… it depends on what you need.

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    All you need to know about Microsoft’s IoT news and futures

    Join developers and industry experts at Microsoft Build to explore the latest developer tools and technologies. #MSBuild

    Source: All you need to know about Microsoft’s IoT news and futures

  • .Net,  Build2019,  Microsoft

    Build 2019 Session: .Net Goodness

    Yes, I know I’m a little behind on picking out my favorite Build 2019 Session… So here the first one…

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    Microsoft Build 2019 Developer Conference May 6-8 Seattle, WA

    .NET Platform Overview and Roadmap

    Join developers and industry experts at Microsoft Build to explore the latest developer tools and technologies. #MSBuild

    Source: .NET Platform Overview and Roadmap

  • Microsoft,  Visual Studio 2017,  Visual Studio 2019

    Azure Logic App Development in Portal vs Visual Studio

    A funny thing happens when you move away from doing Prototype Azure Logic App all in the Portal to doing them in Visual Studio (where you are supposed to do Production develop). What’s funny… or is it annoying? Well, development life turns out is not the same.

    In the next few days I will be adding a small trip thought some things I notice between the two modes of development.

  • Microsoft

    Powershell 6.x Profiles

    Because I can never remember this:

    All Users, All Hosts $PsHome\Profile.ps1
    All Users, Current Host $PsHome\Microsoft.PowerShell_profile.ps1
    Current User, All Hosts $Home\Documents\PowerShell\Profile.ps1
    Current user, Current Host $Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps
    $Profile Current User, Current Host
    $Profile.CurrentUserCurrentHost Current User, Current Host (Yeah the same as above)
    $Profile.CurrentUserAllHosts Current User, All Hosts
    $Profile.AllUsersCurrentHost All Users, Current Host
    $Profile.AllUsersAllHosts All Users, All Hosts
  • Microsoft

    Powershell 6 Core Like Install

    As I re-tool (or is it update) my Powershell, I came across the simple one liner to do the install… nice:

    iex "& { $(irm https://aka.ms/install-powershell.ps1) } -UseMSI"

    Btw some neat changes in 6.2 PS…

    Some interesting settings:

    Enable-ExperimentalFeature -Name PSCommandNotFoundSuggestion
    
    Enable-ExperimentalFeature -Name PSTempDrive
    
    Enable-ExperimentalFeature -Name PSUseAbbreviationExpansion

    Read More:

    What’s New in PowerShell Core 6.2

    What’s New in PowerShell Core 6.2

    New features and changes released in PowerShell Core 6.2

    Source: docs.microsoft.com/en-us/powershell/scripting/whats-new/what-s-new-in-powershell-core-62?view=powershell-6

     

     

  • Microsoft

    The Azure Vault, PGP, and other matters Part 3

    Well if you are still hanging on… thanks and good job. We only have a bit more to go…. (you can go back to Part 1 or Part 2)

    Time to regroup as to where we are in the Big Picture:

    This is the flow of the Logic App. In Part 2 we just finished up the GetKeys block… so onto the Decryptor….

    Some more code of course as this is another Azure Function….

    public static class MHKPGPDecryptor
        {
            [FunctionName("MHKPGPDecryptor")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                ILogger log)
            {
                log.LogInformation($"C# HTTP trigger function {nameof(MHKPGPDecryptor)} processed a request.");
                string vaultKey = req.Query["privatekeysecretid"];
                string useVault = req.Query["useVault"];
                string privateKey = "";

    A familiar start to our Azure Function. Here we are placing two Query parameters:

      privatekeysecretid and useVault

    The privatekeysecretid contains the full PGP key we got from the vault. The second parameter is just a flag to tell the function if the privatekeysecretid  should used or not. I’ve made the private key value required, and the use vault is optional.

    When useVault is something like a “Yes”, the function will assume to use the privatekeysecretid as the actual PGP key. This is what all of this code is about:

                if (!String.IsNullOrEmpty(vaultKey))
                {
                    log.LogInformation($"Vault key found privatekeysecretid");
                }
                else
                {
                    log.LogInformation($"privatekeysecretid = is missing from the call. This must be provided!");
                    return new BadRequestObjectResult("Missing the paramenter privatekeysecretid. This must must have the private key.");
                }
    
                if (!string.IsNullOrEmpty(useVault))
                {
                    if (useVault.ToUpper().Contains("YES"))
                    {
                      privateKey = vaultKey;
                      log.LogInformation($"Using Key from the Vault.");
                    }
                    else
                    {
                      privateKey = @"-----BEGIN PGP PRIVATE KEY BLOCK-----
                                     Version: GnuPG v1.4.9 (MingW32)
                          //something secret is here....
                                     -----END PGP PRIVATE KEY BLOCK-----";
                        log.LogInformation($"Using Key from the internal store.");
                    }
                }

    (Yes that’s me hard-coding a key into the function… well it’s test code get over it 😉).

    Now we have the key, what next? Let’s take a couple of steps back.

    The encrypted content in our adventure is sitting in the request body when this function is call (yeap I did not make that obvious because I’m about to go on about it). 

    When the Decryptor function is called, this content is passed in. Dipping back to the Logic App:

    Notice the Request Body gets the File Content from the sFTP content. Also notice what privatekeysecretid gets. It is the Body content from the GetKeys function that was just called. **Now that’s an important matter. This is Content Scope… one should pause and think about what is being said here. It should be obvious to most who have done any Dot Net Core, MVC, and even for that matter any Web API’s (ok I’ll stop  beating on my drum about it, but put the wrong content in the wrong place and 😬).  

    Our next matter is the PGP parts… We have a Key… We have encrypted contain… Time to make it happen!

    First thing, you will need to add a NuGet Package to the Azure Function code. At the time or this post I’m using PgpCore v1.4.1:

    The Using are:

    The rest of the main method is:

        log.LogInformation("Now Decrypting the body");
        Stream decryptedData = await DecryptAsync(req.Body, privateKey, log);
    
        return new OkObjectResult(decryptedData);
    
    }

    Here we call DecryptAsync. Followed up with the decrypted content going back to the Logic App with a 200.

    We have but one more method to do:

    private static async Task<Stream> DecryptAsync(Stream inputStream, string privateKey, ILogger log)
           {
    
               log.LogInformation("So it begins...");
               using (PGP pgp = new PGP())
               {
                   Stream outputStream = new MemoryStream();
    
                   Stream temp = new MemoryStream();
                   temp = GenerateStreamFromString("Place Holder for errors.");
    
                   try
                   {
                       using (inputStream)
                       using (Stream privateKeyStream = GenerateStreamFromString(privateKey))
                       {
                           log.LogInformation("Now it is done...");
                           await pgp.DecryptStreamAsync(inputStream, outputStream, privateKeyStream, "MY SUPER SECRET PASSPHRASE");
                           outputStream.Seek(0, SeekOrigin.Begin);
    
                           //log.Flush();
                           return outputStream;
                       }
                   }
                   catch (Exception ex)
                   {
                       log.LogInformation("Error Throw");
                       log.LogInformation($"This was {ex.Message}");
                       //log.Flush();
                       temp = GenerateStreamFromString("Stupid PGP errored: " + ex.Message.ToString());
                       temp.Seek(0, SeekOrigin.Begin);
                       return temp;
                   }
    
               }
           }
    
           private static Stream GenerateStreamFromString(string s)
           {
               MemoryStream stream = new MemoryStream();
               StreamWriter writer = new StreamWriter(stream);
               writer.Write(s);
               writer.Flush();
               stream.Position = 0;
               return stream;
           }

    So PGP decrypt takes some content (as a stream), a key, and a passphrase for that key. Mostly super simple. This is all that the decyptor does.

    Now, one last step in our Logic App:

    We must output the content somewhere. Here I have a file share on a Azure storage account. This time the Body Content (which becomes our File Content) is the response from the PGPDecryptor.

    Wrapping it up….

    Can this be improved upon… But of course. For one matter the Pass Phrase should be passed into the Decryptor and should come from it’s own Vault possibly. This can be different (or at least it should be different) for each PGP key. There could be more error handling, and what about Encrypting? PGPCore the handy NuGet package also has methods for Encrypting and Encrypting/Signing.

    But I will leave those Matters for you to explore…. 

    If you need to go back Parts 1 & 2 are here Part 1 Part 2 

    I hope this has been a help….

    ~SG