├── .vscode
└── settings.json
├── .github
├── dependabot.yml
└── workflows
│ └── build.yml
├── src
├── Owin.Security.AesDataProtectorProvider
│ ├── CrypticProviders
│ │ ├── IAesFactory.cs
│ │ ├── ISha256Factory.cs
│ │ ├── ISha512Factory.cs
│ │ ├── AesManagedFactory.cs
│ │ ├── AesCspFactory.cs
│ │ ├── Sha256CspFactory.cs
│ │ ├── Sha256ManagedFactory.cs
│ │ ├── Sha512ManagedFactory.cs
│ │ └── Sha512CspFactory.cs
│ ├── CHANGELOG.md
│ ├── AesDataProtectorProviderException.cs
│ ├── Owin.Security.AesDataProtectorProvider.csproj
│ ├── AesDataProtectorProvider.cs
│ ├── AppBuilderExtensions.cs
│ └── AesDataProtector.cs
├── Owin.Security.AesDataProtectorProvider.Tests
│ ├── Owin.Security.AesDataProtectorProvider.Tests.csproj
│ └── AesDataProtectorTests.cs
└── Owin.Security.AesDataProtectorProvider.sln
├── README.md
├── .gitignore
└── LICENSE
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "FIPS",
4 | "Owin",
5 | "middlewares"
6 | ]
7 | }
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: nuget
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "23:00"
8 | open-pull-requests-limit: 10
9 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/IAesFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Represent AES factory
7 | ///
8 | public interface IAesFactory
9 | {
10 | ///
11 | /// Creates AES instance.
12 | ///
13 | ///
14 | Aes Create();
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/ISha256Factory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Represent SHA256 factory
7 | ///
8 | public interface ISha256Factory
9 | {
10 | ///
11 | /// Creates SHA256 instance.
12 | ///
13 | ///
14 | SHA256 Create();
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/ISha512Factory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Represent SHA512 factory
7 | ///
8 | public interface ISha512Factory
9 | {
10 | ///
11 | /// Creates SHA512 instance.
12 | ///
13 | ///
14 | SHA512 Create();
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [1.2.5] - 2022-11-08
4 |
5 | ### Dependencies
6 |
7 | - Microsoft.Owin.Security bump to v4.2.3
8 |
9 | ## [1.2.4] - 2022-05-18
10 |
11 | ### Dependencies
12 |
13 | - Microsoft.Owin.Security bump to v4.2.2 (PR#45)
14 |
15 | ## [1.2.3] - 2022-04-09
16 |
17 | ### Dependencies
18 |
19 | - Microsoft.Owin.Security bump to v4.2.1
20 |
21 | ## [1.2.2] - 2021-08-08
22 |
23 | ### Dependencies
24 |
25 | - Microsoft.Owin.Security bump to v4.2
26 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/AesManagedFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Provides factory
7 | ///
8 | public class AesManagedFactory : IAesFactory
9 | {
10 | ///
11 | /// Creates AES managed implementation instance.
12 | ///
13 | ///
14 | public Aes Create()
15 | {
16 | return new AesManaged();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/AesCspFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Provides AesCryptoServiceProvider factory
7 | ///
8 | public class AesCspFactory : IAesFactory
9 | {
10 | ///
11 | /// Creates AES CSP implementation instance.
12 | ///
13 | ///
14 | public Aes Create()
15 | {
16 | return new AesCryptoServiceProvider();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/Sha256CspFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Provides SHA256CryptoServiceProvider factory
7 | ///
8 | public class Sha256CspFactory : ISha256Factory
9 | {
10 | ///
11 | /// Creates SHA256 CSP instance.
12 | ///
13 | ///
14 | public SHA256 Create()
15 | {
16 | return new SHA256CryptoServiceProvider();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/Sha256ManagedFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Provides SHA256Managed factory
7 | ///
8 | public class Sha256ManagedFactory : ISha256Factory
9 | {
10 | ///
11 | /// Creates SHA256 managed implementation instance.
12 | ///
13 | ///
14 | public SHA256 Create()
15 | {
16 | return new SHA256Managed();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/Sha512ManagedFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Provides SHA512 managed factory
7 | ///
8 | public class Sha512ManagedFactory : ISha512Factory
9 | {
10 | ///
11 | /// Creates SHA512 managed implementation instance.
12 | ///
13 | ///
14 | public SHA512 Create()
15 | {
16 | return SHA512.Create();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/CrypticProviders/Sha512CspFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider.CrypticProviders
4 | {
5 | ///
6 | /// Provides SHA512CryptoServiceProvider factory
7 | ///
8 | public class Sha512CspFactory : ISha512Factory
9 | {
10 | ///
11 | /// Creates SHA512 CSP implementation instance.
12 | ///
13 | ///
14 | public SHA512 Create()
15 | {
16 | return new SHA512CryptoServiceProvider();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/AesDataProtectorProviderException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Owin.Security.AesDataProtectorProvider
4 | {
5 | ///
6 | /// Provides AesDataProtectorProviderException exception
7 | ///
8 | public class AesDataProtectorProviderException : Exception
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The message that describes the error.
14 | public AesDataProtectorProviderException(string message)
15 | : base(message)
16 | {
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider.Tests/Owin.Security.AesDataProtectorProvider.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net45
4 |
5 | Owin.Security.AesDataProtectorProvider unit tests
6 | Owin.Security.AesDataProtectorProvider
7 | Alexander Krylkov
8 | Licensed under LGPL
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build Package
2 |
3 | on: push
4 |
5 | defaults:
6 | run:
7 | working-directory: src
8 |
9 | jobs:
10 | build:
11 | runs-on: ${{ matrix.os }}
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | os: [ubuntu-22.04, windows-latest]
16 |
17 | steps:
18 | - name: Code Checkout
19 | uses: actions/checkout@v4.1.1
20 |
21 | - name: Install DotNet
22 | uses: actions/setup-dotnet@v4
23 |
24 | - name: Restore Dependencies
25 | run: dotnet restore
26 |
27 | - name: Build Package
28 | run: dotnet build --no-restore -c Release
29 |
30 | - name: Perform Unit Testing
31 | run: dotnet test --no-build -c Release --filter TestCategory!=Integration --verbosity minimal
32 |
33 | - name: Create Package
34 | run: dotnet pack --no-build -c Release -o ./publish
35 |
36 | - name: Create packages artifact
37 | if: ${{ matrix.os == 'windows-latest' }}
38 | uses: actions/upload-artifact@v4
39 | with:
40 | name: Packages
41 | path: ./src/publish/
42 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/Owin.Security.AesDataProtectorProvider.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net45
4 | true
5 | snupkg
6 | true
7 |
8 | 1.2.5
9 |
10 | OWIN AES data protector provider
11 | Owin.Security.AesDataProtectorProvider
12 | Alexander Krylkov
13 | Licensed under LGPL
14 | https://github.com/i4004/Owin.Security.AesDataProtectorProvider
15 | true
16 | OWIN
17 |
18 | See https://github.com/i4004/Owin.Security.AesDataProtectorProvider/tree/master/Owin.Security.AesDataProtectorProvider/CHANGELOG.md for details
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29324.140
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.AesDataProtectorProvider", "Owin.Security.AesDataProtectorProvider\Owin.Security.AesDataProtectorProvider.csproj", "{AB43300F-837C-4E1D-BDB8-35165A146CA2}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Owin.Security.AesDataProtectorProvider.Tests", "Owin.Security.AesDataProtectorProvider.Tests\Owin.Security.AesDataProtectorProvider.Tests.csproj", "{BFE2E96D-C973-4642-887D-E64CEBD32359}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {AB43300F-837C-4E1D-BDB8-35165A146CA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {AB43300F-837C-4E1D-BDB8-35165A146CA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {AB43300F-837C-4E1D-BDB8-35165A146CA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {AB43300F-837C-4E1D-BDB8-35165A146CA2}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {BFE2E96D-C973-4642-887D-E64CEBD32359}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {BFE2E96D-C973-4642-887D-E64CEBD32359}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {BFE2E96D-C973-4642-887D-E64CEBD32359}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {BFE2E96D-C973-4642-887D-E64CEBD32359}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {294F74D9-4B5C-4EA7-99A9-CC922684B853}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider.Tests/AesDataProtectorTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Security;
3 | using Microsoft.Owin.Security.DataProtection;
4 | using NUnit.Framework;
5 | using Owin.Security.AesDataProtectorProvider.CrypticProviders;
6 | using Simplify.Extensions;
7 |
8 | namespace Owin.Security.AesDataProtectorProvider.Tests
9 | {
10 | [TestFixture]
11 | public class AesDataProtectorTests
12 | {
13 | private const string Key = "abcdefg-keyabcx";
14 |
15 | private AesDataProtectorProvider _protectorProvider;
16 | private IDataProtector _protector;
17 |
18 | [SetUp]
19 | public void Initialize()
20 | {
21 | _protectorProvider = new AesDataProtectorProvider(new Sha512ManagedFactory(), new Sha256ManagedFactory(),
22 | new AesManagedFactory(), Key);
23 |
24 | _protector = _protectorProvider.Create();
25 | }
26 |
27 | [Test]
28 | public void ProtectUnprotect_TestString_SourceStringEqualProtectedThenUnprotected()
29 | {
30 | // Assign
31 |
32 | const string source = "Test data";
33 | var data = source.ToBytesArray();
34 |
35 | // Act
36 |
37 | var protectedData = _protector.Protect(data);
38 | var unprotectedData = _protector.Unprotect(protectedData);
39 |
40 | // Assert
41 | Assert.AreEqual(data, unprotectedData);
42 | }
43 |
44 | [Test]
45 | public void Unprotect_CookieWhichCausesLengthIntegrityCheckError_SecurityExceptionWithExactMessageThrown()
46 | {
47 | // Assign
48 |
49 | _protector = _protectorProvider.Create();
50 |
51 | var authCookie = "eLnczc+4i2AwIDknRD90lwEg/qVRgh9yi2oGd9QF8mO/UpgYJyQPQN885qx3tshalkwF5UGRqyHgO6e2t0UHxLBqdO/QWzSNFrbxMDV7mlRfCKF9tfv+Oi+iwNwWAQe/AAWzpZMU/jt6aKFEvDlu5lTx9NMQPANZsTIaRAHD8guje8ltGFJeSDQ8FgyMnzZjBMw8FyiiKYbX5ToFSVoPgsf/6bxlev2QiuYnSkqVsIwMwiCFdUC2fFuj2MouFmipi3dNQDxt+Ihjxff1aBNfI0H2AzDRFtpEyxDSdq/kcMXipkZWSHsfJQaPL9HbJivksQnvg2IUiZWOVn8FOABx0IbjJFzWCQWF1KrdYfCjsLPv/N4LZVJqvyolxHiBBkmM6OrM4WI1+yPndLhoVgUPsg==";
52 | var protectedData = Convert.FromBase64String(authCookie);
53 |
54 | // Act & Assert
55 |
56 | Assert.That(() => _protector.Unprotect(protectedData),
57 | Throws.TypeOf().With.Message.EqualTo("Data length integrity check failed"));
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Owin.Security.AesDataProtectorProvider
2 |
3 | [](https://www.nuget.org/packages/Owin.Security.AesDataProtectorProvider)
4 | [](https://www.nuget.org/packages/Owin.Security.AesDataProtectorProvider)
5 | [](https://github.com/i4004/Owin.Security.AesDataProtectorProvider/actions/workflows/build.yml)[](https://libraries.io/nuget/Owin.Security.AesDataProtectorProvider)
6 | [](https://www.codefactor.io/repository/github/i4004/Owin.Security.AesDataProtectorProvider)
7 | 
8 |
9 | `Owin.Security.AesDataProtectorProvider` - is an AES cryptic provider for OWIN authentication middlewares.
10 | It is based on managed and CSP .Net framework providers.
11 |
12 | ## Examples
13 |
14 | ### Registration
15 |
16 | ```csharp
17 | public class Startup
18 | {
19 | public void Configuration(IAppBuilder app)
20 | {
21 | ...
22 | app.UseAesDataProtectorProvider();
23 | ...
24 | }
25 | }
26 | ```
27 |
28 | #### Usage with custom key
29 |
30 | ```csharp
31 | ...
32 | app.UseAesDataProtectorProvider("my key");
33 | ...
34 | ```
35 |
36 | #### Enabling usage with FIPS-compliant CSP provider
37 |
38 | ```csharp
39 | ...
40 | app.UseAesDataProtectorProvider(null, true);
41 | ...
42 | ```
43 |
44 | or
45 |
46 | ```csharp
47 | ...
48 | app.UseAesDataProtectorProvider("my key", true);
49 | ...
50 | ```
51 |
52 | ### Usage example with cookie authentication
53 |
54 | ```csharp
55 | public class Startup
56 | {
57 | public void Configuration(IAppBuilder app)
58 | {
59 | app.UseCookieAuthentication(new CookieAuthenticationOptions
60 | {
61 | AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
62 | LoginPath = new PathString("/login")
63 | });
64 |
65 | app.UseAesDataProtectorProvider();
66 | }
67 | }
68 | ```
69 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/AesDataProtectorProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using Microsoft.Owin.Security.DataProtection;
4 | using Owin.Security.AesDataProtectorProvider.CrypticProviders;
5 |
6 | namespace Owin.Security.AesDataProtectorProvider
7 | {
8 | ///
9 | /// Provider AES DataProtectorProvider
10 | ///
11 | public class AesDataProtectorProvider : IDataProtectionProvider
12 | {
13 | private readonly ISha512Factory _sha512Factory;
14 | private readonly ISha256Factory _sha256Factory;
15 | private readonly IAesFactory _aesFactory;
16 |
17 | private string _key;
18 |
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The SHA512 factory.
23 | /// The SHA256 factory.
24 | /// The AES factory.
25 | /// The key.
26 | public AesDataProtectorProvider(ISha512Factory sha512Factory, ISha256Factory sha256Factory, IAesFactory aesFactory, string key = null)
27 | {
28 | _sha512Factory = sha512Factory;
29 | _sha256Factory = sha256Factory;
30 | _aesFactory = aesFactory;
31 | _key = key;
32 | }
33 |
34 | private string SeedHash
35 | {
36 | get
37 | {
38 | if (string.IsNullOrWhiteSpace(_key))
39 | _key = HashString(Environment.MachineName);
40 |
41 | return _key;
42 | }
43 | }
44 |
45 | private string HashString(string value)
46 | {
47 | return HexStringFromBytes(_sha512Factory.Create().ComputeHash(Encoding.ASCII.GetBytes(value))).ToUpper();
48 | }
49 |
50 | ///
51 | /// Returns a new instance of IDataProtection for the provider.
52 | ///
53 | /// Additional entropy used to ensure protected data may only be unprotected for the correct purposes.
54 | ///
55 | /// An instance of a data protection service
56 | ///
57 | public IDataProtector Create(params string[] purposes)
58 | {
59 | return new AesDataProtector(_sha256Factory, _aesFactory, SeedHash);
60 | }
61 |
62 | ///
63 | /// Convert an array of bytes to a string of hex digits
64 | ///
65 | /// array of bytes
66 | /// String of hex digits
67 | public static string HexStringFromBytes(byte[] bytes)
68 | {
69 | var sb = new StringBuilder();
70 |
71 | foreach (var b in bytes)
72 | sb.Append(b.ToString("x2"));
73 |
74 | return sb.ToString();
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/AppBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Owin.Security.DataProtection;
3 | using Owin.Security.AesDataProtectorProvider.CrypticProviders;
4 |
5 | namespace Owin.Security.AesDataProtectorProvider
6 | {
7 | ///
8 | /// AesDataProtectorProvider IAppBuilder extensions
9 | ///
10 | public static class AppBuilderExtensions
11 | {
12 | private static ISha512Factory _sha512Factory;
13 | private static ISha256Factory _sha256Factory;
14 | private static IAesFactory _aesFactory;
15 |
16 | ///
17 | /// Gets or sets the SHA512 factory instance.
18 | ///
19 | ///
20 | /// The SHA512 factory instance.
21 | ///
22 | /// value
23 | public static ISha512Factory Sha512Factory
24 | {
25 | get => _sha512Factory ?? (_sha512Factory = new Sha512ManagedFactory());
26 |
27 | set
28 | {
29 | if (value == null)
30 | throw new ArgumentNullException(nameof(value));
31 |
32 | _sha512Factory = value;
33 | }
34 | }
35 |
36 | ///
37 | /// Gets or sets the SHA256 factory instance.
38 | ///
39 | ///
40 | /// The SHA256 factory instance.
41 | ///
42 | /// value
43 | public static ISha256Factory Sha256Factory
44 | {
45 | get => _sha256Factory ?? (_sha256Factory = new Sha256ManagedFactory());
46 |
47 | set
48 | {
49 | if (value == null)
50 | throw new ArgumentNullException(nameof(value));
51 |
52 | _sha256Factory = value;
53 | }
54 | }
55 |
56 | ///
57 | /// Gets or sets the AES factory instance.
58 | ///
59 | ///
60 | /// The AES factory instance.
61 | ///
62 | /// value
63 | public static IAesFactory AesFactory
64 | {
65 | get => _aesFactory ?? (_aesFactory = new AesManagedFactory());
66 |
67 | set
68 | {
69 | if (value == null)
70 | throw new ArgumentNullException(nameof(value));
71 |
72 | _aesFactory = value;
73 | }
74 | }
75 |
76 | ///
77 | /// Uses the AES data protector provider as data provider.
78 | ///
79 | /// The builder.
80 | /// The key for encryption/decryption, to use Environment.MachineName as a key should be null.
81 | /// If set to true then CSP FIPS-compliant providers will be used instead of managed providers.
82 | public static void UseAesDataProtectorProvider(this IAppBuilder builder, string key = null, bool cspProvilder = false)
83 | {
84 | if (cspProvilder)
85 | {
86 | Sha256Factory = new Sha256CspFactory();
87 | Sha512Factory = new Sha512CspFactory();
88 | AesFactory = new AesCspFactory();
89 | }
90 |
91 | builder.SetDataProtectionProvider(new AesDataProtectorProvider(Sha512Factory, Sha256Factory, AesFactory, key));
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | [Rr]eleases/
14 | x64/
15 | x86/
16 | build/
17 | bld/
18 | [Bb]in/
19 | [Oo]bj/
20 |
21 | # Roslyn cache directories
22 | *.ide/
23 |
24 | # MSTest test Results
25 | [Tt]est[Rr]esult*/
26 | [Bb]uild[Ll]og.*
27 |
28 | #NUNIT
29 | *.VisualState.xml
30 | TestResult.xml
31 |
32 | # Build Results of an ATL Project
33 | [Dd]ebugPS/
34 | [Rr]eleasePS/
35 | dlldata.c
36 |
37 | *_i.c
38 | *_p.c
39 | *_i.h
40 | *.ilk
41 | *.meta
42 | *.obj
43 | *.pch
44 | *.pdb
45 | *.pgc
46 | *.pgd
47 | *.rsp
48 | *.sbr
49 | *.tlb
50 | *.tli
51 | *.tlh
52 | *.tmp
53 | *.tmp_proj
54 | *.log
55 | *.vspscc
56 | *.vssscc
57 | .builds
58 | *.pidb
59 | *.svclog
60 | *.scc
61 |
62 | # Chutzpah Test files
63 | _Chutzpah*
64 |
65 | # Visual C++ cache files
66 | ipch/
67 | *.aps
68 | *.ncb
69 | *.opensdf
70 | *.sdf
71 | *.cachefile
72 |
73 | # Visual Studio profiler
74 | *.psess
75 | *.vsp
76 | *.vspx
77 |
78 | # TFS 2012 Local Workspace
79 | $tf/
80 |
81 | # Guidance Automation Toolkit
82 | *.gpState
83 |
84 | # ReSharper is a .NET coding add-in
85 | _ReSharper*/
86 | *.[Rr]e[Ss]harper
87 | *.DotSettings.user
88 |
89 | # JustCode is a .NET coding addin-in
90 | .JustCode
91 |
92 | # TeamCity is a build add-in
93 | _TeamCity*
94 |
95 | # DotCover is a Code Coverage Tool
96 | *.dotCover
97 |
98 | # NCrunch
99 | _NCrunch_*
100 | .*crunch*.local.xml
101 |
102 | # MightyMoose
103 | *.mm.*
104 | AutoTest.Net/
105 |
106 | # Web workbench (sass)
107 | .sass-cache/
108 |
109 | # Installshield output folder
110 | [Ee]xpress/
111 |
112 | # DocProject is a documentation generator add-in
113 | DocProject/buildhelp/
114 | DocProject/Help/*.HxT
115 | DocProject/Help/*.HxC
116 | DocProject/Help/*.hhc
117 | DocProject/Help/*.hhk
118 | DocProject/Help/*.hhp
119 | DocProject/Help/Html2
120 | DocProject/Help/html
121 |
122 | # Click-Once directory
123 | publish/
124 |
125 | # Publish Web Output
126 | *.[Pp]ublish.xml
127 | *.azurePubxml
128 | # TODO: Comment the next line if you want to checkin your web deploy settings
129 | # but database connection strings (with potential passwords) will be unencrypted
130 | *.pubxml
131 | *.publishproj
132 |
133 | # NuGet Packages
134 | *.nupkg
135 | # The packages folder can be ignored because of Package Restore
136 | **/packages/*
137 | # except build/, which is used as an MSBuild target.
138 | !**/packages/build/
139 | # If using the old MSBuild-Integrated Package Restore, uncomment this:
140 | #!**/packages/repositories.config
141 |
142 | # Windows Azure Build Output
143 | csx/
144 | *.build.csdef
145 |
146 | # Windows Store app package directory
147 | AppPackages/
148 |
149 | # Others
150 | sql/
151 | *.Cache
152 | ClientBin/
153 | [Ss]tyle[Cc]op.*
154 | ~$*
155 | *~
156 | *.dbmdl
157 | *.dbproj.schemaview
158 | *.pfx
159 | *.publishsettings
160 | node_modules/
161 |
162 | # RIA/Silverlight projects
163 | Generated_Code/
164 |
165 | # Backup & report files from converting an old project file
166 | # to a newer Visual Studio version. Backup files are not needed,
167 | # because we have git ;-)
168 | _UpgradeReport_Files/
169 | Backup*/
170 | UpgradeLog*.XML
171 | UpgradeLog*.htm
172 |
173 | # SQL Server files
174 | *.mdf
175 | *.ldf
176 |
177 | # Business Intelligence projects
178 | *.rdl.data
179 | *.bim.layout
180 | *.bim_*.settings
181 |
182 | # Microsoft Fakes
183 | FakesAssemblies/
184 |
185 | # Visual Studio Temp files
186 | .vs
187 |
--------------------------------------------------------------------------------
/src/Owin.Security.AesDataProtectorProvider/AesDataProtector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Security;
5 | using System.Security.Cryptography;
6 | using System.Text;
7 | using Microsoft.Owin.Security.DataProtection;
8 | using Owin.Security.AesDataProtectorProvider.CrypticProviders;
9 |
10 | namespace Owin.Security.AesDataProtectorProvider
11 | {
12 | internal class AesDataProtector : IDataProtector
13 | {
14 | private readonly ISha256Factory _sha256Factory;
15 | private readonly IAesFactory _aesFactory;
16 |
17 | private readonly byte[] _key;
18 |
19 | public AesDataProtector(ISha256Factory sha256Factory, IAesFactory aesFactory, string key)
20 | {
21 | _sha256Factory = sha256Factory;
22 | _aesFactory = aesFactory;
23 |
24 | using (var sha = _sha256Factory.Create())
25 | _key = sha.ComputeHash(Encoding.UTF8.GetBytes(key));
26 | }
27 |
28 | public byte[] Protect(byte[] data)
29 | {
30 | byte[] dataHash;
31 | byte[] dataLenHash;
32 |
33 | using (var sha = _sha256Factory.Create())
34 | {
35 | dataHash = sha.ComputeHash(data);
36 | dataLenHash = sha.ComputeHash(Encoding.UTF8.GetBytes(data.Length.ToString()));
37 | }
38 |
39 | using (var aesAlg = _aesFactory.Create())
40 | {
41 | aesAlg.Key = _key;
42 | aesAlg.GenerateIV();
43 |
44 | using (var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV))
45 | using (var msEncrypt = new MemoryStream())
46 | {
47 | msEncrypt.Write(aesAlg.IV, 0, 16);
48 |
49 | using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
50 | using (var bwEncrypt = new BinaryWriter(csEncrypt))
51 | {
52 | bwEncrypt.Write(dataHash);
53 | bwEncrypt.Write(dataLenHash);
54 | bwEncrypt.Write(data.Length);
55 | bwEncrypt.Write(data);
56 | }
57 |
58 | return msEncrypt.ToArray();
59 | }
60 | }
61 | }
62 |
63 | public byte[] Unprotect(byte[] protectedData)
64 | {
65 | using (var aesAlg = _aesFactory.Create())
66 | {
67 | aesAlg.Key = _key;
68 |
69 | using (var msDecrypt = new MemoryStream(protectedData))
70 | {
71 | var iv = new byte[16];
72 | msDecrypt.Read(iv, 0, 16);
73 | aesAlg.IV = iv;
74 |
75 | if (aesAlg.Key == null)
76 | throw new AesDataProtectorProviderException("Key is null");
77 |
78 | using (var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
79 | {
80 | var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
81 | var brDecrypt = new BinaryReader(csDecrypt);
82 |
83 | try
84 | {
85 | var signature = brDecrypt.ReadBytes(32);
86 | var lenSignature = brDecrypt.ReadBytes(32);
87 |
88 | var len = brDecrypt.ReadInt32();
89 |
90 | byte[] data;
91 | byte[] dataHash;
92 |
93 | using (var sha = _sha256Factory.Create())
94 | {
95 | var lenHash = sha.ComputeHash(Encoding.UTF8.GetBytes(len.ToString()));
96 |
97 | if (len < 0 || !lenSignature.SequenceEqual(lenHash))
98 | throw new SecurityException("Data length integrity check failed");
99 |
100 | data = brDecrypt.ReadBytes(len);
101 | dataHash = sha.ComputeHash(data);
102 | }
103 |
104 | if (!dataHash.SequenceEqual(signature))
105 | throw new SecurityException("Signature does not match the computed hash");
106 |
107 | return data;
108 | }
109 | finally
110 | {
111 | try
112 | {
113 | brDecrypt.Dispose();
114 | csDecrypt.Dispose();
115 | }
116 | catch (CryptographicException)
117 | {
118 | }
119 | }
120 | }
121 | }
122 | }
123 | }
124 | }
125 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
167 |
--------------------------------------------------------------------------------