Skip to content

Commit e3ad967

Browse files
authored
Merge pull request #23 from johnkellyoxford/dev
Dev to master
2 parents b90366a + 9d83d2c commit e3ad967

17 files changed

+553
-136
lines changed

CryptoTools/AesCryptoManager.cs

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
using System;
2+
using System.Diagnostics;
3+
using System.IO;
4+
using System.Security.Cryptography;
5+
using utils;
6+
using static System.Diagnostics.Stopwatch;
7+
8+
namespace CryptoTools
9+
{
10+
public class AesCryptoManager
11+
{
12+
/// <summary>
13+
/// Encrypts data from one file to another using AES
14+
/// </summary>
15+
/// <param name="inputFile">The file path to the unencrypted data</param>
16+
/// <param name="outputFile">The file path to output the encrypted data to</param>
17+
/// <param name="keyBytes">The bytes of the key</param>
18+
/// <returns>true if successful, else false</returns>
19+
public bool EncryptFileBytes(string inputFile, string outputFile, byte[] keyBytes)
20+
{
21+
22+
var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
23+
24+
// Any cryptographic exception indicates the data is invalid or an incorrect password has been inputted
25+
try
26+
{
27+
28+
// Creates the instance used to encrypt. This implements IDisposable so is inside a using statement
29+
using (var aes = new AesCryptoServiceProvider())
30+
{
31+
32+
// AESManaged properties
33+
aes.KeySize = 256;
34+
aes.BlockSize = 128;
35+
aes.Padding = PaddingMode.PKCS7;
36+
aes.Mode = CipherMode.CBC;
37+
38+
#if DEBUG
39+
// Debug values
40+
if (!Stopwatch.IsHighResolution) { throw new Exception("You don't have a high-res sysclock"); }
41+
var iterations = 0L;
42+
var fullIterationTime = 0.0D;
43+
var watch = StartNew();
44+
var avgIterationMilliseconds = 0D;
45+
#endif
46+
47+
// Derives a key using PBKDF2 from the password and a salt
48+
var key = new Rfc2898DeriveBytes(keyBytes, saltBytes, 100000);
49+
50+
// Set actual IV and key
51+
aes.Key = key.GetBytes(aes.KeySize / 8);
52+
aes.IV = key.GetBytes(aes.BlockSize / 8);
53+
54+
// Creates the streams necessary for reading and writing data
55+
using (var outFileStream = File.Create(outputFile))
56+
using (var cs = new CryptoStream(outFileStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
57+
using (var inFile = new BinaryReader(File.OpenRead(inputFile))) // BinaryReader is not a stream, but it's only argument is one
58+
{
59+
// Continuously reads the stream until it hits an EndOfStream exception
60+
while (true)
61+
{
62+
try
63+
{
64+
#if DEBUG
65+
var offset = watch.Elapsed.TotalMilliseconds;
66+
#endif
67+
var data = inFile.ReadByte();
68+
cs.WriteByte(data);
69+
#if DEBUG
70+
var perIterationMilliseconds = watch.Elapsed.TotalMilliseconds - offset;
71+
avgIterationMilliseconds = (avgIterationMilliseconds * iterations + perIterationMilliseconds) / (iterations + 1);
72+
fullIterationTime += perIterationMilliseconds;
73+
iterations++;
74+
#endif
75+
}
76+
catch (EndOfStreamException)
77+
{
78+
#if DEBUG
79+
var totalMilliseconds = watch.Elapsed.TotalMilliseconds;
80+
var totalSeconds = totalMilliseconds / 1000;
81+
double perIterationSeconds = avgIterationMilliseconds / 1000,
82+
perIterationMilliseconds = avgIterationMilliseconds;
83+
var toWrite = new[] {"Time to encrypt (s):" + totalSeconds, "Time to encrypt (ms):" + totalMilliseconds,
84+
"Average iteration length (s):" + perIterationSeconds.ToString("0." + new string('#', 339)), "Average iteration length (ms):" + perIterationMilliseconds.ToString("0." + new string('#', 339)),
85+
"Time of all iterations, combined (s):" + fullIterationTime / 1000, "Time of all iterations, combined (ms):" + fullIterationTime,
86+
"Iterations:" + iterations};
87+
88+
Utils.WriteToDiagnosticsFile(toWrite);
89+
#endif
90+
91+
break;
92+
}
93+
}
94+
}
95+
}
96+
}
97+
catch (CryptographicException) // If something went wrong, we get it here
98+
{
99+
return false;
100+
}
101+
102+
return true;
103+
}
104+
105+
/// <summary>
106+
/// Encrypts data from one file to another using AES
107+
/// </summary>
108+
/// <param name="inputFile">The file path to the unencrypted data</param>
109+
/// <param name="outputFile">The file path to output the encrypted data to</param>
110+
/// <param name="keyBytes">The bytes of the key</param>
111+
/// <returns>true if successful, else false</returns>
112+
public bool DecryptFileBytes(string inputFile, string outputFile, byte[] keyBytes)
113+
{
114+
115+
var saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
116+
117+
// Any cryptographic exception indicates the data is invalid or an incorrect password has been inputted
118+
try
119+
{
120+
121+
// Creates the instance used to decrypt. This implements IDisposable so is inside a using statement
122+
using (var aes = new AesCryptoServiceProvider())
123+
{
124+
125+
// AESManaged properties
126+
aes.KeySize = 256;
127+
aes.BlockSize = 128;
128+
aes.Padding = PaddingMode.PKCS7;
129+
aes.Mode = CipherMode.CBC;
130+
131+
#if DEBUG
132+
// Debug values
133+
if (!Stopwatch.IsHighResolution) { throw new Exception("You don't have a high-res sysclock"); }
134+
var iterations = 0L;
135+
var fullIterationTime = 0.0D;
136+
var watch = StartNew();
137+
var avgIterationMilliseconds = 0D;
138+
#endif
139+
140+
// Derives a key using PBKDF2 from the password and a salt
141+
var key = new Rfc2898DeriveBytes(keyBytes, saltBytes, 100000);
142+
143+
// Set actual IV and key
144+
aes.Key = key.GetBytes(aes.KeySize / 8);
145+
aes.IV = key.GetBytes(aes.BlockSize / 8);
146+
147+
// Creates the streams necessary for reading and writing data
148+
using (var outFileStream = File.Create(outputFile))
149+
using (var cs = new CryptoStream(outFileStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
150+
using (var inFile = new BinaryReader(File.OpenRead(inputFile))) // BinaryReader is not a stream, but it's only argument is one
151+
{
152+
// Continuously reads the stream until it hits an EndOfStream exception
153+
while (true)
154+
{
155+
try
156+
{
157+
#if DEBUG
158+
var offset = watch.Elapsed.TotalMilliseconds;
159+
#endif
160+
var data = inFile.ReadByte();
161+
cs.WriteByte(data);
162+
#if DEBUG
163+
var perIterationMilliseconds = watch.Elapsed.TotalMilliseconds - offset;
164+
avgIterationMilliseconds = (avgIterationMilliseconds * iterations + perIterationMilliseconds) / (iterations + 1);
165+
fullIterationTime += perIterationMilliseconds;
166+
iterations++;
167+
#endif
168+
}
169+
catch (EndOfStreamException)
170+
{
171+
#if DEBUG
172+
var totalMilliseconds = watch.Elapsed.TotalMilliseconds;
173+
var totalSeconds = totalMilliseconds / 1000;
174+
double perIterationSeconds = avgIterationMilliseconds / 1000,
175+
perIterationMilliseconds = avgIterationMilliseconds;
176+
var toWrite = new[] {"Time to encrypt (s):" + totalSeconds, "Time to encrypt (ms):" + totalMilliseconds,
177+
"Average iteration length (s):" + perIterationSeconds.ToString("0." + new string('#', 339)), "Average iteration length (ms):" + perIterationMilliseconds.ToString("0." + new string('#', 339)),
178+
"Time of all iterations, combined (s):" + fullIterationTime / 1000, "Time of all iterations, combined (ms):" + fullIterationTime,
179+
"Iterations:" + iterations};
180+
181+
Utils.WriteToDiagnosticsFile(toWrite);
182+
#endif
183+
184+
break;
185+
}
186+
}
187+
}
188+
}
189+
}
190+
catch (CryptographicException) // If something went wrong, we get it here
191+
{
192+
return false;
193+
}
194+
195+
return true;
196+
}
197+
}
198+
}

CryptoTools/CryptoTools.csproj

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{BD173487-6AA1-4376-9464-7090A1925F6A}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>CryptoTools</RootNamespace>
11+
<AssemblyName>CryptoTools</AssemblyName>
12+
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<Deterministic>true</Deterministic>
15+
<TargetFrameworkProfile />
16+
</PropertyGroup>
17+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<DebugType>pdbonly</DebugType>
28+
<Optimize>true</Optimize>
29+
<OutputPath>bin\Release\</OutputPath>
30+
<DefineConstants>TRACE</DefineConstants>
31+
<ErrorReport>prompt</ErrorReport>
32+
<WarningLevel>4</WarningLevel>
33+
</PropertyGroup>
34+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
35+
<DebugSymbols>true</DebugSymbols>
36+
<OutputPath>bin\x64\Debug\</OutputPath>
37+
<DefineConstants>DEBUG;TRACE</DefineConstants>
38+
<DebugType>full</DebugType>
39+
<PlatformTarget>x64</PlatformTarget>
40+
<ErrorReport>prompt</ErrorReport>
41+
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
42+
</PropertyGroup>
43+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
44+
<OutputPath>bin\x64\Release\</OutputPath>
45+
<DefineConstants>TRACE</DefineConstants>
46+
<Optimize>true</Optimize>
47+
<DebugType>pdbonly</DebugType>
48+
<PlatformTarget>x64</PlatformTarget>
49+
<ErrorReport>prompt</ErrorReport>
50+
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
51+
</PropertyGroup>
52+
<ItemGroup>
53+
<Reference Include="System" />
54+
<Reference Include="System.Core" />
55+
<Reference Include="System.Xml.Linq" />
56+
<Reference Include="System.Data.DataSetExtensions" />
57+
<Reference Include="Microsoft.CSharp" />
58+
<Reference Include="System.Data" />
59+
<Reference Include="System.Net.Http" />
60+
<Reference Include="System.Xml" />
61+
</ItemGroup>
62+
<ItemGroup>
63+
<Compile Include="AesCryptoManager.cs" />
64+
<Compile Include="MessageAuthenticator.cs" />
65+
<Compile Include="Properties\AssemblyInfo.cs" />
66+
</ItemGroup>
67+
<ItemGroup>
68+
<ProjectReference Include="..\UnitTests\UnitTests.csproj">
69+
<Project>{1c6d1346-027c-445e-a0bf-0a329e829794}</Project>
70+
<Name>UnitTests</Name>
71+
</ProjectReference>
72+
<ProjectReference Include="..\utils\utils.csproj">
73+
<Project>{0fa675c6-6565-4f9a-b9d0-56118c9ae1a8}</Project>
74+
<Name>utils</Name>
75+
</ProjectReference>
76+
</ItemGroup>
77+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
78+
</Project>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using System.Linq;
33
using System.Security.Cryptography;
44

5-
namespace Encryption_App.Backend
5+
namespace CryptoTools
66
{
77
/// <summary>
88
/// Used for signing and verifying HMACs
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("CryptoTools")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("CryptoTools")]
13+
[assembly: AssemblyCopyright("Copyright © 2018")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("bd173487-6aa1-4376-9464-7090a1925f6a")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]

EncryptionApp.sln

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,50 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EncryptionApp", "src\Encryp
77
EndProject
88
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "utils", "utils\utils.csproj", "{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}"
99
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{1C6D1346-027C-445E-A0BF-0A329E829794}"
11+
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CryptoTools", "CryptoTools\CryptoTools.csproj", "{BD173487-6AA1-4376-9464-7090A1925F6A}"
13+
EndProject
1014
Global
1115
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1216
Debug|Any CPU = Debug|Any CPU
17+
Debug|x64 = Debug|x64
1318
Release|Any CPU = Release|Any CPU
19+
Release|x64 = Release|x64
1420
EndGlobalSection
1521
GlobalSection(ProjectConfigurationPlatforms) = postSolution
1622
{701B9935-7BF8-4BA2-861A-7764761C1318}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1723
{701B9935-7BF8-4BA2-861A-7764761C1318}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{701B9935-7BF8-4BA2-861A-7764761C1318}.Debug|x64.ActiveCfg = Debug|x64
25+
{701B9935-7BF8-4BA2-861A-7764761C1318}.Debug|x64.Build.0 = Debug|x64
1826
{701B9935-7BF8-4BA2-861A-7764761C1318}.Release|Any CPU.ActiveCfg = Release|Any CPU
1927
{701B9935-7BF8-4BA2-861A-7764761C1318}.Release|Any CPU.Build.0 = Release|Any CPU
28+
{701B9935-7BF8-4BA2-861A-7764761C1318}.Release|x64.ActiveCfg = Release|x64
29+
{701B9935-7BF8-4BA2-861A-7764761C1318}.Release|x64.Build.0 = Release|x64
2030
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2131
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Debug|x64.ActiveCfg = Debug|x64
33+
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Debug|x64.Build.0 = Debug|x64
2234
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
2335
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Release|Any CPU.Build.0 = Release|Any CPU
36+
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Release|x64.ActiveCfg = Release|x64
37+
{0FA675C6-6565-4F9A-B9D0-56118C9AE1A8}.Release|x64.Build.0 = Release|x64
38+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Debug|Any CPU.Build.0 = Debug|Any CPU
40+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Debug|x64.ActiveCfg = Debug|x64
41+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Debug|x64.Build.0 = Debug|x64
42+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Release|x64.ActiveCfg = Release|x64
45+
{1C6D1346-027C-445E-A0BF-0A329E829794}.Release|x64.Build.0 = Release|x64
46+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
47+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
48+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Debug|x64.ActiveCfg = Debug|x64
49+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Debug|x64.Build.0 = Debug|x64
50+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Release|Any CPU.Build.0 = Release|Any CPU
52+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Release|x64.ActiveCfg = Release|x64
53+
{BD173487-6AA1-4376-9464-7090A1925F6A}.Release|x64.Build.0 = Release|x64
2454
EndGlobalSection
2555
GlobalSection(SolutionProperties) = preSolution
2656
HideSolutionNode = FALSE
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
[assembly: AssemblyTitle("UnitTests")]
6+
[assembly: AssemblyDescription("")]
7+
[assembly: AssemblyConfiguration("")]
8+
[assembly: AssemblyCompany("")]
9+
[assembly: AssemblyProduct("UnitTests")]
10+
[assembly: AssemblyCopyright("Copyright © 2018")]
11+
[assembly: AssemblyTrademark("")]
12+
[assembly: AssemblyCulture("")]
13+
14+
[assembly: ComVisible(false)]
15+
16+
[assembly: Guid("1c6d1346-027c-445e-a0bf-0a329e829794")]
17+
18+
// [assembly: AssemblyVersion("1.0.*")]
19+
[assembly: AssemblyVersion("1.0.0.0")]
20+
[assembly: AssemblyFileVersion("1.0.0.0")]

0 commit comments

Comments
 (0)