From ce54a3c974000aff2ade9f50471f3d0ab62484f1 Mon Sep 17 00:00:00 2001
From: Klaus Fischer <klaus.fischer@eloware.com>
Date: Thu, 7 Jul 2022 07:06:55 +0200
Subject: [PATCH] Importing JWE

---
 Encryption/AspNetCoreEncryptor.cs | 36 -------------------------------
 Encryption/Encryption.csproj      |  2 +-
 Encryption/FitEncryption.cs       | 20 ++++++-----------
 Encryption/IEncryption.cs         | 23 --------------------
 Encryption/IEncryptor.cs          | 10 ++++-----
 Encryption/JoseEncryptor.cs       | 34 +++++++++++++++++++++++++++++
 Encryption/JsonWebKeyExtension.cs | 28 ------------------------
 7 files changed, 46 insertions(+), 107 deletions(-)
 delete mode 100644 Encryption/AspNetCoreEncryptor.cs
 delete mode 100644 Encryption/IEncryption.cs
 create mode 100644 Encryption/JoseEncryptor.cs
 delete mode 100644 Encryption/JsonWebKeyExtension.cs

diff --git a/Encryption/AspNetCoreEncryptor.cs b/Encryption/AspNetCoreEncryptor.cs
deleted file mode 100644
index e37e0d71..00000000
--- a/Encryption/AspNetCoreEncryptor.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Security.Cryptography;
-using System.Text;
-using IdentityModel.Jwk;
-
-namespace FitConnect.Encryption;
-
-public class AspNetCoreEncryptor : IEncryptor {
-    private readonly RSAEncryptionPadding _rsaEncryptionPadding = RSAEncryptionPadding.OaepSHA256;
-
-    public string Encrypt(string plain, string key, out object? passOver) {
-        var rsa = new JsonWebKey(key).ToRsaKey();
-        passOver = rsa;
-
-        var cipher = rsa.Encrypt(Encoding.UTF8.GetBytes(plain), _rsaEncryptionPadding);
-        return Convert.ToBase64String(cipher);
-    }
-
-    public string Decrypt(string cipher, string key, object? passOver = null) {
-        var rsa = new JsonWebKey(key).ToRsaKey();
-
-        var plain = rsa.Decrypt(Convert.FromBase64String(cipher), _rsaEncryptionPadding);
-        return Encoding.UTF8.GetString(plain);
-    }
-
-    public byte[] Encrypt(byte[] plain, string key, out object? passOver) {
-        var rsa = new JsonWebKey(key).ToRsaKey();
-        passOver = rsa;
-
-        return rsa.Encrypt(plain, _rsaEncryptionPadding);
-    }
-
-    public byte[] Decrypt(byte[] cipher, string key, object? passOver = null) {
-        var rsa = new JsonWebKey(key).ToRsaKey();
-        return rsa.Decrypt(cipher, _rsaEncryptionPadding);
-    }
-}
diff --git a/Encryption/Encryption.csproj b/Encryption/Encryption.csproj
index 8bc0d0ac..5aaba4e4 100644
--- a/Encryption/Encryption.csproj
+++ b/Encryption/Encryption.csproj
@@ -9,12 +9,12 @@
 
     <ItemGroup>
       <PackageReference Include="IdentityModel" Version="6.0.0" />
+      <PackageReference Include="jose-jwt" Version="4.0.0" />
       <PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
       <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.20.0" />
     </ItemGroup>
 
     <ItemGroup>
-      <Compile Remove="JoseEncryptor.cs" />
       <Compile Remove="DefaultEncryptor.cs" />
       <Compile Remove="RsaEncryption.cs" />
     </ItemGroup>
diff --git a/Encryption/FitEncryption.cs b/Encryption/FitEncryption.cs
index 26f4d816..130cf855 100644
--- a/Encryption/FitEncryption.cs
+++ b/Encryption/FitEncryption.cs
@@ -13,7 +13,7 @@ public class FitEncryption {
     public string? PublicKeyEncryption { get; set; }
     public string? PublicKeySignatureVerification { get; set; }
 
-    private readonly IEncryptor _encryptor = new AspNetCoreEncryptor();
+    private readonly IEncryptor _encryptor = new JoseEncryptor();
 
     public FitEncryption(ILogger? logger) {
         _logger = logger;
@@ -36,21 +36,13 @@ public class FitEncryption {
         PublicKeyEncryption = keySet.PublicKeyEncryption;
         PublicKeySignatureVerification = keySet.PublicKeySignatureVerification;
     }
-
-    public byte[] Decrypt(byte[] cypher) {
-        if (PrivateKeyDecryption == null) {
-            throw new InvalidOperationException("PrivateKey is not provided");
-        }
-
-        return _encryptor.Decrypt(cypher, PrivateKeyDecryption);
-    }
-
+    
     public string Decrypt(string cypherText) {
         if (PrivateKeyDecryption == null) {
             throw new InvalidOperationException("PrivateKey is not provided");
         }
 
-        return _encryptor.Decrypt(cypherText, PrivateKeyDecryption);
+        return _encryptor.Decrypt(PrivateKeyDecryption, cypherText);
     }
 
     public string Encrypt(string plain) {
@@ -58,14 +50,14 @@ public class FitEncryption {
             throw new InvalidOperationException("PrivateKey is not provided");
         }
 
-        return _encryptor.Encrypt(plain, PrivateKeyDecryption, out var _);
+        return _encryptor.Encrypt(plain, PrivateKeyDecryption);
     }
 
-    public byte[] Encrypt(byte[] plain) {
+    public string Encrypt(byte[] plain) {
         if (PrivateKeyDecryption == null) {
             throw new InvalidOperationException("PrivateKey is not provided");
         }
 
-        return _encryptor.Encrypt(plain, PrivateKeyDecryption, out var _);
+        return _encryptor.Encrypt( PrivateKeyDecryption, plain);
     }
 }
diff --git a/Encryption/IEncryption.cs b/Encryption/IEncryption.cs
deleted file mode 100644
index 585a698e..00000000
--- a/Encryption/IEncryption.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Security.Cryptography.X509Certificates;
-
-namespace FitConnect.Encryption;
-
-public interface IEncryption {
-    void ImportCertificate(X509Certificate2 cert);
-
-    /// <summary>
-    ///     Import a public key from a PEM file
-    /// </summary>
-    /// <param name="certificatePath"></param>
-    /// <param name="password">Password for the certificate</param>
-    /// <exception cref="ArgumentException"></exception>
-    /// <exception cref="Exception"></exception>
-    void ImportCertificate(string certificatePath, string password);
-
-    string DecryptData(string data);
-
-    byte[] ExportPublicKey();
-    byte[] ExportPrivateKey();
-    byte[] EncryptData(byte[] data);
-    byte[] EncryptData(byte[] data, byte[] publicKey);
-}
diff --git a/Encryption/IEncryptor.cs b/Encryption/IEncryptor.cs
index 0e7311cb..636d2ae0 100644
--- a/Encryption/IEncryptor.cs
+++ b/Encryption/IEncryptor.cs
@@ -1,12 +1,12 @@
 using System.Security.Cryptography;
 using IdentityModel;
 using IdentityModel.Jwk;
+using Base64Url = Jose.Base64Url;
 
 namespace FitConnect.Encryption;
 
 public interface IEncryptor {
-    public string Encrypt(string plain, string key, out object? passOver);
-    public string Decrypt(string cipher, string key, object? passOver = null);
-    public byte[] Encrypt(byte[] plain, string key, out object? passOver);
-    public byte[] Decrypt(byte[] cipher, string key, object? passOver = null);
-}
+    public string Encrypt(string key, string plain);
+    public string Decrypt(string key, string cipher);
+    public string Encrypt(string key, byte[] plain);
+}
\ No newline at end of file
diff --git a/Encryption/JoseEncryptor.cs b/Encryption/JoseEncryptor.cs
new file mode 100644
index 00000000..af233555
--- /dev/null
+++ b/Encryption/JoseEncryptor.cs
@@ -0,0 +1,34 @@
+using Jose;
+
+namespace FitConnect.Encryption;
+
+public class JoseEncryptor : IEncryptor {
+    private string Encrypt(Jwk key, string plain) {
+        return JWE.Encrypt(plain,
+            new JweRecipient[] { new JweRecipient(JweAlgorithm.RSA_OAEP, key) },
+            JweEncryption.A256GCM, compression: JweCompression.DEF);
+    }
+
+    private (string cypher, byte[] tag) Decrypt(Jwk key, string payload) {
+        var result = JWE.Decrypt(payload, key);
+
+        return (result.Plaintext, result.AuthTag);
+    }
+
+    public string Encrypt(string key, string plain) {
+        var jwk = Jwk.FromJson(key, new Jose.JsonMapper());
+        return Encrypt(jwk, plain);
+    }
+
+    public string Decrypt(string key, string cipher) {
+        var jwk = Jwk.FromJson(key, new Jose.JsonMapper());
+        return Decrypt(jwk, cipher).cypher;
+    }
+
+    public string Encrypt(string key, byte[] plain) {
+        var jwk = Jwk.FromJson(key, new Jose.JsonMapper());
+        return JWE.EncryptBytes(plain,
+            new JweRecipient[] { new JweRecipient(JweAlgorithm.RSA_OAEP, key) },
+            JweEncryption.A256GCM, compression: JweCompression.DEF);
+    }
+}
diff --git a/Encryption/JsonWebKeyExtension.cs b/Encryption/JsonWebKeyExtension.cs
deleted file mode 100644
index a7512b4e..00000000
--- a/Encryption/JsonWebKeyExtension.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Buffers.Text;
-using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
-using IdentityModel;
-using Microsoft.IdentityModel.Tokens;
-using JsonWebKey = IdentityModel.Jwk.JsonWebKey;
-
-
-namespace FitConnect.Encryption;
-
-public static class JsonWebKeyExtension {
-    public static RSA ToRsaKey(this JsonWebKey jsonWebKey) {
-            var rsa = RSA.Create();
-        rsa.ImportParameters(new RSAParameters {
-            Modulus = Base64Url.Decode(jsonWebKey.N),
-            Exponent = Base64Url.Decode(jsonWebKey.E),
-            D = Base64Url.Decode(jsonWebKey.D),
-            P = Base64Url.Decode(jsonWebKey.P),
-            Q = Base64Url.Decode(jsonWebKey.Q),
-            DP = Base64Url.Decode(jsonWebKey.DP),
-            DQ = Base64Url.Decode(jsonWebKey.DQ),
-            InverseQ = Base64Url.Decode(jsonWebKey.QI),
-        });
-        
-        //  = "RSA-OAEP-256";
-        return rsa;
-    }
-}
-- 
GitLab