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)
{
core.Init(forEncryption, param);
ParametersWithRandom parametersWithRandom = param as ParametersWithRandom;
if (parametersWithRandom != null) {
key = (RsaKeyParameters)parametersWithRandom.Parameters;
if (key is RsaPrivateCrtKeyParameters)
random = parametersWithRandom.Random;
else
random = null;
} else {
key = (RsaKeyParameters)param;
if (key is RsaPrivateCrtKeyParameters)
random = CryptoServicesRegistrar.GetSecureRandom();
else
random = null;
}
}
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);
}
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);
}
}
}