Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosIntel Devs: Smart AI Edge Solutions - 0 Introduction | Intel Software(22.09.2026 um 23:48 Uhr)
Windows Tipps & SecurityGoogles gibt Chrome 154 frei und schließt über 100 Lücken(23.09.2026 um 09:11 Uhr)
Windows Tipps & SecurityKlangerlebnis & Sicherheit im Vonovia Ruhrstadion(23.09.2026 um 08:45 Uhr)
Unix & Linux ServerLocal AI Jargon Quiz: Do You Know All These Buzzwords?(23.09.2026 um 08:38 Uhr)
Sichere ProgrammierungNeu von AWS: Weniger Kontextpflege für selbst gebaute KI-Agenten(23.09.2026 um 09:52 Uhr)
Sichere ProgrammierungLINQ GroupBy: The Operator Everyone Uses Wrong(23.09.2026 um 09:41 Uhr)
Sichere ProgrammierungIT Heard About the Acquisition Nine Days Before It Closed(23.09.2026 um 09:45 Uhr)
YouTube Security VideosIntel Devs: Smart AI Edge Solutions - 0 Introduction | Intel Software(22.09.2026 um 23:48 Uhr)
Windows Tipps & SecurityGoogles gibt Chrome 154 frei und schließt über 100 Lücken(23.09.2026 um 09:11 Uhr)
Windows Tipps & SecurityKlangerlebnis & Sicherheit im Vonovia Ruhrstadion(23.09.2026 um 08:45 Uhr)
Unix & Linux ServerLocal AI Jargon Quiz: Do You Know All These Buzzwords?(23.09.2026 um 08:38 Uhr)
Sichere ProgrammierungNeu von AWS: Weniger Kontextpflege für selbst gebaute KI-Agenten(23.09.2026 um 09:52 Uhr)
Sichere ProgrammierungLINQ GroupBy: The Operator Everyone Uses Wrong(23.09.2026 um 09:41 Uhr)
Sichere ProgrammierungIT Heard About the Acquisition Nine Days Before It Closed(23.09.2026 um 09:45 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

C# System.Text.Json JsonConverter masking

Introduction Learn how to use custom JsonConverters to export data which mask social security numbers and credit card numbers. These converters are useful when for instance in the case an extract is requested for a customer, but the…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




Introduction



Learn how to use custom JsonConverters to export data which mask social security numbers and credit card numbers. These converters are useful when for instance in the case an extract is requested for a customer, but the asker does not have permissions to see either SSN or credit card numbers.



In both cases the entire value is not masked. This way if a verification is needed other than an export an employee may use the unmasked values for verification like in customer verification process.



For SQL-Server, consider using dynamic data masking is also an option which requires using database table permissions.




Note

An important aspect of the sample code is separation of converters from the frontend as the converters can be used in any project type. For novice developers when writing any code that may be used in other projects consider separating the code to reside in a class project and one step farther is to create a local NuGet package for the class project.




Converter source code
front-end source code






Credit card code



For credit cards, the following display the last four numbers. Validation should be done prior to using this extension, for instance in a custom input or prior to a post operation.




namespace JsonConvertersSampleLibrary.Extensions;
public static partial class StringExtensions
{

/// <summary>
/// Masks a credit card number by replacing all but the last four digits with a specified mask character.
/// </summary>
/// <param name="sender">The credit card number to be masked.</param>
/// <param name="maskCharacter">The character to use for masking the credit card number. Default is 'X'.</param>
/// <returns>A masked version of the credit card number, with all but the last four digits replaced by the mask character.</returns>
/// <remarks>
/// The method uses a regular expression to identify and mask the credit card number.
/// </remarks>
public static string MaskCreditCardNumber(this string sender, char maskCharacter = 'X')
{

if (string.IsNullOrEmpty(sender))
{
return sender;
}

return CreditCardMaskRegEx().Replace(sender, match =>
{
var digits = string.Concat(match.Value.Where(char.IsDigit));

return digits.Length is 16 or 15
? new string(maskCharacter, digits.Length - 4) + digits[^4..]
: match.Value;
});
}

[GeneratedRegex("[0-9][0-9 ]{13,}[0-9]")]
private static partial Regex CreditCardMaskRegEx();
}






Then create the custom JsonConverter<string> which for the read method returns the credit card value while the write operation uses MaskSsn extension method to mask the credit card value.




using System.Text.Json;
using System.Text.Json.Serialization;
using JsonConvertersSampleLibrary.Extensions;

namespace JsonConvertersSampleLibrary.Converters;
/// <summary>
/// Provides a custom JSON converter for Social Security Numbers (SSNs) that masks the SSN value during serialization.
/// </summary>
public class SocialSecurityMaskConverter : JsonConverter<string>
{
/// <summary>
/// Reads and converts the JSON to a string value.
/// </summary>
/// <param name="reader">The <see cref="Utf8JsonReader"/> to read from.</param>
/// <param name="typeToConvert">The type of the object to convert.</param>
/// <param name="options">Options to control the behavior during reading.</param>
/// <returns>The string value read from the JSON.</returns>
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.GetString()!;

/// <summary>
/// Writes a masked Social Security Number (SSN) to the JSON.
/// </summary>
/// <param name="writer">The <see cref="Utf8JsonWriter"/> to write to.</param>
/// <param name="value">The SSN value to be masked and written.</param>
/// <param name="options">Options to control the behavior during writing.</param>
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.MaskSsn());
}
}






To use the converter the following class/model assigns the convert to the SSN property which will be used when serializing data.




using System.Text.Json.Serialization;
using JsonConvertersSampleLibrary.Converters;

namespace JsonConvertersSampleApp.Models;

/// <summary>
/// Represents a customer with personal details and sensitive information such as credit card number and PIN.
/// Inherits from the <see cref="Person"/> class.
/// </summary>
public class Customer : Person
{
/// <summary>
/// Gets or sets the credit card number of the customer.
/// The credit card number is masked when serialized to JSON using the <see cref="CreditCardMaskConverter"/>.
/// </summary>
[JsonConverter(typeof(CreditCardMaskConverter))]
public string CreditCardNumber { get; set; }
public string PIN { get; set; }
}






To serialize, in this case a list of Taxpayer, mocked data is generated using NuGet package Bogus.



Code for json options




private static JsonSerializerOptions Options =>
new()
{
WriteIndented = true
};






Serialize list to a json string.




var json = JsonSerializer.Serialize(BogusOperations.TaxpayerList(), Options);






Since the json converter is not tied to a single type but a string property it can be used with other classes as shown below.




/// <summary>
/// Represents a customer with personal details and sensitive information such as credit card number and PIN.
/// Inherits from the <see cref="Person"/> class.
/// </summary>
public class Customer : Person
{
/// <summary>
/// Gets or sets the credit card number of the customer.
/// The credit card number is masked when serialized to JSON using the <see cref="CreditCardMaskConverter"/>.
/// </summary>
[JsonConverter(typeof(CreditCardMaskConverter))]
public string CreditCardNumber { get; set; }
public string PIN { get; set; }
}






Sample serializing, this time without Bogus.




public static void ForCustomers()
{
var customer1 = new Customer
{
Id = 1,
FirstName = "John",
LastName = "Jones",
Title = "Mr.",
CreditCardNumber = "123456 7890 123456",
PIN = "5555",
BirthDate = new DateOnly(1980, 1, 1),
};

var customer2 = new Customer
{
Id = 2,
FirstName = "Mary",
LastName = "Gallagher",
Title = "Miss.",
CreditCardNumber = "123 456 789 012 3456",
PIN = "1234",
BirthDate = new DateOnly(1980, 1, 1),
};

List<Customer> customers = [customer1, customer2];
var json = JsonSerializer.Serialize(customers, Options);

File.WriteAllText("Customers.json", json);

}






Results




[
{
"CreditCardNumber": "XXXXXXXXXXXX3456",
"PIN": "5555",
"Id": 1,
"FirstName": "John",
"LastName": "Jones",
"Title": "Mr.",
"BirthDate": "1980-01-01",
"Gender": "Male"
},
{
"CreditCardNumber": "XXXXXXXXXXXX3456",
"PIN": "1234",
"Id": 2,
"FirstName": "Mary",
"LastName": "Gallagher",
"Title": "Miss.",
"BirthDate": "1980-01-01",
"Gender": "Male"
}
]









SSN (Social Security number) code



The same pattern is used as with a credit card mask, only difference is the language extension method used.



The following will be used in the custom SSN JsonConverter<string>




#pragma warning disable CA1847
using JsonConvertersSampleLibrary.Classes;
using System.Text.RegularExpressions;

namespace JsonConvertersSampleLibrary.Extensions;
public static partial class StringExtensions
{

/// <summary>
/// Masks a Social Security Number (SSN) by replacing a specified number of digits with a mask character.
/// </summary>
/// <param name="ssn">The Social Security Number to be masked.</param>
/// <param name="digitsToShow">The number of digits to show at the end of the SSN. Default is 4.</param>
/// <param name="maskCharacter">The character to use for masking the SSN. Default is 'X'.</param>
/// <returns>A masked version of the SSN.</returns>
/// <exception cref="ArgumentException">Thrown when the SSN is invalid, either due to incorrect length or non-numeric characters.</exception>
public static string MaskSsn(this string ssn, int digitsToShow = 4, char maskCharacter = 'X')
{
if (string.IsNullOrWhiteSpace(ssn)) return string.Empty;
if (ssn.Contains("-")) ssn = ssn.Replace("-", string.Empty);
if (ssn.Length != 9) throw new ArgumentException("SSN invalid length");
if (ssn.IsNotInteger()) throw new ArgumentException("SSN not valid");

const int ssnLength = 9;
const string separator = "-";

int maskLength = ssnLength - digitsToShow;
int output = int.Parse(ssn.Replace(separator, string.Empty).Substring(maskLength, digitsToShow));

var format = string.Empty;
for (var index = 0; index < maskLength; index++)
{
format += maskCharacter;
}

for (var index = 0; index < digitsToShow; index++)
{
format += "0";
}

format = format.Insert(3, separator).Insert(6, separator);
format = $"{{0:{format}}}";

return string.Format(format, output);

}

}






Sample class




using System.Text.Json.Serialization;
using JsonConvertersSampleApp.Interfaces;
using JsonConvertersSampleLibrary.Converters;
using JsonConvertersSampleLibrary.Extensions;

namespace JsonConvertersSampleApp.Models;

/// <summary>
/// Represents a taxpayer with properties for Social Security Number (SSN), Personal Identification Number (PIN),
/// start date, and Employer Identification Number (EIN). Inherits from <see cref="Person"/> and implements <see cref="ITaxpayer"/>.
/// </summary>
public class Taxpayer : Person, ITaxpayer
{
/// <summary>
/// Gets or sets the Social Security Number (SSN) of the taxpayer.
/// The SSN is masked during JSON serialization using the <see cref="SocialSecurityMaskConverter"/>.
/// </summary>
[JsonConverter(typeof(SocialSecurityMaskConverter))]
public string SSN { get; set; }

public string PIN { get; set; }
public DateOnly StartDate { get; set; }
public string EmployerIdentificationNumber { get; set; }
public override string ToString() => SSN.MaskSsn();
}






Results




[
{
"SSN": "XXX-XX-9617",
"PIN": "9685",
"StartDate": "2004-07-12",
"EmployerIdentificationNumber": "86-4138704",
"Id": 1,
"FirstName": "Clara",
"LastName": "Reilly",
"Title": "Chief Functionality Assistant",
"BirthDate": "1919-04-22",
"Gender": "Female"
},
{
"SSN": "XXX-XX-7173",
"PIN": "1396",
"StartDate": "2002-08-27",
"EmployerIdentificationNumber": "31-5100314",
"Id": 2,
"FirstName": "Tonya",
"LastName": "Prosacco",
"Title": "Lead Quality Planner",
"BirthDate": "1927-08-27",
"Gender": "Female"
},
{
"SSN": "XXX-XX-1763",
"PIN": "8868",
"StartDate": "2008-12-29",
"EmployerIdentificationNumber": "18-3837008",
"Id": 3,
"FirstName": "Jimmie",
"LastName": "D\u0027Amore",
"Title": "Corporate Program Strategist",
"BirthDate": "1933-08-02",
"Gender": "Male"
},
{
"SSN": "XXX-XX-0774",
"PIN": "0627",
"StartDate": "2002-02-02",
"EmployerIdentificationNumber": "45-0134382",
"Id": 4,
"FirstName": "Tracy",
"LastName": "O\u0027Kon",
"Title": "Internal Program Associate",
"BirthDate": "1971-01-13",
"Gender": "Male"
},
{
"SSN": "XXX-XX-2705",
"PIN": "6617",
"StartDate": "2008-01-05",
"EmployerIdentificationNumber": "60-2434511",
"Id": 5,
"FirstName": "Craig",
"LastName": "Hauck",
"Title": "Global Operations Assistant",
"BirthDate": "1982-07-26",
"Gender": "Male"
}
]









Summary



Two custom JsonConverters for use with string properties have been shown which when coupled with the following article provide an arsenal of converters to use or learn from to create other converters.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten C# System.Text.Json JsonConverter masking

Thematisch verwandte Begriffe: SystemTextJson, JsonConverter, masking · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-96258 | A vulnerability has been found in onSite internet GmbH Auktion NG Auktio…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick