92 lines
2.4 KiB
C#
92 lines
2.4 KiB
C#
using System;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Security;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
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);
|
|
if (param is ParametersWithRandom)
|
|
{
|
|
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
|
|
key = (RsaKeyParameters)parametersWithRandom.Parameters;
|
|
random = parametersWithRandom.Random;
|
|
}
|
|
else
|
|
{
|
|
key = (RsaKeyParameters)param;
|
|
random = new SecureRandom();
|
|
}
|
|
}
|
|
|
|
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 bigInteger = core.ConvertInput(inBuf, inOff, inLen);
|
|
BigInteger bigInteger4;
|
|
if (key is RsaPrivateCrtKeyParameters)
|
|
{
|
|
RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)key;
|
|
BigInteger publicExponent = rsaPrivateCrtKeyParameters.PublicExponent;
|
|
if (publicExponent != null)
|
|
{
|
|
BigInteger modulus = rsaPrivateCrtKeyParameters.Modulus;
|
|
BigInteger bigInteger2 = BigIntegers.CreateRandomInRange(BigInteger.One, modulus.Subtract(BigInteger.One), random);
|
|
BigInteger input = bigInteger2.ModPow(publicExponent, modulus).Multiply(bigInteger).Mod(modulus);
|
|
BigInteger bigInteger3 = core.ProcessBlock(input);
|
|
BigInteger val = bigInteger2.ModInverse(modulus);
|
|
bigInteger4 = bigInteger3.Multiply(val).Mod(modulus);
|
|
if (!bigInteger.Equals(bigInteger4.ModPow(publicExponent, modulus)))
|
|
{
|
|
throw new InvalidOperationException("RSA engine faulty decryption/signing detected");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bigInteger4 = core.ProcessBlock(bigInteger);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bigInteger4 = core.ProcessBlock(bigInteger);
|
|
}
|
|
return core.ConvertOutput(bigInteger4);
|
|
}
|
|
}
|