I'm developing a project that will require me to include credentials for things like an SMTP server. I'd like to store this information along with the complete details of the endpoint in an embedded JSON file, but I would like to have that information encrypted and then let my application decrypt it when it needs to establish a connection and log in. The JSON structure looks something like this:
{
    "Endpoints" : [
        {
            "Endpoint" : {
                "Host": "smtp.mydomain.tld",
                "Port": 587,
                "Username": "[email protected]",
                "Password": "mYp@s$w0?d"
            }
        }
    ]
}
While what I'd really like to have actually stored in the file would look something like this:
{
    "Endpoints" : [
        {
            "Endpoint" : "<BASE64_ENCODED_STRING>"
        }
    ]
}
Using Newtonsoft's Json.NET, I've built the class object/properties to desriealize this structure:
<JsonProperty("Endpoints")>
Public Property Endpoints As List(Of EndpointContainer) = Nothing
Public Class EndpointContainer
    <EditorBrowsable(EditorBrowsableState.Never)> <DebuggerBrowsable(DebuggerBrowsableState.Never)>
    Private Const EncryptedPrefix As String = "myappcipher:"
    <EditorBrowsable(EditorBrowsableState.Never)> <DebuggerBrowsable(DebuggerBrowsableState.Never)>
    <JsonProperty("Endpoint")> <JsonConverter(GetType(EndpointProtector))>
    Public Property Endpoint As Endpoint = Nothing
End Class
And I've built the inherited JsonConverter class ("EndpointProtector") like this:
Public Class EndpointProtector
    Inherits JsonConverter
    Public Sub New()
        Using SHAEncryption = New SHA256Managed()
            _EncryptionKey = SHAEncryption.ComputeHash(Encoding.UTF8.GetBytes(TestEncryptionKey))
        End Using
    End Sub
    Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
        Dim clearText As String = JsonConvert.SerializeObject(value)
        If clearText Is Nothing Then
            Throw New ArgumentNullException(NameOf(clearText))
        End If
        writer.WriteValue(EncryptEndpoint(clearText))
    End Sub
    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
        Dim DecryptString As String = TryCast(reader.Value, String)
        If String.IsNullOrEmpty(DecryptString) Then
            Return reader.Value
        ElseIf Not DecryptString.StartsWith(EncryptedPrefix, StringComparison.OrdinalIgnoreCase) Then
            Return DecryptString
        Else
            Return DecryptEndpoint(DecryptString)
        End If
    End Function
    Public Overrides Function CanConvert(objectType As Type) As Boolean
        Throw New NotImplementedException()
    End Function
End Class
Currently I have the JSON file itself with the full object definition (as in the first code block). When my application reads that JSON, it correctly moves to the overridden ReadJson() method I have, but the reader.Value is null (Nothing), so it never actually gets to the DecryptEndpoint() method. Of course, that means there's nothing to encrypt, so the application won't even step into the WriteJson() method.
I've tried a couple of variations, including making the Endpoint property into a private variable with a generic Object type, and then having a separate public property with the <JsonIgnore> decoration to "read" from that, but nothing seems to get me where I need to be. I'm sure I'm overlooking something here, but I can't seem to figure out why it's not getting anything at all.
I looked at a few other SO questions like Encrypt and JSON Serialize an object, but I've still not yet been able to figure out quite where I've gone wrong here.
NOTE: I intentionally didn't include the code for the EncryptEndpoint() or DecryptEndpoint() methods here simply because the code is never making it that far in the process. If you feel it's needed to fully answer the question, please let me know.
                        
this is a linqpad example of working encrypt/decrypt base on JsonAttribute
to activate encryption just add a tag