{"id":75,"date":"2020-06-13T09:49:07","date_gmt":"2020-06-13T09:49:07","guid":{"rendered":"https:\/\/michaeljohnsteiner.com\/?p=75"},"modified":"2020-12-14T12:27:53","modified_gmt":"2020-12-14T12:27:53","slug":"passwordstretch-cs","status":"publish","type":"post","link":"https:\/\/michaeljohnsteiner.com\/index.php\/2020\/06\/13\/passwordstretch-cs\/","title":{"rendered":"PasswordStretch.cs"},"content":{"rendered":"\n<p>Password Stretch using Sha3<\/p>\n\n\n\n<p>Make passwords more secure by increasing the time and space taken to test each password.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Example Code:\nvar b1   = new byte[0];\n        var b2   = new byte[0];\n        var salt = new byte[0];\n        using (var db = new PasswordStretch(\"1234567890\".ToSecureString(), 16))\n        {\n\n            b1   = (byte[]) db.GetBytes(0, 64).Clone();\n            salt = db.Salt;\n        }\n\n        using (var db = new PasswordStretch(\"1234567891\".ToSecureString(), salt))\n        {\n\n            b2 = (byte[]) db.GetBytes(0, 64).Clone();\n        }<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">using System;\nusing System.Security;\nusing System.Security.Cryptography;\npublic class PasswordStretch : IDisposable\n{\n    private const    int         PacketCount = 4;\n    private readonly byte[]      _buffer;\n    private readonly byte[]      _salt;\n    private readonly SHA3Managed _sha;\n    public PasswordStretch(SecureString password) : this(password, 0, 1000)\n    {\n    }\n    public PasswordStretch(SecureString password, int saltSize) : this(password, saltSize, 1000)\n    {\n    }\n    public PasswordStretch(SecureString password, int saltSize, int iterations)\n    {\n        Iterations = iterations;\n        var temp = new byte[0];\n        if (saltSize != 0)\n        {\n            var data = new byte[saltSize];\n            new RNGCryptoServiceProvider().GetBytes(data);\n            _salt   = data;\n            _sha    = new SHA3Managed(512);\n            _buffer = new byte[_sha.HashLength * PacketCount];\n            _sha.TransformBlock(_salt, 0, _salt.Length, null, 0);\n            var pwb = password.GetBytes();\n            _sha.TransformBlock(pwb, 0, pwb.Length, null, 0);\n            _sha.Finalize();\n            temp = _sha.HashValue;\n        }\n        else\n        {\n            _sha    = new SHA3Managed(512);\n            _buffer = new byte[_sha.HashLength * PacketCount];\n            temp    = _sha.ComputeHash(password.GetBytes());\n        }\n        for (var i = 0; i &lt; PacketCount; i++)\n        {\n            for (var j = 0; j &lt; Iterations; j++)\n                temp = _sha.ComputeHash(temp);\n            Buffer.BlockCopy(temp, 0, _buffer, i * _sha.HashLength, _sha.HashLength);\n        }\n    }\n    public PasswordStretch(SecureString password, byte[] salt) : this(password, salt, 1000)\n    {\n    }\n    public PasswordStretch(SecureString password, byte[] salt, int iterations = 1000)\n    {\n        Iterations = iterations;\n        _sha       = new SHA3Managed(512);\n        _buffer    = new byte[_sha.HashLength * PacketCount];\n        _sha.TransformBlock(salt, 0, salt.Length, null, 0);\n        var pwb = password.GetBytes();\n        _sha.TransformBlock(pwb, 0, pwb.Length, null, 0);\n        _sha.Finalize();\n        var temp = _sha.HashValue;\n        for (var i = 0; i &lt; PacketCount; i++)\n        {\n            for (var j = 0; j &lt; Iterations; j++)\n                temp = _sha.ComputeHash(temp);\n            Buffer.BlockCopy(temp, 0, _buffer, i * _sha.HashLength, _sha.HashLength);\n        }\n    }\n    public byte[] Salt\n    {\n        get\n        {\n            if (_salt != null)\n                return (byte[]) _salt.Clone();\n            return default;\n        }\n    }\n    public int Iterations\n    {\n        get;\n    } = 1000;\n    public void Dispose()\n    {\n        Dispose(true);\n        GC.SuppressFinalize(this);\n    }\n    ~PasswordStretch()\n    {\n        Dispose();\n    }\n    public byte[] GetBytes(int offset, int psize)\n    {\n        if (offset + psize > _buffer.Length)\n            throw new Exception(\"Offset and Size Exceed Buffer Length.\");\n        var passpart = new byte[psize];\n        Buffer.BlockCopy(_buffer, offset, passpart, 0, passpart.Length);\n        return passpart;\n    }\n    private void Dispose(bool disposing)\n    {\n        if (!disposing)\n            return;\n        if (_sha != null)\n            _sha.Dispose();\n        if (_buffer != null)\n            Array.Clear(_buffer, 0, _buffer.Length);\n        if (_salt == null)\n            return;\n        Array.Clear(_salt, 0, _salt.Length);\n    }\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Password Stretch using Sha3 Make passwords more secure by increasing the time and space taken to test each password.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[22,19,21,20],"_links":{"self":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/75"}],"collection":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/comments?post=75"}],"version-history":[{"count":3,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/75\/revisions"}],"predecessor-version":[{"id":274,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/posts\/75\/revisions\/274"}],"wp:attachment":[{"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/media?parent=75"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/categories?post=75"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaeljohnsteiner.com\/index.php\/wp-json\/wp\/v2\/tags?post=75"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}