ARCHIVE NOTICE

My website can still be found at industrialcuriosity.com, but I have not been posting on this blog as I've been primarily focused on therightstuff.medium.com - please head over there and take a look!
Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Sunday, 10 February 2019

C# / OPENSSH RSA ENCRYPTION MADE EVEN EASIER

A long time ago, I posted about importing and exporting Javascript-compatible RSA certificates to and from C#. Last night I realized that I needed a simple and reliable way to shared encrypted code with non-technical folk and decided to put everything I've learned into a comprehensive package called simple-free-encryption-tool that runs on a node.js backend, in your browser, and doesn't even need to be cloned for quick abuse.

This makes strong RSA key generation and encryption and AES encryption simple to implement, and practical to use for client-server communications. It also allows me to give someone an encryption package on a stick (just copy the dist folder) that they can open on any machine.

Saturday, 11 August 2018

IIS Rewrite Rules Regex

I'm not sure why it's so hard to find clear examples of the not-quite-regex regex that the IIS Url Rewrite module implements for its rewrite rules. Here are three things that I've wasted time figuring out.

1. Rewrite actions use regex matched groups by referencing {R:<group number>} eg. {R:1}

2. The order of the rules is critical, rewrites are then re-matched from scratch.

3. To prevent matches beginning with a word, use "^((?!theword).*)"

Wednesday, 28 March 2018

Azure Key Vault in C# for Dummies

There's a vast amount of documentation available, but all of it assumes a lot of prior knowledge or very particular use cases. Here's a simple and straightforward guide to creating and using a service principal for an Azure Key Vault so that your secrets can be managed programmatically.

Please note: I'm excited because I've finally managed to authenticate using a secret, it's probably more secure to use certificates but I'll get to that another time.

Step 1: Registered App

Under Azure Active Directory in the Azure Portal, select App registrations.

Add a New application registration, the application type being Web app / API and the Sign-on URL anything being any valid URL (just the format, it doesn't have to exist). If the name you enter isn't simple to remember then it would be a good idea to take a note of it for step 2.

Take note of the Application ID as that will be your Client ID for authentication, then select the Keys blade under Settings. Enter a Key description (preferably indicating the user or application that will be using this key), select a duration and Save. Immediately store the resulting value somewhere safe as it will never be displayed again.

I recommend adding yourself as an owner on the Owners blade (also under Settings), whatever else this may be good for it'll let you see the app registration immediately on the App registrations blade without having to select "All apps".

Step 2: Key Vault permissions

Open the Key Vault in the Azure Portal and select the Access policies blade under Settings. Click Add New and click on Select principal - you'll have to enter the full name of the registered app you created in the previous step in the search box before it'll show up, at which point you'll be able to select it.

You can either select an appropriate template from the top dropdown or choose Key, Secret or Certificate permissions manually. Don't worry about Authorized application at this stage.

IMPORTANT: pressing the OK button will add your new policy to the list, but it will not be saved! Be sure to click Save before continuing.

Step 3: Accessing the Key Vault from your Code

There are many different ways to authenticate, most of them obscure and undocumented. This is the simplest method, I've put the credentials in the code for clarity but I have faith that you'll store them somewhere more intelligent. Never store credentials in the codebase. Seriously. Just don't.

Sunday, 19 November 2017

'How to create an Azure SQL Database programmatically' with less frustration

Microsoft's devs have done yet another "almost-but-not-quite-great" job with their sample code for creating an Azure database programmatically.

In addition to the headache of setting up an Azure subscription and Azure Active Directory correctly, it took a silly amount of investigation and trial and error before I could figure out what values the code was expecting as the variable names (almost predictably) don't match their counterparts as displayed in the Azure portal.
    Instructions:
  1. Follow the instructions from the original code's page up to item 4 ("Add your variables to the program")
  2. Replace Program.cs with my modified code.
  3. Follow the instructions in the 4th item, using the modified code's documentation in case of confusion or ambiguity.
Once a database has been created, you can log in via SQL Server Management Studio using the server's fully qualified domain name (xxxxx.database.windows.net) and the server's admin credentials which were created along with the server. For this you will need to update the server's firewall to allow your client IP's connections.

Wednesday, 4 October 2017

C# / OpenSSH RSA Encryption made easy

[EDIT: please see C# / OPENSSH RSA ENCRYPTION MADE EVEN EASIER]

The struggle to uncover the secrets of importing from and export to OpenSSH keys with Microsoft's .NET RSACryptoServiceProvider is real. It's possible but not practical to do this without BouncyCastle, which may or may not be well-documented (navigating their website is far from a joyful experience), but after trawling the web and playing around I've created the following gists that should be of assistance to anyone who needs to do this in a straightforward manner.
And if you want to share RSA keys between JavaScript and .NET platforms, well, you're going to need to do this.
Import and export RSA Keys between C# and PEM format using BouncyCastle
And just because the actual encryption and decryption are always annoying:
Simple RSA Encryption to and Decryption from Base64 encoded strings in C#

Sunday, 23 April 2017

How to code Entity Framework programmable migrations

The internets are eerily quiet when it comes to running Entity Framework's migrations through code, which is odd because Entity Framework's Code First migrations are extremely powerful and calling them (or rolling them back) through the code seems an obvious choice to someone like me, who prefers to reduce the amount of complexity for the poor IT people handling deployment.

(And for poor me, too, I'm very lazy and I like being able to just press a button to make magic happen.)

The most important quirk of running migrations programmatically that you'll need to know before we begin is that the DbMigrator class, for reasons unclear, requires the Entity Framework Configuration class but uses it in a way that's incompatible with the Update-Database and Add-Migration scripts, even after manually configuring the ContextType and ContextKey properties. We'll set those anyway for consistency, but no matter where you store your migrations and however diligently you inform the DbMigrator (the MigrationsDirectory property was ignored too) you're going to be stuck with automatic migrations. And while we're fiddling with the Configuration class, be sure to make the internal Configuration class public.

Automatic migrations ignore the explicit migration files and detect changes between the context's models and the database. As with the Update-Database script, the database will be created if it hasn't been already. It will not function reliably unless the AutomaticMigrationDataLossAllowed property is set to true, and you'll also need to update the OnModelCreating method of your context class to allow for database calls when the models are out of sync to give you a chance to run the migrations:





Migrating up and down

Using automatic migrations to update your database is great, but what do you do if you need to roll back? DbMigrator requires a migration name to update to, and unlike the case with explicit migrations, the migration name is not established by the developer but is unique to the database in question.

Fortunately, the DbMigrator includes the GetDatabaseMigrations method, which returns a list of applied migrations; so while you won't be able to roll back to a predefined named state, you will be able to roll back to a previously run migration. Here it is important to note that the order of the migrations returned is not guaranteed, but the names begin with a timestamp so they're not too difficult to sort.



So rolling back the first of that list is as simple as



Seeding

Seeding must be performed manually after calling DbMigrator.Update(). The Configuration class' Seed method is protected, so add the following wrapper method to your Configuration class



and call it once the migration is complete.

Thursday, 26 January 2017

Passing data from C# to Node.js via Edge.js

Edge.js is a phenomenal tool, but its documentation is a hit and miss.  Sending data to C# from Node.js is straightforward, and the JSON object is translated to a dynamic object automatically:

public async Task<dynamic> Invoke(dynamic input) {
   // echo input message
   await doSomething(input.message);
}

Returning data is not trivial, however, because any kind of complex object I tried to return caused unreported exceptions.

Until now!

It turns out that Edge .js returns associative arrays if and only if they're correctly JSON formatted. I don't recall seeing this documented anywhere, but it makes perfect sense (20/20 hindsight). So in order to return an associative array to Node.js, make sure to use a Dictionary object where the first element type is a string; if you want to send a list of usernames with their IDs, for example, you would either use

Dictionary<string, string>

with the ID cast to string for transmission or

Dictionary<string, int>

with the ID / username columns switched from their normal positions.

Of course, one could go about creating more intricate objects using the dynamic type, but that's beyond the scope of this post.