Reputation:
My code is below, it throws an exception because prv and pub are equal. It only serializes 2 members. I looked at RSAParameters and maybe it isn't showing me some attributes because I'm using .net core 2 but I see nothing to say not to serialize those members. Is there a way to force json.net to serialize those members? How do I save my private key? Write a function by hand?
using(var rsa = System.Security.Cryptography.RSA.Create())
{
var prv = rsa.ExportParameters(true);
var pub = rsa.ExportParameters(false);
var prvtext = Newtonsoft.Json.JsonConvert.SerializeObject(prv);
var pubtext = Newtonsoft.Json.JsonConvert.SerializeObject(pub);
if (prvtext == pubtext)
throw new Exception();
}
The class is
#region Assembly System.Security.Cryptography.Algorithms, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Users\acidzombie24\.nuget\packages\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Security.Cryptography.Algorithms.dll
#endregion
namespace System.Security.Cryptography
{
//
// Summary:
// Represents the standard parameters for the System.Security.Cryptography.RSA algorithm.
public struct RSAParameters
{
//
// Summary:
// Represents the D parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] D;
//
// Summary:
// Represents the DP parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] DP;
//
// Summary:
// Represents the DQ parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] DQ;
//
// Summary:
// Represents the Exponent parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] Exponent;
//
// Summary:
// Represents the InverseQ parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] InverseQ;
//
// Summary:
// Represents the Modulus parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] Modulus;
//
// Summary:
// Represents the P parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] P;
//
// Summary:
// Represents the Q parameter for the System.Security.Cryptography.RSA algorithm.
public byte[] Q;
}
}
Upvotes: 0
Views: 907
Reputation: 14477
You can use a custom DefaultContractResolver
to ignore the effect of [NonSerialized]
:
public class RSAContractResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
if (type == typeof(RSAParameters))
{
foreach(var property in properties)
{
property.Ignored = false;
}
}
return properties;
}
}
Usage:
var settings = new JsonSerializerSettings { ContractResolver = new RSAContractResolver() };
var prvtext = Newtonsoft.Json.JsonConvert.SerializeObject(prv, settings);
Upvotes: 1
Reputation: 2123
You could also use a CustomConverter
... Something like this:
public class RsaConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(RSAParameters);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var obj = JObject.Load(reader);
var param = new RSAParameters();
param.D = Convert.FromBase64String((string)obj["D"]);
// other properties...
return param;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var obj = (JObject)JToken.FromObject(value);
RSAParameters param = (RSAParameters)value;
if (obj["D"] == null && param.D != null) obj.Add("D", Convert.ToBase64String(param.D));
// other properties...
obj.WriteTo(writer);
}
}
Upvotes: 0
Reputation: 17578
Yes, fields on the RSAParameters
struct are marked with [NonSerialized]
.
Here's the github commit that fixes that, or an image of the commit in case the link dies.
Before that commit only the Exponent
and Modulus
properties were allowed to be serialized.
You'll need to wait for that commit to make it to a nuget package release. Based on the pull request this will be in version 2.1.0.
Upvotes: 2