Skip to content

Commit 175d2a5

Browse files
committed
fix README.md
1 parent cf9ba00 commit 175d2a5

File tree

1 file changed

+24
-26
lines changed

1 file changed

+24
-26
lines changed

README.md

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,26 @@ adds support for data protection and querying for encrypted properties for your
99

1010
## What problem does this library solve?
1111

12-
When you need to store sensitive data in your database, you may want to encrypt it to protect it from unauthorized access. However, when you
13-
encrypt data, it becomes unreadable by EF-core, which is not really convenient if you want to encrypt, for example, email addresses, or SSNs
14-
AND then query them.
15-
This library (optionally) hashes the sensitive data and stores their sha256 hashes in a shadow property alongside the encrypted data. This
16-
allows you to query the encrypted data without decrypting it first. using `QueryableExt.WherePdEquals`
12+
When you need to store sensitive data in your database, you may want to encrypt it to protect it from unauthorized access, however, when you
13+
encrypt data, it becomes impossible to query it by EF-core, which is not really convenient if you want to encrypt, for example, email addresses, or SSNs
14+
AND then filter entities by them.
15+
This library (optionally) hashes the sensitive data and stores their sha256 hashes in a shadow property alongside the encrypted data.
16+
This allows you to query the encrypted data without decrypting it first. using `QueryableExt.WherePdEquals`
1717

1818
## Disclaimer
1919

20-
This project is maintained by <a href="https://github.com/ddjerqq">ddjerqq</a> and is not affiliated with Microsoft.
20+
This project is maintained by [one (tenx) developer](https://github.com/ddjerqq) and is not affiliated with Microsoft.
2121

22-
I made this library initially to solve my own problems with EFCore when I needed to encrypt personal IDs but also query them. I wanted a
23-
simple yet boilerplate-free solution. Thus, I made this library.
22+
I made this library to solve my own problems with EFCore. I needed to store a bunch of protected personal data encrypted, among these properties were personal IDs, Emails, SocialSecurityNumbers and so on.
23+
As you know, you cannot query encrypted data with EFCore, and I wanted a simple yet boilerplate-free solution. Thus, I made this library.
24+
25+
**What this library allows you to do, is to encrypt your properties and query them without decrypting them first. It does so by hashing the encrypted data and storing the hash in a shadow property alongside the encrypted data.**
2426

2527
I **do not** take responsibility for any damage done in production environments and lose of your encryption key or corruption of your data.
2628

2729
Keeping your encryption keys secure is your responsibility. If you lose your encryption key, **you will lose your data.**
2830

29-
## Supported property types
31+
## Currently supported property types
3032

3133
- string
3234
- byte[]
@@ -54,23 +56,23 @@ public class Your(DbContextOptions<Your> options, IDataProtectionProvider dataPr
5456
protected override void OnModelCreating(ModelBuilder builder)
5557
{
5658
// if you are using IEntityTypeConfiguration<T> in your project
57-
// then ApplyConfigurationsFromAssembly must come before base.OnModelCreating(builder);
59+
// then ApplyConfigurationsFromAssembly must come before base.OnModelCreating
5860
builder.ApplyConfigurationsFromAssembly(typeof(YourDbContext).Assembly);
5961

6062
base.OnModelCreating(builder);
6163

62-
// MUST COME AFTER `base.OnModelCreating(builder);`
64+
// UseDataProtection MUST come after base.OnModelCreating
6365
builder.UseDataProtection(dataProtectionProvider);
6466

65-
// anything else you want to do with the builder must come after the call to UseDataProtection
67+
// anything else you want to do with the builder must come after the call to UseDataProtection, unless you know exactly what you are doing
6668
builder.SnakeCaseRename();
6769
}
6870
}
6971
```
7072

7173
> [!WARNING]
72-
> The call to `builder.UseDataProtection` **MUST** come after the call to `base.OnModelCreating` in your `DbContext` class.
73-
> And before any other configuration you might have.
74+
> The call to `builder.UseDataProtection` **MUST** come after the call to `base.OnModelCreating` in your `DbContext` class
75+
> and before any other configuration you might have.
7476
7577
### Registering the services
7678

@@ -86,7 +88,7 @@ builder.Services.AddDataProtectionServices()
8688

8789
> [!TIP]
8890
> See the [Microsoft documentation](https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview) for more
89-
> information on how to configure the data protection services, and how to store your encryption keys securely.
91+
> information on **how to configure the data protection** services, and how to store your encryption keys securely.
9092
9193
### Marking your properties as encrypted
9294

@@ -96,19 +98,15 @@ Using the EncryptedAttribute:
9698
```csharp
9799
class User
98100
{
99-
public Guid Id { get; set; }
100-
101-
public string Name { get; set; }
102-
103-
[Encrypt(true)]
101+
[Encrypt(isQueryable: true)]
104102
public string SocialSecurityNumber { get; set; }
105103

106104
[Encrypt]
107105
public byte[] IdPicture { get; set; }
108106
}
109107
```
110108

111-
Or using the FluentApi (in your `DbContext.OnModelCreating` method):
109+
Using the FluentApi (in your `DbContext.OnModelCreating` method):
112110
```csharp
113111
protected override void OnModelCreating(ModelBuilder builder)
114112
{
@@ -120,7 +118,7 @@ protected override void OnModelCreating(ModelBuilder builder)
120118
}
121119
```
122120

123-
Or creating a custom `EntityTypeConfiguration`:
121+
Creating a custom `EntityTypeConfiguration` (Recommended for DDD):
124122
```csharp
125123
class UserConfiguration : IEntityTypeConfiguration<User>
126124
{
@@ -142,14 +140,14 @@ var foo = await DbContext.Users
142140
.SingleOrDefaultAsync();
143141
```
144142

145-
> [!TIP]
146-
> Generates an expression like this under the hood:
147-
> `Where(e => EF.Property<string>(e, $"{propertyName}ShadowHash") == value.Sha256Hash())`
148-
149143
> [!WARNING]
150144
> The `QueryableExt.WherePdEquals` method is only available for properties that are marked as Queryable using the `[Encrypt(isQueryable: true)]` attribute or the
151145
> `IsEncrypted(isQueryable: true)` method.
152146
147+
> [!TIP]
148+
> The `WherePdEquals` extension method generates an expression like this one under the hood:<br/>
149+
> `Where(e => EF.Property<string>(e, $"{propertyName}ShadowHash") == value.Sha256Hash())`
150+
153151
### Profit!
154152

155153
## Thank you for using this library!

0 commit comments

Comments
 (0)