feat: "Spanify" DataProtector with GetSize/TryProtect pattern - #62903
Closed
DeagleGross wants to merge 57 commits into
Closed
feat: "Spanify" DataProtector with GetSize/TryProtect pattern#62903DeagleGross wants to merge 57 commits into
DeagleGross wants to merge 57 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR adds new non-allocating "Span-based" APIs to the DataProtection interfaces, specifically implementing the Protect/Encrypt functionality without requiring heap allocations. The new APIs allow callers to get the size of protected data upfront and then encrypt directly into a provided buffer.
Key changes:
- Added
GetProtectedSize()andTryProtect()methods toIDataProtectorinterface - Added
GetEncryptedSize()andTryEncrypt()methods toIAuthenticatedEncryptorinterface - Implemented these methods across all encryptor types (AES-GCM, CBC, CNG variants, Managed implementations)
Reviewed Changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/DataProtection/Abstractions/src/IDataProtector.cs | Added new span-based APIs to the main data protector interface |
| src/DataProtection/DataProtection/src/AuthenticatedEncryption/IAuthenticatedEncryptor.cs | Added new span-based APIs to the authenticated encryptor interface |
| src/DataProtection/DataProtection/src/KeyManagement/KeyRingBasedDataProtector.cs | Core implementation of new APIs with proper header management |
| src/DataProtection/DataProtection/src/Managed/ManagedAuthenticatedEncryptor.cs | Implementation for managed (non-CNG) encryption algorithms |
| src/DataProtection/DataProtection/src/Managed/AesGcmAuthenticatedEncryptor.cs | Implementation for AES-GCM encryption |
| src/DataProtection/DataProtection/src/Cng/CbcAuthenticatedEncryptor.cs | Implementation for CNG-based CBC encryption |
| src/DataProtection/DataProtection/src/Cng/CngGcmAuthenticatedEncryptor.cs | Implementation for CNG-based GCM encryption |
| src/DataProtection/Extensions/src/TimeLimitedDataProtector.cs | Updated time-limited protector to support new APIs |
| Multiple test files | Comprehensive test coverage for the new functionality |
halter73
reviewed
Jul 24, 2025
halter73
left a comment
Member
There was a problem hiding this comment.
I think we should update our existing code that calls into IDataProtecter to use the new methods to get good test coverage of the new methods.
3 tasks
Member
Author
4 tasks
Member
Author
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
Member
Author
|
Decided to go with other design: #64262 |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Please, review with caution! This is cryptography and failures here can be pretty dramatic...
This PR introduces 2 new interfaces which allow usage of DataProtection via
Span<byte>:ISpanDataProtectorandIAuthenticatedEncryptor.Details
Current PR proposes extra interfaces
ISpanDataProtectorandISpanAuthenticatedEncryptor(Inspiration taken from ISpanFormattable : IFormattable). The APIs are:and
From the implementation standpoint, these APIs are basically doing what existing
Protect() / Unprotect()andEncrypt() / Decrypt()do, but without allocating a result array and instead filling in theSpan<byte> destination.For
IAuthenticatedEncryptors I tried to reuse theTryEncrypt/TryDecryptfromEncrypt/Decryptwhere possible to reduce code duplication.Registrations
IDataProtectoralso should implementIDataProtectionProviderwhich provides the protector instance:And in default DI (
AddDataProtection)IDataProtectoris created in such a manner:https://github.com/dotnet/aspnetcore/blob/b52c80fef2b8bf5239c7643d9c79d1029bb6c988/src/DataProtection/DataProtection/src/DataProtectionServiceCollectionExtensions.cs#L89C13-L95C14
I dont want to introduce more APIs and interfaces for providing
ISpanDataProtectorand instead when providing I am doing a lookup to determine whether it is possible to returnISpanDataProtectororIDataProtector. Users will then be able to differentiate based on their needs and registrations.Usage
Having
IDataProtector:and the same goes for
IAuthenticatedEncryptor, but I doubt majority of users implement their ownIAuthenticatedEncryptor.Testing
In order to verify correctness of the changes I've created
RoundtripEncryptionHelpers.AssertTryEncryptTryDecryptParitywhere I try to call Encrypt/Decrypt in different order forIDataProtectorandIAuthenticatedEncryptorto ensure any order of operations give a correct roundtrip result.I will also change any other place in aspnetcore to use this API to make sure new APIs behave correctly and in the same way as existing APIs
Fixes #44758