RsaCipher
Implements RSA cipher algorithm.
using Renci.SshNet.Common;
using System;
namespace Renci.SshNet.Security.Cryptography.Ciphers
{
public class RsaCipher : AsymmetricCipher
{
private readonly RsaKey _key;
public RsaCipher(RsaKey key)
{
if (key == null)
throw new ArgumentNullException("key");
_key = key;
}
public override byte[] Encrypt(byte[] input, int offset, int length)
{
int bitLength = _key.Modulus.BitLength;
byte[] array = new byte[bitLength / 8 + ((bitLength % 8 > 0) ? 1 : 0) - 1];
array[0] = 1;
for (int i = 1; i < array.Length - length - 1; i++) {
array[i] = byte.MaxValue;
}
Buffer.BlockCopy(input, offset, array, array.Length - length, length);
return Transform(array);
}
public override byte[] Decrypt(byte[] input)
{
return Decrypt(input, 0, input.Length);
}
public override byte[] Decrypt(byte[] input, int offset, int length)
{
byte[] array = Transform(input, offset, length);
byte b = array[0];
if (b != 1 && b != 2)
throw new NotSupportedException("Only block type 01 or 02 are supported.");
int i;
for (i = 1; i < array.Length && array[i] != 0; i++) {
}
i++;
byte[] array2 = new byte[array.Length - i];
Buffer.BlockCopy(array, i, array2, 0, array2.Length);
return array2;
}
private byte[] Transform(byte[] data)
{
return Transform(data, 0, data.Length);
}
private byte[] Transform(byte[] data, int offset, int length)
{
Array.Reverse(data, offset, length);
byte[] array = new byte[length + 1];
Buffer.BlockCopy(data, offset, array, 0, length);
BigInteger bigInteger = new BigInteger(array);
BigInteger bigInteger2 = _key.D;
BigInteger bigInteger5;
if (!bigInteger2.IsZero) {
BigInteger bigInteger3 = BigInteger.One;
BigInteger bigInteger4 = _key.Modulus - (BigInteger)1;
bigInteger2 = _key.Modulus;
int bitLength = bigInteger2.BitLength;
if (bigInteger4 < BigInteger.One)
throw new SshException("Invalid RSA key.");
while (bigInteger3 <= BigInteger.One || bigInteger3 >= bigInteger4) {
bigInteger3 = BigInteger.Random(bitLength);
}
BigInteger dividend = BigInteger.PositiveMod(BigInteger.ModPow(bigInteger3, _key.Exponent, _key.Modulus) * bigInteger, _key.Modulus);
BigInteger left = BigInteger.ModPow(dividend % _key.P, _key.DP, _key.P);
BigInteger right = BigInteger.ModPow(dividend % _key.Q, _key.DQ, _key.Q);
BigInteger left2 = BigInteger.PositiveMod((left - right) * _key.InverseQ, _key.P) * _key.Q + right;
BigInteger right2 = BigInteger.ModInverse(bigInteger3, _key.Modulus);
bigInteger5 = BigInteger.PositiveMod(left2 * right2, _key.Modulus);
} else
bigInteger5 = BigInteger.ModPow(bigInteger, _key.Exponent, _key.Modulus);
return bigInteger5.ToByteArray().Reverse();
}
}
}