using ServiceShared.Crypto; using System.Text; using System.Text.Json; namespace ServiceShared.Models.Response { public class EncryptedResponse { public string descriptor { get; set; } public string encrypted_content { get; set; } public string hmac { get; set; } /// /// Default constructor of EncryptedResponse /// public EncryptedResponse() { } /// /// Constructor for EncryptedResponse /// /// Descriptor of the content object /// content object that should be encrypted /// shared deriveKey that should be used in the encrption public EncryptedResponse(string descriptor, object? contentObject, byte[] deriveKey) { this.Encrypt(descriptor, contentObject, deriveKey); } /// /// Constructor for EncryptedResponse /// /// Descriptor of the content object /// content object that should be encrypted /// shared deriveKey that should be used in the encrption /// returns true if encryption was successfully public bool Encrypt(string descriptor, object? contentObject, byte[] deriveKey) { bool result = false; try { if (deriveKey != null && deriveKey.Length > 0 && !string.IsNullOrEmpty(descriptor)) { this.descriptor = AES.Encrypt(descriptor, deriveKey); if (contentObject != null) { string json = JsonSerializer.Serialize(contentObject, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); if (!string.IsNullOrEmpty(json)) { this.encrypted_content = AES.Encrypt(json, deriveKey); if (!string.IsNullOrEmpty(this.encrypted_content)) { this.hmac = SHA512.HMAC(this.encrypted_content, deriveKey); if (!string.IsNullOrEmpty(hmac)) { result = true; } } } } else { this.hmac = SHA512.HMAC(this.descriptor, deriveKey); if (!string.IsNullOrEmpty(hmac)) { result = true; } } } } catch (System.Exception ex) { Log.Error(ex, "ServiceOutside.Models.Request.EncryptedResponse", "Encrypt"); } return result; } /// /// Decrypts the encrypted content /// /// Type of content object /// shared deriveKey for the decryption /// returns a object with defined type public T? Decrypt(byte[] deriveKey) { object? result = null; try { if (deriveKey != null && !string.IsNullOrEmpty(this.descriptor)) { this.descriptor = AES.Decrypt(this.descriptor, deriveKey); if (!string.IsNullOrEmpty(this.encrypted_content)) { string json = AES.Decrypt(this.encrypted_content, deriveKey); if (!string.IsNullOrEmpty(json)) { result = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } } } } catch (System.Exception ex) { Log.Error(ex, "ServiceOutside.Models.Request.EncryptedResponse", "Decrypt(byte[])"); } return (T?)result; } /// /// Decrypts the encrypted content /// /// shared deriveKey for the decryption /// returns a object public object? Decrypt(byte[] deriveKey) { object? result = null; try { if (deriveKey != null && deriveKey.Length > 0 && !string.IsNullOrEmpty(this.descriptor)) { this.descriptor = AES.Decrypt(this.descriptor, deriveKey); if (!string.IsNullOrEmpty(this.encrypted_content)) { string json = AES.Decrypt(this.encrypted_content, deriveKey); if (!string.IsNullOrEmpty(json)) { result = JsonSerializer.Deserialize(json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } } } } catch (System.Exception ex) { Log.Error(ex, "ServiceOutside.Models.Request.EncryptedResponse", "Decrypt(byte[])"); } return result; } /// /// Validates the encrypted request by HMAC and Ed25519 /// /// shared derive key, that should be used for the HMAC Authentification /// client signature, that should be verified /// client public signature key, that was used in client signature /// true if request is valid public bool ValidSignature(byte[] deriveKey, string clientSignatur, string clientSignaturKey) { if (!string.IsNullOrEmpty(this.encrypted_content)) { return // Validate over HMAC ((!string.IsNullOrEmpty(this.hmac) && deriveKey != null && deriveKey.Length > 0 && Crypto.SHA512.isValidAuthenticationCode(hmac, this.encrypted_content, deriveKey)) && //Validate over Ed25519 (!string.IsNullOrEmpty(clientSignatur) && Ed25519.CheckValid(Convert.FromBase64String(clientSignatur), Encoding.UTF8.GetBytes(this.encrypted_content), Convert.FromBase64String(clientSignaturKey)))); } else { return // Validate over HMAC ((!string.IsNullOrEmpty(this.hmac) && deriveKey != null && deriveKey.Length > 0 && Crypto.SHA512.isValidAuthenticationCode(hmac, this.descriptor, deriveKey)) && //Validate over Ed25519 (!string.IsNullOrEmpty(clientSignatur) && Ed25519.CheckValid(Convert.FromBase64String(clientSignatur), Encoding.UTF8.GetBytes(this.descriptor), Convert.FromBase64String(clientSignaturKey)))); } } } }