TizzyT

RSAx -TizzyT

Sep 27th, 2018
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.97 KB | None | 0 0
  1.     public class RSAx : IDisposable
  2.     {
  3.         public enum RSAPadding
  4.         {
  5.             PKCS1 = 0,
  6.             SHA1 = 1,
  7.             SHA256 = 2,
  8.             SHA384 = 3,
  9.             SHA512 = 4
  10.         }
  11.  
  12.         private static readonly byte[] _Exponent = new byte[] { 1, 0, 1 };
  13.         private readonly RSACng Cryptor;
  14.         private readonly int _KeySize;
  15.         private readonly int _KeySizeDiv;
  16.         private readonly int _KeySizeDiv2;
  17.         private readonly RSAEncryptionPadding Padding;
  18.         private readonly RSAPadding padEnum;
  19.         private readonly int limit;
  20.  
  21.         public RSAx(int KeySize, in RSAPadding padding = RSAPadding.PKCS1)
  22.         {
  23.             if (KeySize < 512 || KeySize % 64 > 0 || KeySize > 16384)
  24.                 throw new Exception("KeySize must be a multiple of 64, greater than 512, upto 16,384.");
  25.             _KeySize = KeySize;
  26.             _KeySizeDiv = _KeySize / 8;
  27.             _KeySizeDiv2 = _KeySize / 16;
  28.             padEnum = padding;
  29.             switch (padding)
  30.             {
  31.                 case RSAPadding.PKCS1:
  32.                     limit = _KeySizeDiv - 11;
  33.                     Padding = RSAEncryptionPadding.Pkcs1;
  34.                     break;
  35.                 case RSAPadding.SHA1:
  36.                     limit = _KeySizeDiv - 42;
  37.                     Padding = RSAEncryptionPadding.OaepSHA1;
  38.                     break;
  39.                 case RSAPadding.SHA256:
  40.                     limit = _KeySizeDiv - 66;
  41.                     Padding = RSAEncryptionPadding.OaepSHA256;
  42.                     break;
  43.                 case RSAPadding.SHA384:
  44.                     limit = _KeySizeDiv - 98;
  45.                     Padding = RSAEncryptionPadding.OaepSHA384;
  46.                     break;
  47.                 case RSAPadding.SHA512:
  48.                     limit = _KeySizeDiv - 130;
  49.                     Padding = RSAEncryptionPadding.OaepSHA512;
  50.                     break;
  51.             }
  52.             for (int i = 0; i < 10; i++)
  53.                 if (_Exponent.SequenceEqual((Cryptor = new RSACng(KeySize)).ExportParameters(false).Exponent))
  54.                     return;
  55.             throw new Exception("Failed to create RSA" + KeySize + " Object");
  56.         }
  57.  
  58.         public RSAx(byte[] paramBytes)
  59.         {
  60.             _KeySize = BitConverter.ToInt32(paramBytes, 0);
  61.             padEnum = (RSAPadding)(_KeySize >> 24);
  62.             _KeySize = _KeySize & 0b_0000_0000_1111_1111_1111_1111_1111_1111;
  63.             _KeySizeDiv = _KeySize / 8;
  64.             _KeySizeDiv2 = _KeySize / 16;
  65.             switch (padEnum)
  66.             {
  67.                 case RSAPadding.PKCS1:
  68.                     limit = _KeySizeDiv - 11;
  69.                     Padding = RSAEncryptionPadding.Pkcs1;
  70.                     break;
  71.                 case RSAPadding.SHA1:
  72.                     limit = _KeySizeDiv - 42;
  73.                     Padding = RSAEncryptionPadding.OaepSHA1;
  74.                     break;
  75.                 case RSAPadding.SHA256:
  76.                     limit = _KeySizeDiv - 66;
  77.                     Padding = RSAEncryptionPadding.OaepSHA256;
  78.                     break;
  79.                 case RSAPadding.SHA384:
  80.                     limit = _KeySizeDiv - 98;
  81.                     Padding = RSAEncryptionPadding.OaepSHA384;
  82.                     break;
  83.                 case RSAPadding.SHA512:
  84.                     limit = _KeySizeDiv - 130;
  85.                     Padding = RSAEncryptionPadding.OaepSHA512;
  86.                     break;
  87.             }
  88.             RSAParameters rsaPar = new RSAParameters();
  89.             if (paramBytes.Length == ((9 * _KeySize) / 16) + 4)
  90.             {
  91.                 int idx = 4;
  92.                 rsaPar.D = SubArray(paramBytes, idx, _KeySizeDiv);
  93.                 rsaPar.P = SubArray(paramBytes, idx += _KeySizeDiv, _KeySizeDiv2);
  94.                 rsaPar.Q = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
  95.                 rsaPar.DP = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
  96.                 rsaPar.DQ = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
  97.                 rsaPar.InverseQ = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
  98.                 rsaPar.Modulus = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv);
  99.                 rsaPar.Exponent = (byte[])_Exponent.Clone();
  100.             }
  101.             else if (paramBytes.Length == _KeySizeDiv + 4)
  102.             {
  103.                 rsaPar.Modulus = SubArray(paramBytes, 4, _KeySizeDiv);
  104.                 rsaPar.Exponent = (byte[])_Exponent.Clone();
  105.             }
  106.             else
  107.             {
  108.                 throw new Exception("Invalid Parameter");
  109.             }
  110.             Cryptor = new RSACng();
  111.             Cryptor.ImportParameters(rsaPar);
  112.         }
  113.  
  114.         public byte[] Encrypt(byte[] Data)
  115.         {
  116.             if (Data.Length > limit)
  117.             {
  118.                 List<byte> result = new List<byte>();
  119.                 int minRounds = Data.Length / limit;
  120.                 for (int i = 0; i < minRounds; i++)
  121.                     result.AddRange(Cryptor.Encrypt(SubArray(Data, i * limit, limit), Padding));
  122.                 minRounds *= limit;
  123.                 if (minRounds < Data.Length)
  124.                     result.AddRange(Cryptor.Encrypt(SubArray(Data, minRounds, Data.Length - minRounds), Padding));
  125.                 return result.ToArray();
  126.             }
  127.             else
  128.             {
  129.                 return Cryptor.Encrypt(Data, Padding);
  130.             }
  131.         }
  132.  
  133.         public byte[] Decrypt(byte[] Data)
  134.         {
  135.             if (Data.Length > _KeySizeDiv)
  136.             {
  137.                 List<byte> result = new List<byte>();
  138.                 for (int i = 0; i < Data.Length; i += _KeySizeDiv) result.AddRange(Cryptor.Decrypt(SubArray(Data,i, _KeySizeDiv), Padding));
  139.                 return result.ToArray();
  140.             }
  141.             else
  142.             {
  143.                 return Cryptor.Decrypt(Data, Padding);
  144.             }
  145.         }
  146.  
  147.         public byte[] ToByteArray(in bool includePrivate)
  148.         {
  149.             List<byte> ab = new List<byte>();
  150.             RSAParameters parameters = Cryptor.ExportParameters(includePrivate);
  151.             ab.AddRange(BitConverter.GetBytes(((int)padEnum << 24) | _KeySize));
  152.             if (includePrivate)
  153.             {
  154.                 ab.AddRange(parameters.D);
  155.                 ab.AddRange(parameters.P);
  156.                 ab.AddRange(parameters.Q);
  157.                 ab.AddRange(parameters.DP);
  158.                 ab.AddRange(parameters.DQ);
  159.                 ab.AddRange(parameters.InverseQ);
  160.                 ab.AddRange(parameters.Modulus);
  161.             }
  162.             else
  163.             {
  164.                 ab.AddRange((byte[])parameters.Modulus.Clone());
  165.             }
  166.             return ab.ToArray();
  167.         }
  168.  
  169.         public void Dispose() => Cryptor.Dispose();
  170.  
  171.         private static byte[] SubArray(byte[] arr, in int offset, in int length)
  172.         {
  173.             byte[] result = new byte[length];
  174.             Array.Copy(arr, offset, result, 0, length);
  175.             return result;
  176.         }
  177.     }
Advertisement
Add Comment
Please, Sign In to add comment