From e68b3aed2c919ed749cb46ce8d61148dd4c283a3 Mon Sep 17 00:00:00 2001 From: ruri Date: Wed, 1 Apr 2020 01:38:21 +0200 Subject: [PATCH] Readded RSA Pkcs1Pad2 function --- .../StackerBlocks/PageBlockFunction.xaml | 12 ++++ .../StackerBlocks/PageBlockFunction.xaml.cs | 15 +++-- RuriLib/Blocks/BlockFunction.cs | 34 ++++++++-- RuriLib/Functions/Crypto/Crypto.cs | 64 +++++++++++++++++++ 4 files changed, 114 insertions(+), 11 deletions(-) diff --git a/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml b/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml index a7401bf..6b922a3 100644 --- a/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml +++ b/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml @@ -160,6 +160,18 @@ + + + + + + + + diff --git a/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml.cs b/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml.cs index 4fff818..421d4bd 100644 --- a/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml.cs +++ b/OpenBullet/Views/StackerBlocks/PageBlockFunction.xaml.cs @@ -116,25 +116,29 @@ namespace OpenBullet.Views.StackerBlocks break; */ - case BlockFunction.Function.CharAt: + case BlockFunction.Function.RSAPKCS1PAD2: functionTabControl.SelectedIndex = 11; break; - case BlockFunction.Function.Substring: + case BlockFunction.Function.CharAt: functionTabControl.SelectedIndex = 12; break; - case BlockFunction.Function.GetRandomUA: + case BlockFunction.Function.Substring: functionTabControl.SelectedIndex = 13; break; + case BlockFunction.Function.GetRandomUA: + functionTabControl.SelectedIndex = 14; + break; + case BlockFunction.Function.AESEncrypt: case BlockFunction.Function.AESDecrypt: - functionTabControl.SelectedIndex = 14; + functionTabControl.SelectedIndex = 15; break; case BlockFunction.Function.PBKDF2PKCS5: - functionTabControl.SelectedIndex = 15; + functionTabControl.SelectedIndex = 16; break; } } @@ -149,6 +153,7 @@ namespace OpenBullet.Views.StackerBlocks { "Compute", "Calculates the value of a math expression, for example (6+3)*5 will return 45." }, { "RSAEncrypt", "Encrypts data with RSA. All parameters must be provided as base64 strings" }, { "RSADecrypt", "Decrypts data with RSA. All parameters must be provided as base64 strings" }, + { "RSAPKCS1PAD" , "Encrypts data with RSA Pkcs1Pad2. Modulus and exponent must be provided as HEX strings."}, { "Delay", "Write the amount of MILLISECONDS you want to wait in the input field" }, { "CharAt", "Returns the character at the specified index of the string in the input field" }, { "AESEncrypt", "Encrypts data with AES. All parameters must be provided as base64 strings. Uses SHA-256 to get a 256 bit key" }, diff --git a/RuriLib/Blocks/BlockFunction.cs b/RuriLib/Blocks/BlockFunction.cs index cc55a73..fbfdf1c 100644 --- a/RuriLib/Blocks/BlockFunction.cs +++ b/RuriLib/Blocks/BlockFunction.cs @@ -117,6 +117,9 @@ namespace RuriLib // Decrypts a string with RSA. // RSADecrypt, + /// Encrypts a string with RSA PKCS1PAD2. + RSAPKCS1PAD2, + /// Waits a given amount of milliseconds. Delay, @@ -423,14 +426,19 @@ namespace RuriLib LineParser.SetBool(ref input, this); break; - /* - case Function.RSADecrypt: + /* + case Function.RSADecrypt: + RsaN = LineParser.ParseLiteral(ref input, "Public Key Modulus"); + RsaD = LineParser.ParseLiteral(ref input, "Private Key Exponent"); + if (LineParser.Lookahead(ref input) == TokenType.Boolean) + LineParser.SetBool(ref input, this); + break; + */ + + case Function.RSAPKCS1PAD2: RsaN = LineParser.ParseLiteral(ref input, "Public Key Modulus"); - RsaD = LineParser.ParseLiteral(ref input, "Private Key Exponent"); - if (LineParser.Lookahead(ref input) == TokenType.Boolean) - LineParser.SetBool(ref input, this); + RsaE = LineParser.ParseLiteral(ref input, "Public Key Exponent"); break; - */ case Function.GetRandomUA: if (LineParser.ParseToken(ref input, TokenType.Parameter, false, false) == "BROWSER") @@ -579,6 +587,12 @@ namespace RuriLib break; */ + case Function.RSAPKCS1PAD2: + writer + .Literal(RsaN) + .Literal(RsaE); + break; + case Function.GetRandomUA: if (UserAgentSpecifyBrowser) { @@ -792,6 +806,14 @@ namespace RuriLib break; */ + case Function.RSAPKCS1PAD2: + outputString = Crypto.RSAPkcs1Pad2( + localInputString, + ReplaceValues(RsaN, data), + ReplaceValues(RsaE, data) + ); + break; + case Function.Delay: try { Thread.Sleep(int.Parse(localInputString)); } catch { } break; diff --git a/RuriLib/Functions/Crypto/Crypto.cs b/RuriLib/Functions/Crypto/Crypto.cs index 08119ce..2373677 100644 --- a/RuriLib/Functions/Crypto/Crypto.cs +++ b/RuriLib/Functions/Crypto/Crypto.cs @@ -4,6 +4,8 @@ using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; +using System.Globalization; +using System.Numerics; namespace RuriLib.Functions.Crypto { @@ -307,6 +309,68 @@ namespace RuriLib.Functions.Crypto oaep ); } + + /// + /// Encrypts a message using RSA with PKCS1PAD2 padding. + /// + /// The message as a UTF-8 string + /// The public key's modulus as a HEX string + /// The public key's exponent as a HEX string + /// The encrypted message. + // Thanks to TheLittleTrain for this implementation. + public static string RSAPkcs1Pad2(string message, string modulus, string exponent) + { + // Convert the public key components to numbers + var n = HexToBigInteger(modulus); + var e = HexToBigInteger(exponent); + + // (modulus.ToByteArray().Length - 1) * 8 + //modulus has 256 bytes multiplied by 8 bits equals 2048 + var encryptedNumber = Pkcs1Pad2(message, (2048 + 7) >> 3); + + // And now, the RSA encryption + encryptedNumber = BigInteger.ModPow(encryptedNumber, e, n); + + //Reverse number and convert to base64 + var encryptedString = Convert.ToBase64String(encryptedNumber.ToByteArray().Reverse().ToArray()); + + return encryptedString; + } + + private static BigInteger HexToBigInteger(string hex) + { + return BigInteger.Parse("00" + hex, NumberStyles.AllowHexSpecifier); + } + + private static BigInteger Pkcs1Pad2(string data, int keySize) + { + if (keySize < data.Length + 11) + return new BigInteger(); + + var buffer = new byte[256]; + var i = data.Length - 1; + + while (i >= 0 && keySize > 0) + { + buffer[--keySize] = (byte)data[i--]; + } + + // Padding, I think + var random = new Random(); + buffer[--keySize] = 0; + while (keySize > 2) + { + buffer[--keySize] = (byte)random.Next(1, 256); + //buffer[--keySize] = 5; + } + + buffer[--keySize] = 2; + buffer[--keySize] = 0; + + Array.Reverse(buffer); + + return new BigInteger(buffer); + } #endregion #region KDF