JSON ToObject with SecureString

Viewed 4845

I'm having trouble serializing JSON text to an object that contains a SecureString variable. How might I serialize the following whilst keeping the public 'pwd' variable a SecureString?

Let's say have the following string:

string j_str = "{ 'uid':'JohnDoe', 'age':30, 'pwd':'MyPassword' }";

and I would like to serialize this string into an object I have in C#

public class User
{
   public string uid = { get; set; }
   public string age = { get; set; }
   public SecureString pwd = { get; set; }
}

So I may the following call using the JSON ToObject) call with Newtonsoft like so:

JObject j_obj = JObject.Parse(j_str);

User newUser = j_obj.ToObject<User>();

This results in the following error:

Newtonsoft.Json.JsonSerializationException: 'Error converting value "MyPassword" to type 'System.Security.SecureString'. Path 'pwd'
2 Answers

As said earlier, this does go against the principle of a SecureString. But here is a JSON converter for SecureString you can use.

using System.Runtime.InteropServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

public class SecureStringConverter : JsonConverter<SecureString>
{
    public override void WriteJson(JsonWriter writer, SecureString value, JsonSerializer serializer)
    {
        IntPtr ptr = Marshal.SecureStringToBSTR(value);
        writer.WriteValue(Marshal.PtrToStringBSTR(ptr));
        Marshal.ZeroFreeBSTR(ptr);
    }

    public override SecureString ReadJson(JsonReader reader, Type objectType, SecureString existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        string json_val = (string)reader.Value;
        SecureString s = new SecureString();

        if (json_val != null) 
        {
            foreach (char c in json_val) 
            {
                s.AppendChar(c);
            }
        }
        s.MakeReadOnly();
        return s;
    }
}

To Serialize user:

string serialized_user = JsonConvert.SerializeObject(user, new SecureStringConverter());

To Deseralize serialized_user:

User deserialized_user = JsonConvert.DeserializeObject<User>(serialized_user, new SecureStringConverter());
Related