Browse Source

- Added AES 128 CFB encrypt/decrypt with IV padding.

- Added helper to edit/remove two factor secrets to/from Git.
- Removed uneccessary references.
- Added initial Unit Tests.
master
Teknikode 2 years ago
parent
commit
181e20d86c

+ 24
- 0
Teknik.sln View File

@@ -26,6 +26,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Configuration", "Utilities\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeknikStreaming", "TeknikStreaming\TeknikStreaming.csproj", "{7695CE9A-A0DB-4D73-BC9B-2206481F0254}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FAC9FE6E-9AA9-45AD-AA72-40DDF7DC44C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtilitiesTests", "UtilitiesTests\UtilitiesTests.csproj", "{88DEB506-3F7E-4B39-8264-861976DC7434}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeknikTests", "TeknikTests\TeknikTests.csproj", "{9D7A805E-2629-476E-B36A-040AD332C7DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -91,11 +97,29 @@ Global
{7695CE9A-A0DB-4D73-BC9B-2206481F0254}.Release|Any CPU.Build.0 = Release|Any CPU
{7695CE9A-A0DB-4D73-BC9B-2206481F0254}.Release|x64.ActiveCfg = Release|Any CPU
{7695CE9A-A0DB-4D73-BC9B-2206481F0254}.Release|x64.Build.0 = Release|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Debug|x64.ActiveCfg = Debug|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Debug|x64.Build.0 = Debug|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Release|Any CPU.Build.0 = Release|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Release|x64.ActiveCfg = Release|Any CPU
{88DEB506-3F7E-4B39-8264-861976DC7434}.Release|x64.Build.0 = Release|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Debug|x64.ActiveCfg = Debug|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Debug|x64.Build.0 = Debug|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Release|Any CPU.Build.0 = Release|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Release|x64.ActiveCfg = Release|Any CPU
{9D7A805E-2629-476E-B36A-040AD332C7DC}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E08975F9-1B84-41B0-875A-CEC9778C4F9E} = {783361EC-DCD6-4A34-8479-5476DF752C34}
{88DEB506-3F7E-4B39-8264-861976DC7434} = {FAC9FE6E-9AA9-45AD-AA72-40DDF7DC44C6}
{9D7A805E-2629-476E-B36A-040AD332C7DC} = {FAC9FE6E-9AA9-45AD-AA72-40DDF7DC44C6}
EndGlobalSection
EndGlobal

+ 0
- 1
Teknik/Areas/Upload/Controllers/UploadController.cs View File

@@ -19,7 +19,6 @@ using Teknik.Utilities;
using Teknik.Models;
using Teknik.Attributes;
using System.Text;
using Org.BouncyCastle.Crypto;
using Teknik.Utilities.Cryptography;

namespace Teknik.Areas.Upload.Controllers

+ 0
- 1
Teknik/Areas/Upload/Uploader.cs View File

@@ -7,7 +7,6 @@ using Teknik.Configuration;
using Teknik.Models;
using Teknik.Utilities;
using System.Text;
using Org.BouncyCastle.Utilities.Encoders;
using Teknik.Utilities.Cryptography;

namespace Teknik.Areas.Upload

+ 12
- 0
Teknik/Areas/User/Controllers/UserController.cs View File

@@ -452,11 +452,23 @@ namespace Teknik.Areas.Users.Controllers
{
// They just enabled it, let's regen the key
newKey = Authenticator.GenerateKey();

// New key, so let's upsert their key into git
if (Config.GitConfig.Enabled)
{
UserHelper.CreateUserGitTwoFactor(Config, user.Username, newKey, DateTimeHelper.GetUnixTimestamp());
}
}
else if (!twoFactorEnabled)
{
// remove the key when it's disabled
newKey = string.Empty;

// Removed the key, so delete it from git as well
if (Config.GitConfig.Enabled)
{
UserHelper.DeleteUserGitTwoFactor(Config, user.Username);
}
}
else
{

+ 119
- 1
Teknik/Areas/User/Utility/UserHelper.cs View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -18,6 +19,9 @@ using Teknik.Configuration;
using Teknik.Utilities;
using Teknik.Models;
using Teknik.Utilities.Cryptography;
using MD5 = Teknik.Utilities.Cryptography.MD5;
using SHA256 = Teknik.Utilities.Cryptography.SHA256;
using SHA384 = Teknik.Utilities.Cryptography.SHA384;

namespace Teknik.Areas.Users.Utility
{
@@ -971,6 +975,12 @@ If you recieved this email and you did not reset your password, you can ignore t

if (config.GitConfig.Enabled)
{
// Git user exists?
if (UserGitExists(config, username))
{
throw new Exception($"Git User '{username}' does not exist.");
}

string email = GetUserEmailAddress(config, username);
// We need to check the actual git database
MysqlDatabase mySQL = new MysqlDatabase(config.GitConfig.Database.Server, config.GitConfig.Database.Database, config.GitConfig.Database.Username, config.GitConfig.Database.Password, config.GitConfig.Database.Port);
@@ -1030,10 +1040,16 @@ If you recieved this email and you did not reset your password, you can ignore t
// If Git is enabled
if (config.GitConfig.Enabled)
{
// Git user exists?
if (UserGitExists(config, username))
{
throw new Exception($"Git User '{username}' does not exist.");
}

string email = GetUserEmailAddress(config, username);
using (var client = new WebClient())
{
var obj = new { source_id = config.GitConfig.SourceId, email = email, login_name = email, password = password };
var obj = new {source_id = config.GitConfig.SourceId, email = email, login_name = email, password = password};
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
client.Headers[HttpRequestHeader.ContentType] = "application/json";
Uri baseUri = new Uri(config.GitConfig.Host);
@@ -1048,6 +1064,102 @@ If you recieved this email and you did not reset your password, you can ignore t
}
}

public static void CreateUserGitTwoFactor(Config config, string username, string secret, int unixTime)
{
try
{
// If Git is enabled
if (config.GitConfig.Enabled)
{
// Git user exists?
if (UserGitExists(config, username))
{
throw new Exception($"Git User '{username}' does not exist.");
}

// Generate the scratch token
string token = StringHelper.RandomString(8);

// Get the Encryption Key from the git secret key
byte[] keyBytes = MD5.Hash(Encoding.UTF8.GetBytes(config.GitConfig.SecretKey));

// Modify the input secret
byte[] secBytes = Encoding.UTF8.GetBytes(secret);

// Generate the encrypted secret using AES CGM
byte[] encValue = Aes128CFB.Encrypt(secBytes, keyBytes);
string finalSecret = Convert.ToBase64String(encValue);

// Create connection to the DB
MysqlDatabase mySQL = new MysqlDatabase(config.GitConfig.Database.Server, config.GitConfig.Database.Database, config.GitConfig.Database.Username, config.GitConfig.Database.Password, config.GitConfig.Database.Port);

// Get the user's UID
string email = GetUserEmailAddress(config, username);
string userSelect = @"SELECT id FROM gogs.user WHERE gogs.user.login_name = {0}";
var uid = mySQL.ScalarQuery(userSelect, new object[] { email });

// See if they have Two Factor already
string sqlSelect = @"SELECT id
FROM gogs.two_factor
LEFT JOIN gogs.user ON gogs.user.id = gogs.gogs.two_factor.uid
WHERE gogs.user.login_name = {0}";
var result = mySQL.ScalarQuery(sqlSelect, new object[] { email });
if (result != null)
{
// They have an entry! Let's update it
string insert = @"UPDATE gogs.two_factor SET uid = {1}, secret = {2}, scratch_token = {3}, updated_unix = {4} WHERE gogs.two_factor.id = {0}";

mySQL.Execute(insert, new object[] { result, uid, finalSecret, token, unixTime });
}
else
{
// They need a new entry
string update = @"INSERT INTO gogs.two_factor SET (uid, secret, scratch_token, created_unix, updated_unix) VALUES ({0}, {1}, {2}, {3}, {4})";

mySQL.Execute(update, new object[] { uid, finalSecret, token, unixTime, 0 });
}
}
}
catch (Exception ex)
{
throw new Exception("Unable to edit git account two factor.", ex);
}
}

public static void DeleteUserGitTwoFactor(Config config, string username)
{
try
{
// If Git is enabled
if (config.GitConfig.Enabled)
{
// Git user exists?
if (UserGitExists(config, username))
{
throw new Exception($"Git User '{username}' does not exist.");
}

// Create connection to the DB
MysqlDatabase mySQL = new MysqlDatabase(config.GitConfig.Database.Server, config.GitConfig.Database.Database, config.GitConfig.Database.Username, config.GitConfig.Database.Password, config.GitConfig.Database.Port);

// Get the user's UID
string email = GetUserEmailAddress(config, username);

// See if they have Two Factor already
string deleteSql = @"DELETE tf.*
FROM gogs.two_factor tf
LEFT JOIN gogs.user u ON u.id = tf.uid
WHERE u.login_name = {0}";
mySQL.Execute(deleteSql, new object[] { email });
}
}
catch (Exception ex)
{
throw new Exception("Unable to delete git account two factor.", ex);
}
}

public static void DeleteUserGit(Config config, string username)
{
try
@@ -1055,6 +1167,12 @@ If you recieved this email and you did not reset your password, you can ignore t
// If Git is enabled
if (config.GitConfig.Enabled)
{
// Git user exists?
if (UserGitExists(config, username))
{
throw new Exception($"Git User '{username}' does not exist.");
}

try
{
Uri baseUri = new Uri(config.GitConfig.Host);

+ 0
- 4
Teknik/Teknik.csproj View File

@@ -51,10 +51,6 @@
<HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
<HintPath>..\packages\BouncyCastle.1.8.1\lib\BouncyCastle.Crypto.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll</HintPath>
<Private>True</Private>

+ 0
- 1
Teknik/packages.config View File

@@ -4,7 +4,6 @@
<package id="bootstrap" version="3.3.7" targetFramework="net452" userInstalled="true" />
<package id="Bootstrap.Flat" version="3.3.4" targetFramework="net452" />
<package id="Bootstrap.Switch" version="3.3.2.1" targetFramework="net452" />
<package id="BouncyCastle" version="1.8.1" targetFramework="net452" />
<package id="EntityFramework" version="6.1.3" targetFramework="net452" userInstalled="true" />
<package id="FontAwesome" version="4.7.0" targetFramework="net462" userInstalled="true" />
<package id="GitVersionTask" version="3.6.5" targetFramework="net462" developmentDependency="true" />

+ 36
- 0
TeknikTests/Properties/AssemblyInfo.cs View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TeknikTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Teknik")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9d7a805e-2629-476e-b36a-040ad332c7dc")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 83
- 0
TeknikTests/TeknikTests.csproj View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props" Condition="Exists('..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9D7A805E-2629-476E-B36A-040AD332C7DC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Teknik.Tests.TeknikTests</RootNamespace>
<AssemblyName>TeknikTests</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props'))" />
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 12
- 0
TeknikTests/packages.config View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="xunit" version="2.2.0" targetFramework="net462" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net462" />
<package id="xunit.assert" version="2.2.0" targetFramework="net462" />
<package id="xunit.core" version="2.2.0" targetFramework="net462" />
<package id="xunit.extensibility.core" version="2.2.0" targetFramework="net462" />
<package id="xunit.extensibility.execution" version="2.2.0" targetFramework="net462" />
<package id="xunit.runner.console" version="2.2.0" targetFramework="net462" developmentDependency="true" />
<package id="xunit.runner.msbuild" version="2.2.0" targetFramework="net462" developmentDependency="true" />
<package id="xunit.runner.visualstudio" version="2.2.0" targetFramework="net462" developmentDependency="true" />
</packages>

+ 3
- 0
Utilities/Configuration/GitConfig.cs View File

@@ -14,6 +14,8 @@ namespace Teknik.Configuration

public string AccessToken { get; set; }

public string SecretKey { get; set; }

public int SourceId { get; set; }

public DatabaseConfig Database { get; set; }
@@ -23,6 +25,7 @@ namespace Teknik.Configuration
Enabled = true;
Host = string.Empty;
AccessToken = string.Empty;
SecretKey = string.Empty;
SourceId = 1;
Database = new DatabaseConfig();
}

+ 74
- 0
Utilities/Utilities/Cryptography/AES.cs View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Teknik.Utilities.Cryptography
{
public static class AES
{
public static byte[] Encrypt(byte[] value, byte[] key, byte[] iv, int keyLength, int blockLength, int feedbackSize, CipherMode mode, PaddingMode paddingMode)
{
using (var cipher = CreateCipher(key, iv, keyLength, blockLength, feedbackSize, mode, paddingMode))
{
return Encrypt(cipher, value);
}
}
public static byte[] Decrypt(byte[] value, byte[] key, byte[] iv, int keyLength, int blockLength, int feedbackSize, CipherMode mode, PaddingMode paddingMode)
{
using (var cipher = CreateCipher(key, iv, keyLength, blockLength, feedbackSize, mode, paddingMode))
{
return Decrypt(cipher, value);
}
}

public static byte[] Encrypt(RijndaelManaged cipher, byte[] value)
{
byte[] encryptedBytes;
using (var encryptor = cipher.CreateEncryptor())
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (var bw = new BinaryWriter(cs, Encoding.UTF8))
{
bw.Write(value);
bw.Close();

encryptedBytes = ms.ToArray();
}
return encryptedBytes;
}

public static byte[] Decrypt(RijndaelManaged cipher, byte[] value)
{
byte[] decryptedBytes;
using (var decryptor = cipher.CreateDecryptor())
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
using (var bw = new BinaryWriter(cs, Encoding.UTF8))
{
bw.Write(value);
bw.Close();

decryptedBytes = ms.ToArray();
}
return decryptedBytes;
}

public static RijndaelManaged CreateCipher(byte[] key, byte[] iv, int keyLength, int blockSize, int feedbackSize, CipherMode mode, PaddingMode paddingMode)
{
RijndaelManaged cipher = new RijndaelManaged();
cipher.Mode = mode;
cipher.Padding = paddingMode;
cipher.Key = key;
cipher.IV = iv;
cipher.KeySize = keyLength;
cipher.BlockSize = blockSize;
cipher.FeedbackSize = feedbackSize;

return cipher;
}
}
}

+ 83
- 0
Utilities/Utilities/Cryptography/Aes128CFB.cs View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace Teknik.Utilities.Cryptography
{
public static class Aes128CFB
{
public static byte[] Encrypt(byte[] text, byte[] key)
{
int blockSize = 128;
int keySize = 128;

// Encode the text
string textEnc = Convert.ToBase64String(text);
byte[] textBytes = Encoding.UTF8.GetBytes(textEnc);

// cipherArray
int cipherLen = (blockSize / 8) + textEnc.Length;
byte[] cipherText = new byte[cipherLen];
Array.Clear(cipherText, 0, cipherLen);

// Create the IV needed for this operation
string ivStr = StringHelper.RandomString(blockSize / 8);
byte[] ivBytes = Encoding.UTF8.GetBytes(ivStr);

// copy IV to the cipher text start
ivBytes.CopyTo(cipherText, 0);

// Process the cipher
ProcessCipher(true, textBytes, key, ivBytes, blockSize, keySize, ref cipherText, blockSize / 8);

return cipherText;
}

public static byte[] Decrypt(byte[] text, byte[] key)
{
int blockSize = 128;
int keySize = 128;

// Grab the IV and encrypted text from the original text
byte[] ivBytes = text.Take(blockSize / 8).ToArray();
text = text.Skip(blockSize / 8).Take(text.Length - (blockSize / 8)).ToArray();

// Process the cipher
ProcessCipher(false, text, key, ivBytes, blockSize, keySize, ref text, 0);

string encodedText = Encoding.UTF8.GetString(text);
return Convert.FromBase64String(encodedText);
}

public static void ProcessCipher(bool encrypt, byte[] text, byte[] key, byte[] iv, int blockSize, int keySize, ref byte[] output, int offset)
{
using (var cipher = new RijndaelManaged())
{
cipher.BlockSize = blockSize;
cipher.KeySize = keySize;

cipher.Mode = CipherMode.CFB;
cipher.FeedbackSize = 8;
cipher.Padding = PaddingMode.None;

cipher.Key = key;
cipher.IV = iv;

using (var encryptor = (encrypt) ? cipher.CreateEncryptor() : cipher.CreateDecryptor())
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (var bw = new BinaryWriter(cs, Encoding.UTF8))
{
bw.Write(text);
bw.Close();

ms.ToArray().CopyTo(output, offset);
}
}
}
}
}

+ 6
- 0
Utilities/Utilities/Cryptography/MD5.cs View File

@@ -29,6 +29,12 @@ namespace Teknik.Utilities.Cryptography

}

public static byte[] Hash(byte[] value)
{
System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
return md5.ComputeHash(value);
}

public static string FileHash(string filename)
{
try

+ 21
- 0
Utilities/Utilities/DateTimeHelper.cs View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Teknik.Utilities
{
public static class DateTimeHelper
{
public static int GetUnixTimestamp()
{
return DateTime.UtcNow.GetUnixTimestamp();
}

public static int GetUnixTimestamp(this DateTime dt)
{
return (int)(dt.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
}
}
}

+ 1
- 2
Utilities/Utilities/FileGenerateResult.cs View File

@@ -1,5 +1,4 @@
using Org.BouncyCastle.Crypto;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

+ 1
- 2
Utilities/Utilities/ResponseHelper.cs View File

@@ -1,5 +1,4 @@
using Org.BouncyCastle.Crypto;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

+ 6
- 1
Utilities/Utilities/StringHelper.cs View File

@@ -8,7 +8,12 @@ namespace Teknik.Utilities
{
public static class StringHelper
{
public static string RandomString(int length, string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
public static string RandomString(int length)
{
return RandomString(length, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
}

public static string RandomString(int length, string allowedChars)
{
const int byteSize = 0x100;
var allowedCharSet = new HashSet<char>(allowedChars).ToArray();

+ 3
- 0
Utilities/Utilities/Utilities.csproj View File

@@ -102,6 +102,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AccountType.cs" />
<Compile Include="Cryptography\AES.cs" />
<Compile Include="Cryptography\Aes128CFB.cs" />
<Compile Include="Cryptography\AesCounterStream.cs" />
<Compile Include="Cryptography\AesCounterManaged.cs" />
<Compile Include="Cryptography\AesCounterMode.cs" />
@@ -111,6 +113,7 @@
<Compile Include="Cryptography\SHA384.cs" />
<Compile Include="CurrencyHelper.cs" />
<Compile Include="CurrencyType.cs" />
<Compile Include="DateTimeHelper.cs" />
<Compile Include="EntityExtensions.cs" />
<Compile Include="FileGenerateResult.cs" />
<Compile Include="HttpWebResponseResult.cs" />

+ 38
- 0
UtilitiesTests/Cryptography/Aes128Tests.cs View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Teknik.Utilities;
using Teknik.Utilities.Cryptography;
using Xunit;

namespace Teknik.Tests.UtilitiesTests.Cryptography
{
public class Aes128Tests
{
[Fact]
public void Aes128DataTest()
{
string secret = "426KOBTS66KYLFLQ";
string key = "u1GIRvmnIFFHLov";

// Get the Encryption Key from the git secret key
byte[] keyBytes = MD5.Hash(Encoding.UTF8.GetBytes(key));

// Modify the input secret
byte[] secBytes = Encoding.UTF8.GetBytes(secret);

// Generate the encrypted secret using AES CGM
byte[] encValue = Aes128CFB.Encrypt(secBytes, keyBytes);
string finalSecret = Convert.ToBase64String(encValue);

// Decode it
byte[] decodedSecret = Convert.FromBase64String(finalSecret);
byte[] val = Aes128CFB.Decrypt(decodedSecret, keyBytes);
string verify = Encoding.UTF8.GetString(val);

Assert.Equal(secret, verify);
}
}
}

+ 36
- 0
UtilitiesTests/Properties/AssemblyInfo.cs View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("UtilitiesTests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Teknik")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("88deb506-3f7e-4b39-8264-861976dc7434")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

+ 90
- 0
UtilitiesTests/UtilitiesTests.csproj View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props" Condition="Exists('..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props')" />
<Import Project="..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{88DEB506-3F7E-4B39-8264-861976DC7434}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Teknik.Tests.UtilitiesTests</RootNamespace>
<AssemblyName>UtilitiesTests</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.assert, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.core, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.2.0.3545, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Cryptography\Aes128Tests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Utilities\Utilities\Utilities.csproj">
<Project>{F45DE6FC-3754-4954-A20A-4277362CC6C1}</Project>
<Name>Utilities</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.2.0\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.msbuild.2.2.0\build\net452\xunit.runner.msbuild.props'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

+ 12
- 0
UtilitiesTests/packages.config View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="xunit" version="2.2.0" targetFramework="net462" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net462" />
<package id="xunit.assert" version="2.2.0" targetFramework="net462" />
<package id="xunit.core" version="2.2.0" targetFramework="net462" />
<package id="xunit.extensibility.core" version="2.2.0" targetFramework="net462" />
<package id="xunit.extensibility.execution" version="2.2.0" targetFramework="net462" />
<package id="xunit.runner.console" version="2.2.0" targetFramework="net462" developmentDependency="true" />
<package id="xunit.runner.msbuild" version="2.2.0" targetFramework="net462" developmentDependency="true" />
<package id="xunit.runner.visualstudio" version="2.2.0" targetFramework="net462" developmentDependency="true" />
</packages>

Loading…
Cancel
Save