From 08d4cdc38728b13e26f748d862a2209aaeeaacd0 Mon Sep 17 00:00:00 2001 From: Geky <127978634+GekySan@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:36:27 +0200 Subject: [PATCH 1/3] Implemented RSA signing for JWT support --- RuriLib/Functions/Crypto/Crypto.cs | 56 +++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/RuriLib/Functions/Crypto/Crypto.cs b/RuriLib/Functions/Crypto/Crypto.cs index ad69dd483..64ecf7cd0 100644 --- a/RuriLib/Functions/Crypto/Crypto.cs +++ b/RuriLib/Functions/Crypto/Crypto.cs @@ -626,18 +626,58 @@ private static byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTr #region JWT public static string JwtEncode(JwtAlgorithmName algorithmName, string secret, IDictionary extraHeaders, IDictionary payload) { - IJwtAlgorithm algorithm = algorithmName switch + IJwtAlgorithm algorithm = null; + RSA rsa = null; + + switch (algorithmName) { - JwtAlgorithmName.HS256 => new HMACSHA256Algorithm(), - JwtAlgorithmName.HS384 => new HMACSHA384Algorithm(), - JwtAlgorithmName.HS512 => new HMACSHA512Algorithm(), - _ => throw new NotSupportedException("This algorithm is not supported at the moment") - }; - + case JwtAlgorithmName.HS256: + algorithm = new HMACSHA256Algorithm(); + break; + case JwtAlgorithmName.HS384: + algorithm = new HMACSHA384Algorithm(); + break; + case JwtAlgorithmName.HS512: + algorithm = new HMACSHA512Algorithm(); + break; + case JwtAlgorithmName.RS256: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS256Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS384: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS384Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS512: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS512Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS1024: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS1024Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS2048: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS2048Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS4096: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS4096Algorithm(rsa, rsa); + break; + default: + throw new NotSupportedException("This algorithm is not supported at the moment"); + } + var jsonSerializer = new JsonNetSerializer(); var urlEncoder = new JwtBase64UrlEncoder(); var jwtEncoder = new JwtEncoder(algorithm, jsonSerializer, urlEncoder); - + return jwtEncoder.Encode(extraHeaders, payload, secret); } #endregion From 796c5c883fa29256aeb1ae63c7181e4a351988f9 Mon Sep 17 00:00:00 2001 From: Geky <127978634+GekySan@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:09:56 +0200 Subject: [PATCH 2/3] Update Crypto.cs --- RuriLib/Functions/Crypto/Crypto.cs | 104 +++++++++++++++-------------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/RuriLib/Functions/Crypto/Crypto.cs b/RuriLib/Functions/Crypto/Crypto.cs index 64ecf7cd0..c7d437054 100644 --- a/RuriLib/Functions/Crypto/Crypto.cs +++ b/RuriLib/Functions/Crypto/Crypto.cs @@ -628,57 +628,63 @@ public static string JwtEncode(JwtAlgorithmName algorithmName, string secret, ID { IJwtAlgorithm algorithm = null; RSA rsa = null; - - switch (algorithmName) + try { - case JwtAlgorithmName.HS256: - algorithm = new HMACSHA256Algorithm(); - break; - case JwtAlgorithmName.HS384: - algorithm = new HMACSHA384Algorithm(); - break; - case JwtAlgorithmName.HS512: - algorithm = new HMACSHA512Algorithm(); - break; - case JwtAlgorithmName.RS256: - rsa = RSA.Create(); - rsa.ImportFromPem(secret.ToCharArray()); - algorithm = new RS256Algorithm(rsa, rsa); - break; - case JwtAlgorithmName.RS384: - rsa = RSA.Create(); - rsa.ImportFromPem(secret.ToCharArray()); - algorithm = new RS384Algorithm(rsa, rsa); - break; - case JwtAlgorithmName.RS512: - rsa = RSA.Create(); - rsa.ImportFromPem(secret.ToCharArray()); - algorithm = new RS512Algorithm(rsa, rsa); - break; - case JwtAlgorithmName.RS1024: - rsa = RSA.Create(); - rsa.ImportFromPem(secret.ToCharArray()); - algorithm = new RS1024Algorithm(rsa, rsa); - break; - case JwtAlgorithmName.RS2048: - rsa = RSA.Create(); - rsa.ImportFromPem(secret.ToCharArray()); - algorithm = new RS2048Algorithm(rsa, rsa); - break; - case JwtAlgorithmName.RS4096: - rsa = RSA.Create(); - rsa.ImportFromPem(secret.ToCharArray()); - algorithm = new RS4096Algorithm(rsa, rsa); - break; - default: - throw new NotSupportedException("This algorithm is not supported at the moment"); + switch (algorithmName) + { + case JwtAlgorithmName.HS256: + algorithm = new HMACSHA256Algorithm(); + break; + case JwtAlgorithmName.HS384: + algorithm = new HMACSHA384Algorithm(); + break; + case JwtAlgorithmName.HS512: + algorithm = new HMACSHA512Algorithm(); + break; + case JwtAlgorithmName.RS256: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS256Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS384: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS384Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS512: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS512Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS1024: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS1024Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS2048: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS2048Algorithm(rsa, rsa); + break; + case JwtAlgorithmName.RS4096: + rsa = RSA.Create(); + rsa.ImportFromPem(secret.ToCharArray()); + algorithm = new RS4096Algorithm(rsa, rsa); + break; + default: + throw new NotSupportedException("This algorithm is not supported at the moment"); + } + + var jsonSerializer = new JsonNetSerializer(); + var urlEncoder = new JwtBase64UrlEncoder(); + var jwtEncoder = new JwtEncoder(algorithm, jsonSerializer, urlEncoder); + + return jwtEncoder.Encode(extraHeaders, payload, secret); + } + finally + { + rsa?.Dispose(); } - - var jsonSerializer = new JsonNetSerializer(); - var urlEncoder = new JwtBase64UrlEncoder(); - var jwtEncoder = new JwtEncoder(algorithm, jsonSerializer, urlEncoder); - - return jwtEncoder.Encode(extraHeaders, payload, secret); } #endregion From f5d74c6b5405c79d7f8f20ba1bee1fb449248efa Mon Sep 17 00:00:00 2001 From: Geky <127978634+GekySan@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:10:32 +0200 Subject: [PATCH 3/3] Update Methods.cs --- RuriLib/Blocks/Functions/Crypto/Methods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RuriLib/Blocks/Functions/Crypto/Methods.cs b/RuriLib/Blocks/Functions/Crypto/Methods.cs index 643914099..b51e529a0 100644 --- a/RuriLib/Blocks/Functions/Crypto/Methods.cs +++ b/RuriLib/Blocks/Functions/Crypto/Methods.cs @@ -217,7 +217,7 @@ public static string AESDecryptString(BotData data, byte[] cipherText, byte[] ke } [Block("Generates a JSON Web Token using a secret key, payload, optional extra headers and specified algorithm type", - name = "JWT Encode", extraInfo = "The header already contains the selected algorithm and token type (JWT) by default")] + name = "JWT Encode", extraInfo = "The header already contains the selected algorithm and token type (JWT) by default. For JWTs using asymmetric key signatures, the secret must be provided in PEM format.")] public static string JwtEncode(BotData data, JwtAlgorithmName algorithm, string secret, string extraHeaders = "{}", string payload = "{}") { var extraHeadersDictionary = JsonConvert.DeserializeObject>(extraHeaders);