-
Notifications
You must be signed in to change notification settings - Fork 605
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
15 changed files
with
324 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.Security.Cryptography; | ||
|
||
namespace SampleAesGcmNetCore31 | ||
{ | ||
/// <summary> | ||
/// SymmetricAlgorithm decrypting implementation for http://www.w3.org/2009/xmlenc11#aes128-gcm. | ||
/// This is class is not a general implementation and can only do decryption. | ||
/// </summary> | ||
public class AesGcmAlgorithm : SymmetricAlgorithm | ||
{ | ||
public const string AesGcm128Identifier = "http://www.w3.org/2009/xmlenc11#aes128-gcm"; | ||
|
||
// "For the purposes of this specification, AES-GCM shall be used with a 96 bit Initialization Vector (IV) and a 128 bit Authentication Tag (T)." | ||
// Source: https://www.w3.org/TR/xmlenc-core1/#sec-AES-GCM | ||
public const int NonceSizeInBits = 96; | ||
|
||
private const int AuthenticationTagSizeInBits = 128; | ||
|
||
public AesGcmAlgorithm() | ||
{ | ||
//not sure about 128 keysize? | ||
LegalKeySizesValue = new[] { new KeySizes(128, 128, 0) }; | ||
|
||
//iv setter checks that iv is the size of a block. Not sure if there should be other block sizes | ||
LegalBlockSizesValue = new[] { new KeySizes(NonceSizeInBits, NonceSizeInBits, 0) }; | ||
BlockSizeValue = NonceSizeInBits; | ||
//dummy iv value since it is accessed first in EncryptedXml.DecryptData | ||
IV = new byte[NonceSizeInBits / 8]; | ||
} | ||
|
||
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) | ||
{ | ||
return new AesGcmDecryptor(rgbKey, rgbIV, AuthenticationTagSizeInBits); | ||
} | ||
|
||
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public override void GenerateIV() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public override void GenerateKey() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using System; | ||
using System.Security.Cryptography; | ||
|
||
namespace SampleAesGcmNetCore31 | ||
{ | ||
internal class AesGcmDecryptor : ICryptoTransform | ||
{ | ||
private readonly byte[] key; | ||
private readonly byte[] nonce; | ||
private readonly int authenticationTagSizeInBits; | ||
|
||
public AesGcmDecryptor(byte[] key, byte[] nonce, int authenticationTagSizeInBits) | ||
{ | ||
this.key = key; | ||
this.nonce = nonce; | ||
this.authenticationTagSizeInBits = authenticationTagSizeInBits; | ||
} | ||
|
||
public bool CanReuseTransform => throw new NotImplementedException(); | ||
|
||
public bool CanTransformMultipleBlocks => throw new NotImplementedException(); | ||
|
||
public int InputBlockSize => throw new NotImplementedException(); | ||
|
||
public int OutputBlockSize => throw new NotImplementedException(); | ||
|
||
public void Dispose() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) | ||
{ | ||
//inspired by https://stackoverflow.com/a/60891115 | ||
|
||
var tagSize = authenticationTagSizeInBits / 8; | ||
var cipherSize = inputCount - tagSize; | ||
|
||
// "The cipher text contains the IV first, followed by the encrypted octets and finally the Authentication tag." | ||
// https://www.w3.org/TR/xmlenc-core1/#sec-AES-GCM | ||
var encryptedData = inputBuffer.AsSpan().Slice(inputOffset, inputCount); | ||
var tag = encryptedData.Slice(encryptedData.Length - tagSize); | ||
|
||
var cipherBytes = encryptedData.Slice(0, cipherSize); | ||
|
||
var plainBytes = cipherSize < 1024 | ||
? stackalloc byte[cipherSize] | ||
: new byte[cipherSize]; | ||
|
||
using var aes = new AesGcm(key); | ||
aes.Decrypt(nonce, cipherBytes, tag, plainBytes); | ||
|
||
return plainBytes.ToArray(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
|
||
namespace SampleAesGcmNetCore31 | ||
{ | ||
public class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
CreateHostBuilder(args).Build().Run(); | ||
} | ||
|
||
public static IHostBuilder CreateHostBuilder(string[] args) => | ||
Host.CreateDefaultBuilder(args) | ||
.ConfigureWebHostDefaults(webBuilder => | ||
{ | ||
webBuilder.UseStartup<Startup>(); | ||
}); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
Samples/SampleAesGcmStartupNetCore31/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:50565", | ||
"sslPort": 0 | ||
} | ||
}, | ||
"profiles": { | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"SampleAesGcmStartupNetCore31": { | ||
"commandName": "Project", | ||
"launchBrowser": true, | ||
"applicationUrl": "http://localhost:5000", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Adding AES-GCM support for SustainSys.Saml2 | ||
|
||
To add AES-GCM support for decrypting SAML messages, a SymmetricAlgorithm implementation must be provided and registered with `System.Security.Cryptography.CryptoConfig.AddAlgorithm()` | ||
|
||
This sample project demonstrates how such implementation could be done in .Net Core 3.1. | ||
|
||
See `AesGcmAlgorithm.cs` for the SymmetricAlgorithm implementation. It is a wrapper for the actual AES-GCM implementation. The used AES-GCM implementation is available in .Net Core 3.1 and .Net Standard 2.1. For .Net Core 2.x and .Net Framework, the some other implementation must be used (for examle, BouncyCastle). |
7 changes: 7 additions & 0 deletions
7
Samples/SampleAesGcmStartupNetCore31/SampleAesGcmNetCore31.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Builder; | ||
using Microsoft.AspNetCore.Hosting; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
using System.Security.Cryptography; | ||
|
||
namespace SampleAesGcmNetCore31 | ||
{ | ||
public class Startup | ||
{ | ||
// This method gets called by the runtime. Use this method to add services to the container. | ||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 | ||
public void ConfigureServices(IServiceCollection services) | ||
{ | ||
CryptoConfig.AddAlgorithm(typeof(AesGcmAlgorithm), AesGcmAlgorithm.AesGcm128Identifier); | ||
} | ||
|
||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | ||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) | ||
{ | ||
if (env.IsDevelopment()) | ||
{ | ||
app.UseDeveloperExceptionPage(); | ||
} | ||
|
||
app.UseRouting(); | ||
|
||
app.UseEndpoints(endpoints => | ||
{ | ||
endpoints.MapGet("/", async context => | ||
{ | ||
var aesGcm = CryptoConfig.CreateFromName(AesGcmAlgorithm.AesGcm128Identifier); | ||
await context.Response.WriteAsync( | ||
$"Resolved '{AesGcmAlgorithm.AesGcm128Identifier}' to {aesGcm.GetType().FullName}"); | ||
}); | ||
}); | ||
} | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
Samples/SampleAesGcmStartupNetCore31/appsettings.Development.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft": "Warning", | ||
"Microsoft.Hosting.Lifetime": "Information" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft": "Warning", | ||
"Microsoft.Hosting.Lifetime": "Information" | ||
} | ||
}, | ||
"AllowedHosts": "*" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using System; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using System.Security.Cryptography.Xml; | ||
using System.Xml; | ||
using FluentAssertions; | ||
using Sustainsys.Saml2.Internal; | ||
using System.Linq; | ||
|
||
namespace Sustainsys.Saml2.Tests.Internal | ||
{ | ||
|
||
[TestClass] | ||
public class RSAEncryptedXmlTests | ||
{ | ||
[TestMethod] | ||
public void AesGcmNonceIsSupported() | ||
{ | ||
var aesGcm128NonceSizeInBytes = RSAEncryptedXml.AesGcm128NonceSizeInBits / 8; | ||
var dummyBytes = Enumerable.Range(42, aesGcm128NonceSizeInBytes + 1).Select(i => (byte)i).ToArray(); | ||
var expectedIv = Enumerable.Range(42, aesGcm128NonceSizeInBytes); | ||
var dummyData = new EncryptedData(); | ||
dummyData.CipherData = new CipherData(dummyBytes); | ||
var rex = new RSAEncryptedXml(new XmlDocument(), null ); | ||
var iv = rex.GetDecryptionIV(dummyData, RSAEncryptedXml.AesGcm128Identifier); | ||
iv.Should().NotBeNull(); | ||
iv.Should().BeEquivalentTo(expectedIv); | ||
} | ||
|
||
[TestMethod] | ||
public void NonAesGcmAlgorithmsAreHandledByBaseClass() | ||
{ | ||
var dummyBytes = Enumerable.Range(17, 20).Select(i => (byte)i).ToArray(); | ||
var dummyData = new EncryptedData(); | ||
dummyData.CipherData = new CipherData(dummyBytes); | ||
var rex = new RSAEncryptedXml(new XmlDocument(), null ); | ||
var iv = rex.GetDecryptionIV(dummyData, EncryptedXml.XmlEncAES256Url); | ||
iv.Should().NotBeNull(); | ||
iv.Should().BeEquivalentTo(Enumerable.Range(17, 16)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters