为什么没有JSON序列化所有值,我该如何强制它?

时间:2017-09-28 18:02:07

标签: c# json serialization

我的代码在下面,因为prv和pub相等而引发异常。它只序列化了2个成员。我查看了RSAParameters,也许它没有向我展示一些属性,因为我使用的是.net core 2,但我没有说不要序列化这些成员。有没有办法强制json.net序列化这些成员?如何保存我的私钥?手写函数?

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();
}

班级

#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;
    }
}

3 个答案:

答案 0 :(得分:1)

是的,RSAParameters结构上的字段标有[NonSerialized]

Here's the github commit that fixes thatimage of the commit in case the link dies

在该提交之前,只允许序列化ExponentModulus属性。

您需要等待该提交才能进入nuget包发布。基于the pull request,这将在2.1.0版本中。

答案 1 :(得分:1)

您可以使用自定义DefaultContractResolver忽略[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;
  }
}

用法:

var settings = new JsonSerializerSettings { ContractResolver = new RSAContractResolver() };
var prvtext = Newtonsoft.Json.JsonConvert.SerializeObject(prv, settings);

答案 2 :(得分:0)

您还可以使用CustomConverter ......这样的事情:

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);
    }
}