Skip to content

Commit 546e04a

Browse files
author
Filipe GP
authored
Merge pull request #25 from RichardD2/feature/data-types
Enahnced data type support
2 parents 8cfe4c2 + 376b9ba commit 546e04a

33 files changed

+1742
-212
lines changed

.editorconfig

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
[*.cs]
2+
indent_style = space
3+
indent_size = 4
4+
5+
csharp_new_line_before_else = true
6+
csharp_new_line_before_finally = true
7+
csharp_new_line_before_members_in_object_initializers = true
8+
csharp_new_line_before_open_brace = methods, object_collection_array_initializers, control_blocks, types
9+
dotnet_sort_system_directives_first = true
10+
11+
csharp_space_after_cast = false
12+
csharp_space_after_colon_in_inheritance_clause = true
13+
csharp_space_after_keywords_in_control_flow_statements = true
14+
csharp_space_before_colon_in_inheritance_clause = true
15+
csharp_space_between_method_call_empty_parameter_list_parentheses = false
16+
csharp_space_between_method_call_name_and_opening_parenthesis = false
17+
csharp_space_between_method_call_parameter_list_parentheses = false
18+
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
19+
csharp_space_between_method_declaration_parameter_list_parentheses = false
20+
21+
csharp_preserve_single_line_blocks = true
22+
csharp_preserve_single_line_statements = false
23+
csharp_prefer_braces = true:warning
24+
25+
csharp_style_var_when_type_is_apparent = true:suggestion
26+
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
27+
28+
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
29+
csharp_preferred_modifier_order = public,private,internal,protected,static,readonly,sealed,async,override,abstract:suggestion
30+
31+
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
32+
dotnet_style_predefined_type_for_member_access = true:suggestion
33+
dotnet_style_object_initializer = true:suggestion
34+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
35+
csharp_prefer_simple_default_expression = true:suggestion
36+
37+
dotnet_style_qualification_for_field = false:suggestion
38+
dotnet_style_qualification_for_method = false:suggestion
39+
dotnet_style_qualification_for_property = false:suggestion

EntityFrameworkCore.DataEncryption.sln

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pipelines", "pipelines", "{
2828
ProjectSection(SolutionItems) = preProject
2929
.azure\pipelines\azure-pipelines.yml = .azure\pipelines\azure-pipelines.yml
3030
EndProjectSection
31+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5EE4E8BE-6B15-49DB-A4A8-D2CD63D5E90C}"
32+
ProjectSection(SolutionItems) = preProject
33+
.editorconfig = .editorconfig
34+
EndProjectSection
3135
EndProject
3236
Global
3337
GlobalSection(SolutionConfigurationPlatforms) = preSolution

samples/AesSample/Program.cs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
using Microsoft.EntityFrameworkCore.DataEncryption.Providers;
33
using System;
44
using System.Linq;
5+
using System.Security;
56

67
namespace AesSample
78
{
8-
class Program
9+
static class Program
910
{
10-
static void Main(string[] args)
11+
static void Main()
1112
{
1213
var options = new DbContextOptionsBuilder<DatabaseContext>()
1314
.UseInMemoryDatabase(databaseName: "MyInMemoryDatabase")
@@ -23,17 +24,33 @@ static void Main(string[] args)
2324
{
2425
FirstName = "John",
2526
LastName = "Doe",
26-
Email = "john@doe.com"
27+
Email = "john@doe.com",
28+
Password = BuildPassword(),
2729
};
2830

2931
context.Users.Add(user);
3032
context.SaveChanges();
3133

3234
Console.WriteLine($"Users count: {context.Users.Count()}");
3335

34-
user = context.Users.FirstOrDefault();
36+
user = context.Users.First();
3537

36-
Console.WriteLine($"User: {user.FirstName} {user.LastName} - {user.Email}");
38+
Console.WriteLine($"User: {user.FirstName} {user.LastName} - {user.Email} ({user.Password.Length})");
39+
}
40+
41+
static SecureString BuildPassword()
42+
{
43+
SecureString result = new();
44+
result.AppendChar('L');
45+
result.AppendChar('e');
46+
result.AppendChar('t');
47+
result.AppendChar('M');
48+
result.AppendChar('e');
49+
result.AppendChar('I');
50+
result.AppendChar('n');
51+
result.AppendChar('!');
52+
result.MakeReadOnly();
53+
return result;
3754
}
3855
}
3956
}

samples/AesSample/UserEntity.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.ComponentModel.DataAnnotations;
33
using System.ComponentModel.DataAnnotations.Schema;
4+
using System.Security;
45

56
namespace AesSample
67
{
@@ -19,5 +20,7 @@ public class UserEntity
1920
[Required]
2021
[Encrypted]
2122
public string Email { get; set; }
23+
24+
public SecureString Password { get; set; }
2225
}
2326
}

src/EntityFrameworkCore.DataEncryption/Attributes/EncryptedAttribute.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,27 @@
66
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
77
public sealed class EncryptedAttribute : Attribute
88
{
9+
/// <summary>
10+
/// Initializes a new instance of the <see cref="EncryptedAttribute"/> class.
11+
/// </summary>
12+
/// <param name="format">
13+
/// The storage format.
14+
/// </param>
15+
public EncryptedAttribute(StorageFormat format)
16+
{
17+
Format = format;
18+
}
19+
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="EncryptedAttribute"/> class.
22+
/// </summary>
23+
public EncryptedAttribute() : this(StorageFormat.Default)
24+
{
25+
}
26+
27+
/// <summary>
28+
/// Returns the storage format for the database value.
29+
/// </summary>
30+
public StorageFormat Format { get; }
931
}
10-
}
32+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace System.ComponentModel.DataAnnotations
2+
{
3+
/// <summary>
4+
/// Represents the storage format for an encrypted value.
5+
/// </summary>
6+
public enum StorageFormat
7+
{
8+
/// <summary>
9+
/// The format is determined by the model data type.
10+
/// </summary>
11+
Default,
12+
/// <summary>
13+
/// The value is stored in binary.
14+
/// </summary>
15+
Binary,
16+
/// <summary>
17+
/// The value is stored in a Base64-encoded string.
18+
/// </summary>
19+
/// <remarks>
20+
/// <b>NB:</b> If the source property is a <see cref="string"/>,
21+
/// and no encryption provider is configured,
22+
/// the string will not be modified.
23+
/// </remarks>
24+
Base64,
25+
}
26+
}
Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<TargetFrameworks>netstandard2.0</TargetFrameworks>
5-
<LangVersion>9.0</LangVersion>
6-
<AssemblyName>EntityFrameworkCore.DataEncryption</AssemblyName>
7-
<RootNamespace>Microsoft.EntityFrameworkCore.DataEncryption</RootNamespace>
8-
<Version>2.0.0</Version>
9-
<Authors>Filipe GOMES PEIXOTO</Authors>
10-
<PackageId>EntityFrameworkCore.DataEncryption</PackageId>
11-
<PackageProjectUrl>https://github.com/Eastrall/EntityFrameworkCore.DataEncryption</PackageProjectUrl>
12-
<RepositoryUrl>https://github.com/Eastrall/EntityFrameworkCore.DataEncryption.git</RepositoryUrl>
13-
<RepositoryType>git</RepositoryType>
14-
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
15-
<GenerateDocumentationFile>true</GenerateDocumentationFile>
16-
<PackageTags>entity-framework-core, extensions, dotnet-core, dotnet, encryption, fluent-api</PackageTags>
17-
<LangVersion>8.0</LangVersion>
18-
<PackageIcon>icon.png</PackageIcon>
19-
<Copyright>Filipe GOMES PEIXOTO © 2019 - 2020</Copyright>
20-
<Description>A plugin for Microsoft.EntityFrameworkCore to add support of encrypted fields using built-in or custom encryption providers.</Description>
21-
<PackageLicenseFile>LICENSE</PackageLicenseFile>
22-
<PackageReleaseNotes>- Remove initializationVector parameter from `AesProvider` constructor.
23-
- Apply unique IV for each row.</PackageReleaseNotes>
24-
</PropertyGroup>
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0</TargetFrameworks>
5+
<LangVersion>9.0</LangVersion>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
<AssemblyName>EntityFrameworkCore.DataEncryption</AssemblyName>
8+
<RootNamespace>Microsoft.EntityFrameworkCore.DataEncryption</RootNamespace>
9+
<Version>3.0.0</Version>
10+
<Authors>Filipe GOMES PEIXOTO</Authors>
11+
<PackageId>EntityFrameworkCore.DataEncryption</PackageId>
12+
<PackageProjectUrl>https://github.com/Eastrall/EntityFrameworkCore.DataEncryption</PackageProjectUrl>
13+
<RepositoryUrl>https://github.com/Eastrall/EntityFrameworkCore.DataEncryption.git</RepositoryUrl>
14+
<RepositoryType>git</RepositoryType>
15+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
16+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
17+
<PackageTags>entity-framework-core, extensions, dotnet-core, dotnet, encryption, fluent-api</PackageTags>
18+
<PackageIcon>icon.png</PackageIcon>
19+
<Copyright>Filipe GOMES PEIXOTO © 2019 - 2020</Copyright>
20+
<Description>A plugin for Microsoft.EntityFrameworkCore to add support of encrypted fields using built-in or custom encryption providers.</Description>
21+
<PackageLicenseFile>LICENSE</PackageLicenseFile>
22+
<PackageReleaseNotes>
23+
- Add support for storing data as binary or Base64
24+
- Add support for SecureString and binary model properties
25+
</PackageReleaseNotes>
26+
</PropertyGroup>
2527

26-
<ItemGroup>
27-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
28-
</ItemGroup>
28+
<ItemGroup>
29+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
30+
</ItemGroup>
2931

30-
<ItemGroup>
31-
<None Include="..\..\LICENSE">
32-
<Pack>True</Pack>
33-
<PackagePath></PackagePath>
34-
</None>
35-
<None Include="Resources/icon.png" Pack="true" Visible="true" PackagePath="" />
36-
</ItemGroup>
32+
<ItemGroup>
33+
<None Include="..\..\LICENSE">
34+
<Pack>True</Pack>
35+
<PackagePath></PackagePath>
36+
</None>
37+
<None Include="Resources/icon.png" Pack="true" Visible="true" PackagePath="" />
38+
</ItemGroup>
39+
40+
<ItemGroup>
41+
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
42+
<_Parameter1>Microsoft.EntityFrameworkCore.Encryption.Test</_Parameter1>
43+
</AssemblyAttribute>
44+
</ItemGroup>
3745

3846
</Project>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp90</s:String></wpf:ResourceDictionary>
Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,67 @@
1-
namespace Microsoft.EntityFrameworkCore.DataEncryption
1+
using System;
2+
using System.IO;
3+
4+
namespace Microsoft.EntityFrameworkCore.DataEncryption
25
{
36
/// <summary>
47
/// Provides a mechanism for implementing a custom encryption provider.
58
/// </summary>
69
public interface IEncryptionProvider
710
{
811
/// <summary>
9-
/// Encrypts a string.
12+
/// Encrypts a value.
1013
/// </summary>
11-
/// <param name="dataToEncrypt">Input data as a string to encrypt.</param>
12-
/// <returns>Encrypted data as a string.</returns>
13-
string Encrypt(string dataToEncrypt);
14+
/// <typeparam name="TStore">
15+
/// The type of data stored in the database.
16+
/// </typeparam>
17+
/// <typeparam name="TModel">
18+
/// The type of value stored in the model.
19+
/// </typeparam>
20+
/// <param name="dataToEncrypt">
21+
/// Input data to encrypt.
22+
/// </param>
23+
/// <param name="converter">
24+
/// Function which converts the model value to a byte array.
25+
/// </param>
26+
/// <param name="encoder">
27+
/// Function which encodes the value for storing the the database.
28+
/// </param>
29+
/// <returns>
30+
/// Encrypted data.
31+
/// </returns>
32+
/// <exception cref="ArgumentNullException">
33+
/// <para><paramref name="converter"/> is <see langword="null"/>.</para>
34+
/// <para>-or-</para>
35+
/// <para><paramref name="encoder"/> is <see langword="null"/>.</para>
36+
/// </exception>
37+
TStore Encrypt<TStore, TModel>(TModel dataToEncrypt, Func<TModel, byte[]> converter, Func<Stream, TStore> encoder);
1438

1539
/// <summary>
16-
/// Decrypts a string.
40+
/// Decrypts a value.
1741
/// </summary>
18-
/// <param name="dataToDecrypt">Encrypted data as a string to decrypt.</param>
19-
/// <returns>Decrypted data as a string.</returns>
20-
string Decrypt(string dataToDecrypt);
42+
/// <typeparam name="TStore">
43+
/// The type of data stored in the database.
44+
/// </typeparam>
45+
/// <typeparam name="TModel">
46+
/// The type of value stored in the model.
47+
/// </typeparam>
48+
/// <param name="dataToDecrypt">
49+
/// Encrypted data to decrypt.
50+
/// </param>
51+
/// <param name="decoder">
52+
/// Function which converts the stored data to a byte array.
53+
/// </param>
54+
/// <param name="converter">
55+
/// Function which converts the decrypted <see cref="Stream"/> to the return value.
56+
/// </param>
57+
/// <returns>
58+
/// Decrypted data.
59+
/// </returns>
60+
/// <exception cref="ArgumentNullException">
61+
/// <para><paramref name="decoder"/> is <see langword="null"/>.</para>
62+
/// <para>-or-</para>
63+
/// <para><paramref name="converter"/> is <see langword="null"/>.</para>
64+
/// </exception>
65+
TModel Decrypt<TStore, TModel>(TStore dataToDecrypt, Func<TStore, byte[]> decoder, Func<Stream, TModel> converter);
2166
}
2267
}

0 commit comments

Comments
 (0)