RsaBlindedEngine
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using System;
namespace Org.BouncyCastle.Crypto.Engines
{
public class RsaBlindedEngine : IAsymmetricBlockCipher
{
private readonly IRsa core;
private RsaKeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName => "RSA";
public RsaBlindedEngine()
: this(new RsaCoreEngine())
{
}
public RsaBlindedEngine(IRsa rsa)
{
core = rsa;
}
public virtual void Init(bool forEncryption, ICipherParameters param)
{
SecureRandom provided = null;
ParametersWithRandom parametersWithRandom = param as ParametersWithRandom;
if (parametersWithRandom != null) {
provided = parametersWithRandom.Random;
param = parametersWithRandom.Parameters;
}
core.Init(forEncryption, param);
key = (RsaKeyParameters)param;
random = InitSecureRandom(key is RsaPrivateCrtKeyParameters, provided);
}
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
public virtual byte[] ProcessBlock(byte[] inBuf, int inOff, int inLen)
{
if (key == null)
throw new InvalidOperationException("RSA engine not initialised");
BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
BigInteger result = ProcessInput(input);
return core.ConvertOutput(result);
}
protected virtual SecureRandom InitSecureRandom(bool needed, SecureRandom provided)
{
if (!needed)
return null;
return CryptoServicesRegistrar.GetSecureRandom(provided);
}
private BigInteger ProcessInput(BigInteger input)
{
RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = key as RsaPrivateCrtKeyParameters;
if (rsaPrivateCrtKeyParameters == null)
return core.ProcessBlock(input);
BigInteger publicExponent = rsaPrivateCrtKeyParameters.PublicExponent;
BigInteger modulus = rsaPrivateCrtKeyParameters.Modulus;
BigInteger bigInteger = BigIntegers.CreateRandomInRange(BigInteger.One, modulus.Subtract(BigInteger.One), random);
BigInteger bigInteger2 = bigInteger.ModPow(publicExponent, modulus);
BigInteger bigInteger3 = BigIntegers.ModOddInverse(modulus, bigInteger);
BigInteger input2 = bigInteger2.Multiply(input).Mod(modulus);
BigInteger val = core.ProcessBlock(input2);
return bigInteger3.Multiply(val).Mod(modulus);
}
}
}