question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

API proposal: Add ReadOnlySpan<byte> to IDataProtector (un)Protect

See original GitHub issue

Background and Motivation

Add ReadOnlySpan<byte> overrides so consumer apps are able to avoid a extra array allocation+blockbuffer.copy every time they try to protect\unprotect data.

Proposed API

namespace Microsoft.AspNetCore.DataProtection;

public interface IDataProtector : IDataProtectionProvider
{
+    byte[] Protect(ReadOnlySpan<byte> plaintext);

+    byte[] Unprotect(ReadOnlySpan<byte> protectedData);
}

Usage Examples

var buffer = new ArrayBufferWriter<byte>();

// write some data to buffer
var blob = new Data { Some = "Payload" };
MessagePackSerializer.Serialize(buffer, blob);

IDataProtector protector = provider.CreateProtector("demo");
return protector.Protect(buffer.WrittenSpan);

Alternative Designs

namespace Microsoft.AspNetCore.DataProtection;

public interface IDataProtector : IDataProtectionProvider
{
+    byte[] Protect(ReadOnlySpan<byte> plaintext) => this.Protect(plaintext.ToArray())

+    byte[] Unprotect(ReadOnlySpan<byte> protectedData) => this.Unprotect(protectedData.ToArray())
}

Risks

All of the existing protector implementations have to be changed to implement this change. We could also have a default interface implementation to prevent it breaking to aggressively.

Performance impact should be minimal, and actually open the possibility for apps to avoid a unnecessary array copy, if people use the api correctly

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:3
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
amcaseycommented, May 18, 2023

To get the perf win, we’d have to avoid allocating the array in the API implementation as well, so we’d probably need/want to update these too:

Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor.Decrypt(System.ArraySegment<byte> ciphertext, System.ArraySegment<byte> additionalAuthenticatedData) -> byte[]!
Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.IAuthenticatedEncryptor.Encrypt(System.ArraySegment<byte> plaintext, System.ArraySegment<byte> additionalAuthenticatedData) -> byte[]!
Microsoft.AspNetCore.DataProtection.ISecret.WriteSecretIntoBuffer(System.ArraySegment<byte> buffer) -> void
Microsoft.AspNetCore.DataProtection.Secret.Secret(System.ArraySegment<byte> value) -> void
Microsoft.AspNetCore.DataProtection.Secret.WriteSecretIntoBuffer(System.ArraySegment<byte> buffer) -> void

And probably these, if only for consistency:

static Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivation.Pbkdf2(string! password, byte[]! salt, Microsoft.AspNetCore.Cryptography.KeyDerivation.KeyDerivationPrf prf, int iterationCount, int numBytesRequested) -> byte[]!
Microsoft.AspNetCore.DataProtection.IPersistedDataProtector.DangerousUnprotect(byte[]! protectedData, bool ignoreRevocationErrors, out bool requiresMigration, out bool wasRevoked) -> byte[]!
Microsoft.AspNetCore.DataProtection.Secret.Secret(byte[]! value) -> void
Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector.Protect(byte[]! plaintext, System.DateTimeOffset expiration) -> byte[]!
Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector.Unprotect(byte[]! protectedData, out System.DateTimeOffset expiration) -> byte[]!
static Microsoft.AspNetCore.DataProtection.DataProtectionAdvancedExtensions.Protect(this Microsoft.AspNetCore.DataProtection.ITimeLimitedDataProtector! protector, byte[]! plaintext, System.TimeSpan lifetime) -> byte[]!
1reaction
adityamandaleekacommented, Nov 4, 2022

Triage: optimizing this is likely going to help in some hot paths. We believe the API needs some design work though.

Note: We’ll need to make sure netstandard2.0 works.

Read more comments on GitHub >

github_iconTop Results From Across the Web

IDataProtector.Unprotect(Byte[]) Method
Cryptographically unprotects a piece of protected data.
Read more >
Protecting Data with IDataProtector in ASP.NET Core
In this article, we are going to learn how to use IDataProtector to protect the sensitive data in the ASP.NET Core application.
Read more >
How to Disable Data Protection in ASP.NET Core
To create a IDataProtector without protection you just need to return the same argument received in the methods Protect and Unprotect.
Read more >
c# - IDataProtector unable to decrypt when application runs ...
json as I wrote some probing code that checks if the file is present and can be read before I even try to...
Read more >
How to use the Data Protection API in ASP.NET Core
Configure the Data Protection API in ASP.NET Core ... The AddDataProtection extension method can be used to configure the Data Protection API. The ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found