Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class RSAx : IDisposable
- {
- public enum RSAPadding
- {
- PKCS1 = 0,
- SHA1 = 1,
- SHA256 = 2,
- SHA384 = 3,
- SHA512 = 4
- }
- private static readonly byte[] _Exponent = new byte[] { 1, 0, 1 };
- private readonly RSACng Cryptor;
- private readonly int _KeySize;
- private readonly int _KeySizeDiv;
- private readonly int _KeySizeDiv2;
- private readonly RSAEncryptionPadding Padding;
- private readonly RSAPadding padEnum;
- private readonly int limit;
- public RSAx(int KeySize, in RSAPadding padding = RSAPadding.PKCS1)
- {
- if (KeySize < 512 || KeySize % 64 > 0 || KeySize > 16384)
- throw new Exception("KeySize must be a multiple of 64, greater than 512, upto 16,384.");
- _KeySize = KeySize;
- _KeySizeDiv = _KeySize / 8;
- _KeySizeDiv2 = _KeySize / 16;
- padEnum = padding;
- switch (padding)
- {
- case RSAPadding.PKCS1:
- limit = _KeySizeDiv - 11;
- Padding = RSAEncryptionPadding.Pkcs1;
- break;
- case RSAPadding.SHA1:
- limit = _KeySizeDiv - 42;
- Padding = RSAEncryptionPadding.OaepSHA1;
- break;
- case RSAPadding.SHA256:
- limit = _KeySizeDiv - 66;
- Padding = RSAEncryptionPadding.OaepSHA256;
- break;
- case RSAPadding.SHA384:
- limit = _KeySizeDiv - 98;
- Padding = RSAEncryptionPadding.OaepSHA384;
- break;
- case RSAPadding.SHA512:
- limit = _KeySizeDiv - 130;
- Padding = RSAEncryptionPadding.OaepSHA512;
- break;
- }
- for (int i = 0; i < 10; i++)
- if (_Exponent.SequenceEqual((Cryptor = new RSACng(KeySize)).ExportParameters(false).Exponent))
- return;
- throw new Exception("Failed to create RSA" + KeySize + " Object");
- }
- public RSAx(byte[] paramBytes)
- {
- _KeySize = BitConverter.ToInt32(paramBytes, 0);
- padEnum = (RSAPadding)(_KeySize >> 24);
- _KeySize = _KeySize & 0b_0000_0000_1111_1111_1111_1111_1111_1111;
- _KeySizeDiv = _KeySize / 8;
- _KeySizeDiv2 = _KeySize / 16;
- switch (padEnum)
- {
- case RSAPadding.PKCS1:
- limit = _KeySizeDiv - 11;
- Padding = RSAEncryptionPadding.Pkcs1;
- break;
- case RSAPadding.SHA1:
- limit = _KeySizeDiv - 42;
- Padding = RSAEncryptionPadding.OaepSHA1;
- break;
- case RSAPadding.SHA256:
- limit = _KeySizeDiv - 66;
- Padding = RSAEncryptionPadding.OaepSHA256;
- break;
- case RSAPadding.SHA384:
- limit = _KeySizeDiv - 98;
- Padding = RSAEncryptionPadding.OaepSHA384;
- break;
- case RSAPadding.SHA512:
- limit = _KeySizeDiv - 130;
- Padding = RSAEncryptionPadding.OaepSHA512;
- break;
- }
- RSAParameters rsaPar = new RSAParameters();
- if (paramBytes.Length == ((9 * _KeySize) / 16) + 4)
- {
- int idx = 4;
- rsaPar.D = SubArray(paramBytes, idx, _KeySizeDiv);
- rsaPar.P = SubArray(paramBytes, idx += _KeySizeDiv, _KeySizeDiv2);
- rsaPar.Q = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
- rsaPar.DP = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
- rsaPar.DQ = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
- rsaPar.InverseQ = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv2);
- rsaPar.Modulus = SubArray(paramBytes, idx += _KeySizeDiv2, _KeySizeDiv);
- rsaPar.Exponent = (byte[])_Exponent.Clone();
- }
- else if (paramBytes.Length == _KeySizeDiv + 4)
- {
- rsaPar.Modulus = SubArray(paramBytes, 4, _KeySizeDiv);
- rsaPar.Exponent = (byte[])_Exponent.Clone();
- }
- else
- {
- throw new Exception("Invalid Parameter");
- }
- Cryptor = new RSACng();
- Cryptor.ImportParameters(rsaPar);
- }
- public byte[] Encrypt(byte[] Data)
- {
- if (Data.Length > limit)
- {
- List<byte> result = new List<byte>();
- int minRounds = Data.Length / limit;
- for (int i = 0; i < minRounds; i++)
- result.AddRange(Cryptor.Encrypt(SubArray(Data, i * limit, limit), Padding));
- minRounds *= limit;
- if (minRounds < Data.Length)
- result.AddRange(Cryptor.Encrypt(SubArray(Data, minRounds, Data.Length - minRounds), Padding));
- return result.ToArray();
- }
- else
- {
- return Cryptor.Encrypt(Data, Padding);
- }
- }
- public byte[] Decrypt(byte[] Data)
- {
- if (Data.Length > _KeySizeDiv)
- {
- List<byte> result = new List<byte>();
- for (int i = 0; i < Data.Length; i += _KeySizeDiv) result.AddRange(Cryptor.Decrypt(SubArray(Data,i, _KeySizeDiv), Padding));
- return result.ToArray();
- }
- else
- {
- return Cryptor.Decrypt(Data, Padding);
- }
- }
- public byte[] ToByteArray(in bool includePrivate)
- {
- List<byte> ab = new List<byte>();
- RSAParameters parameters = Cryptor.ExportParameters(includePrivate);
- ab.AddRange(BitConverter.GetBytes(((int)padEnum << 24) | _KeySize));
- if (includePrivate)
- {
- ab.AddRange(parameters.D);
- ab.AddRange(parameters.P);
- ab.AddRange(parameters.Q);
- ab.AddRange(parameters.DP);
- ab.AddRange(parameters.DQ);
- ab.AddRange(parameters.InverseQ);
- ab.AddRange(parameters.Modulus);
- }
- else
- {
- ab.AddRange((byte[])parameters.Modulus.Clone());
- }
- return ab.ToArray();
- }
- public void Dispose() => Cryptor.Dispose();
- private static byte[] SubArray(byte[] arr, in int offset, in int length)
- {
- byte[] result = new byte[length];
- Array.Copy(arr, offset, result, 0, length);
- return result;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment