<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[dfaiv-dev]]></title><description><![CDATA[Dev Notes - Your Mileage May Vary]]></description><link>https://blog.dfaiv.dev</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 10 Jan 2021 17:47:46 GMT</lastBuildDate><item><title><![CDATA[How Should I Be Hashing Passwords in C#/dotnet core?]]></title><description><![CDATA[I wanted to add authorization to a SPA web api backend (using asp.net core). The build in solutions seem to either be IdentityServer4 (which…]]></description><link>https://blog.dfaiv.devfoo/bar</link><guid isPermaLink="false">https://blog.dfaiv.devfoo/bar</guid><pubDate>Mon, 07 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I wanted to add authorization to a SPA web api backend (using asp.net core). The build in solutions seem to either be &lt;strong&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity-api-authorization?view=aspnetcore-5.0&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;IdentityServer4&lt;/a&gt;&lt;/strong&gt; &lt;del&gt;(which &lt;a href=&quot;https://identityserver4.readthedocs.io/en/latest/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;will only be supported unitl Nov 2022?&lt;/a&gt;)&lt;/del&gt; (wait, &lt;a href=&quot;https://blog.duendesoftware.com/posts/20201210_community_edition/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;maybe they’ll have a Community Edition&lt;/a&gt; for companies with less that $1M revenue?) or &lt;strong&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-5.0&amp;#x26;tabs=visual-studio&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Microsoft.AspNetCore.Identity&lt;/a&gt;&lt;/strong&gt; which seems to want to work more with MVC/Razor and SPAs (though I’m sure it could be hacked?).&lt;/p&gt;
&lt;p&gt;Seems like it shouldn’t be the end of the world to create a user table and store passwords with some sort of best practice. The first part of that would be how to hash the password. Unsurprisingly there seem to be a few opinions around the inter-webs. This is what I ended up with.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Pbkdf2PasswordHasher&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; PasswordHashSize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; SaltSize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashAlgorithmName&lt;/span&gt; HashAlgorithm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 
        HashAlgorithmName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;SHA512&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Generate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; iterations &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;175_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//generate a random salt for hashing&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; salt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;SaltSize&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;RNGCryptoServiceProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;salt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//hash password given salt and iterations&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//iterations provide difficulty when cracking&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; pbkdf2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; 
            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Rfc2898DeriveBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; salt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; iterations&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; HashAlgorithm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; hash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pbkdf2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PasswordHashSize&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//return delimited string with salt | #iterations | hash&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Convert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;salt&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;|&quot;&lt;/span&gt; 
                &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; iterations &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;|&quot;&lt;/span&gt; 
                &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Convert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;bool&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;IsValid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; encodedHash&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//extract original values from delimited hash text&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; parts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; encodedHash&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string character&quot;&gt;&apos;|&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; salt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Convert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;FromBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; iterations &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; hash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//generate hash from test password &lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//  and original salt and iterations&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; pbkdf2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Rfc2898DeriveBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
                        password&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; salt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; iterations&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; HashAlgorithm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; testHash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pbkdf2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PasswordHashSize&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//if hash values match then return success&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Convert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToBase64String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;testHash&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; hash&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//no match return false&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Notes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;interationCount&lt;/code&gt; was used by running a perf test on my local machine to find hashing that took ~100ms&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Fact&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Skip &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;not really a unit test, should probably move to some other mechanism.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Perf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; maxRuntimeMs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; iterations &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; lastRuntime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0L&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lastRuntime &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; maxRuntimeMs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; timer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Stopwatch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;StartNew&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; hashResult &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
        Pbkdf2PasswordHasher&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Generate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            PasswordPlainTextDefault&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            iterations&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    timer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; runTime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; timer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ElapsedMilliseconds&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _testOutputHelper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;$&quot;hash with iterations: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token expression language-csharp&quot;&gt;iterations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, ms: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token expression language-csharp&quot;&gt;runTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;, result: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token expression language-csharp&quot;&gt;hashResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    lastRuntime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; runTime&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    iterations &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;I used &lt;code class=&quot;language-text&quot;&gt;HashAlgorithmName.SHA512&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;SHA256&lt;/code&gt; because larger is better?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;bcrypt&lt;/h3&gt;
&lt;p&gt;There is a &lt;code class=&quot;language-text&quot;&gt;dotnet&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;bcrypt&lt;/code&gt; implementation which seems to more widely respected on the internet (as it is slower to calculate, and slower is better?). But &lt;code class=&quot;language-text&quot;&gt;PBKDF2&lt;/code&gt; still seems to be “officially” recommended, and it’s built into &lt;code class=&quot;language-text&quot;&gt;dotnet&lt;/code&gt; which seemed a little safer than OSS.&lt;/p&gt;
&lt;h3&gt;Resources:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cidean.com/blog/2019/password-hashing-using-rfc2898derivebytes/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;C# pdfh source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PBKDF2 Recommendation by NIST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pkbdf2-sha256&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PBKDF2 Iterations Recommendation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/aspnet/Identity/blob/master/src/Core/PasswordHasher.cs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Microsoft.AspNetCore.Identity.PasswordHasher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Angular - Can You Use an Async Variable in a Pipe?]]></title><description><![CDATA[When I Googled for this, I got a bunch of results that just explain the  pipe; but I wanted to know if I could use an async variable into…]]></description><link>https://blog.dfaiv.devfoo/bar</link><guid isPermaLink="false">https://blog.dfaiv.devfoo/bar</guid><pubDate>Fri, 20 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When I Googled for this, I got a bunch of results that just explain the &lt;code class=&quot;language-text&quot;&gt;async&lt;/code&gt; pipe; but I wanted to know if I could use an async variable into the pipe:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Currency {{ 100 | currency:(currencySymbol$ | async)}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Looks like you can. See this &lt;a href=&quot;https://stackblitz.com/edit/pipe-variable-async?file=src/app/app.component.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Stack Blitz&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Powershell - Write-Host from Background Script Block]]></title><description><![CDATA[I have a Powershell deploy script that runs multiple background tasks in parallel using a script block. The block was using  but I wasn’t…]]></description><link>https://blog.dfaiv.devfoo/bar</link><guid isPermaLink="false">https://blog.dfaiv.devfoo/bar</guid><pubDate>Mon, 23 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have a Powershell deploy script that runs multiple background tasks in parallel using a &lt;a href=&quot;https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_script_blocks?view=powershell-7.1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;script block&lt;/a&gt;. The block was using &lt;code class=&quot;language-text&quot;&gt;Write-Host&lt;/code&gt; but I wasn’t getting any output. Turns out I needed to use &lt;code class=&quot;language-text&quot;&gt;Receive-Job&lt;/code&gt; to capture any output.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;powershell&quot;&gt;&lt;pre class=&quot;language-powershell&quot;&gt;&lt;code class=&quot;language-powershell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# helper to log results&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; _handleJobResults &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;listing all jobs&quot;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Get-Job&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;resetting jobs&quot;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Get-Job&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Remove-Job&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; _waitForJobs &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# should really check that jobs have finished, maybe in another post.&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;waiting for jobs to finish&quot;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Start-Sleep&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Seconds 2
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token variable&quot;&gt;$jobCount&lt;/span&gt; = 3

&lt;span class=&quot;token comment&quot;&gt;# function block to be invoked in background job.&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;$_deployBlock01&lt;/span&gt; = &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$_i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;script block output: &lt;span class=&quot;token variable&quot;&gt;$_i&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# invoke background jobs&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# no Write-Host output from $_deployBlock01&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; in 1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$jobCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Start-Job&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ScriptBlock &lt;span class=&quot;token variable&quot;&gt;$_deployBlock01&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Name &lt;span class=&quot;token string&quot;&gt;&quot;test-job-&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ArgumentList &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

_waitForJobs
_handleJobResults
&lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;no output from script block should have been logged.&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;re-run jobs, capture output&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# invoke background jobs, capture outputs&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; in 1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$jobCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Start-Job&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ScriptBlock &lt;span class=&quot;token variable&quot;&gt;$_deployBlock01&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Name &lt;span class=&quot;token string&quot;&gt;&quot;test-job-&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;ArgumentList &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

_waitForJobs

&lt;span class=&quot;token function&quot;&gt;Write-Host&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Get Job output&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#Recieve-Job will get the Write-Host output.&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;Get-Job&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Receive-Job&lt;/span&gt;

_handleJobResults&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[git - Rewrite authors]]></title><description><![CDATA[On my computer, my default git user is for my work account. I was working on a personal project, pushed it to GitHub, and didn’t realize…]]></description><link>https://blog.dfaiv.devfoo/bar</link><guid isPermaLink="false">https://blog.dfaiv.devfoo/bar</guid><pubDate>Sat, 17 Mar 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On my computer, my default git user is for my work account. I was working on a personal project, pushed it to GitHub, and didn’t realize until after that I had been commiting with my work username/email. Some Googling &lt;a href=&quot;https://stackoverflow.com/questions/750172/how-to-change-the-author-and-committer-name-and-e-mail-of-multiple-commits-in-gi&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;turned up&lt;/a&gt; that you can rewrite history from one email/username to another:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; filter-branch --env-filter &lt;span class=&quot;token string&quot;&gt;&apos;
OLD_EMAIL=&quot;your-old-email@example.com&quot;
CORRECT_NAME=&quot;Your Correct Name&quot;
CORRECT_EMAIL=&quot;your-correct-email@example.com&quot;
if [ &quot;&lt;span class=&quot;token variable&quot;&gt;$GIT_COMMITTER_EMAIL&lt;/span&gt;&quot; = &quot;&lt;span class=&quot;token variable&quot;&gt;$OLD_EMAIL&lt;/span&gt;&quot; ]
then
    export GIT_COMMITTER_NAME=&quot;&lt;span class=&quot;token variable&quot;&gt;$CORRECT_NAME&lt;/span&gt;&quot;
    export GIT_COMMITTER_EMAIL=&quot;&lt;span class=&quot;token variable&quot;&gt;$CORRECT_EMAIL&lt;/span&gt;&quot;
fi
if [ &quot;&lt;span class=&quot;token variable&quot;&gt;$GIT_AUTHOR_EMAIL&lt;/span&gt;&quot; = &quot;&lt;span class=&quot;token variable&quot;&gt;$OLD_EMAIL&lt;/span&gt;&quot; ]
then
    export GIT_AUTHOR_NAME=&quot;&lt;span class=&quot;token variable&quot;&gt;$CORRECT_NAME&lt;/span&gt;&quot;
    export GIT_AUTHOR_EMAIL=&quot;&lt;span class=&quot;token variable&quot;&gt;$CORRECT_EMAIL&lt;/span&gt;&quot;
fi
&apos;&lt;/span&gt; --tag-name-filter &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; -- --branches --tags&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I got a nasty warning, but after a few seconds it proceeded with the rewrite and the world didn’t seem to end. I guess I could have tried the &lt;a href=&quot;https://github.com/newren/git-filter-repo/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;suggested alternative&lt;/a&gt;, but I only had a few commits and the rewrite seemed mostly innocuous.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;WARNING: git-filter-branch has a glut of gotchas generating mangled history
         rewrites.  Hit Ctrl-C before proceeding to abort, then use an
         alternative filtering tool such as &amp;#39;git filter-repo&amp;#39;
         (https://github.com/newren/git-filter-repo/) instead.  See the
         filter-branch manual page for more details; to squelch this warning,
         set FILTER_BRANCH_SQUELCH_WARNING=1.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;code class=&quot;language-text&quot;&gt;git push --force&lt;/code&gt; and my repo commits were updated with my personal email.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[TMUX, WSL, Copy & Paste with Mouse]]></title><description><![CDATA[I wanted to use  and still be able to highlight text with my mouse and have it copied to the system clipboard.  captures mouse commands…]]></description><link>https://blog.dfaiv.devfoo/bar</link><guid isPermaLink="false">https://blog.dfaiv.devfoo/bar</guid><pubDate>Tue, 02 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I wanted to use &lt;code class=&quot;language-text&quot;&gt;tmux&lt;/code&gt; and still be able to highlight text with my mouse and have it copied to the system clipboard. &lt;code class=&quot;language-text&quot;&gt;tmux&lt;/code&gt; captures mouse commands though, so the copy/paste wasn’t making it out.&lt;/p&gt;
&lt;p&gt;Turns out, using the default &lt;code class=&quot;language-text&quot;&gt;WSL Bash on Windows&lt;/code&gt; shell, you just hold the &lt;code class=&quot;language-text&quot;&gt;shift key&lt;/code&gt; along with your mouse actions.&lt;/p&gt;
&lt;p&gt;There are some more complex options out there, but this was all I needed.&lt;/p&gt;
&lt;p&gt;Details: &lt;a href=&quot;https://github.com/Microsoft/WSL/issues/1586#issuecomment-272235493&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/Microsoft/WSL/issues/1586#issuecomment-272235493&lt;/a&gt;&lt;/p&gt;</content:encoded></item></channel></rss>