init commit
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Encodings;
|
||||
|
||||
public class ISO9796d1Encoding : IAsymmetricBlockCipher
|
||||
{
|
||||
private static readonly BigInteger Sixteen = BigInteger.ValueOf(16L);
|
||||
|
||||
private static readonly BigInteger Six = BigInteger.ValueOf(6L);
|
||||
|
||||
private static readonly byte[] shadows = new byte[16]
|
||||
{
|
||||
14, 3, 5, 8, 9, 4, 2, 15, 0, 13,
|
||||
11, 6, 7, 10, 12, 1
|
||||
};
|
||||
|
||||
private static readonly byte[] inverse = new byte[16]
|
||||
{
|
||||
8, 15, 6, 1, 5, 2, 11, 12, 3, 4,
|
||||
13, 10, 14, 9, 0, 7
|
||||
};
|
||||
|
||||
private readonly IAsymmetricBlockCipher engine;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private int bitSize;
|
||||
|
||||
private int padBits = 0;
|
||||
|
||||
private BigInteger modulus;
|
||||
|
||||
public string AlgorithmName => engine.AlgorithmName + "/ISO9796-1Padding";
|
||||
|
||||
public ISO9796d1Encoding(IAsymmetricBlockCipher cipher)
|
||||
{
|
||||
engine = cipher;
|
||||
}
|
||||
|
||||
public IAsymmetricBlockCipher GetUnderlyingCipher()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
RsaKeyParameters rsaKeyParameters;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
rsaKeyParameters = (RsaKeyParameters)parametersWithRandom.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
rsaKeyParameters = (RsaKeyParameters)parameters;
|
||||
}
|
||||
engine.Init(forEncryption, parameters);
|
||||
modulus = rsaKeyParameters.Modulus;
|
||||
bitSize = modulus.BitLength;
|
||||
this.forEncryption = forEncryption;
|
||||
}
|
||||
|
||||
public int GetInputBlockSize()
|
||||
{
|
||||
int inputBlockSize = engine.GetInputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return (inputBlockSize + 1) / 2;
|
||||
}
|
||||
return inputBlockSize;
|
||||
}
|
||||
|
||||
public int GetOutputBlockSize()
|
||||
{
|
||||
int outputBlockSize = engine.GetOutputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return outputBlockSize;
|
||||
}
|
||||
return (outputBlockSize + 1) / 2;
|
||||
}
|
||||
|
||||
public void SetPadBits(int padBits)
|
||||
{
|
||||
if (padBits > 7)
|
||||
{
|
||||
throw new ArgumentException("padBits > 7");
|
||||
}
|
||||
this.padBits = padBits;
|
||||
}
|
||||
|
||||
public int GetPadBits()
|
||||
{
|
||||
return padBits;
|
||||
}
|
||||
|
||||
public byte[] ProcessBlock(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return EncodeBlock(input, inOff, length);
|
||||
}
|
||||
return DecodeBlock(input, inOff, length);
|
||||
}
|
||||
|
||||
private byte[] EncodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
byte[] array = new byte[(bitSize + 7) / 8];
|
||||
int num = padBits + 1;
|
||||
int num2 = (bitSize + 13) / 16;
|
||||
for (int i = 0; i < num2; i += inLen)
|
||||
{
|
||||
if (i > num2 - inLen)
|
||||
{
|
||||
Array.Copy(input, inOff + inLen - (num2 - i), array, array.Length - num2, num2 - i);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(input, inOff, array, array.Length - (i + inLen), inLen);
|
||||
}
|
||||
}
|
||||
for (int j = array.Length - 2 * num2; j != array.Length; j += 2)
|
||||
{
|
||||
byte b = array[array.Length - num2 + j / 2];
|
||||
array[j] = (byte)((shadows[(b & 0xFF) >>> 4] << 4) | shadows[b & 0xF]);
|
||||
array[j + 1] = b;
|
||||
}
|
||||
byte[] array3;
|
||||
byte[] array2 = (array3 = array);
|
||||
int num3 = array.Length - 2 * inLen;
|
||||
nint num4 = num3;
|
||||
array2[num3] = (byte)(array3[num4] ^ (byte)num);
|
||||
array[^1] = (byte)((array[^1] << 4) | 6);
|
||||
int num5 = 8 - (bitSize - 1) % 8;
|
||||
int num6 = 0;
|
||||
if (num5 != 8)
|
||||
{
|
||||
(array3 = array)[0] = (byte)(array3[0] & (byte)(255 >> num5));
|
||||
(array3 = array)[0] = (byte)(array3[0] | (byte)(128 >> num5));
|
||||
}
|
||||
else
|
||||
{
|
||||
array[0] = 0;
|
||||
(array3 = array)[1] = (byte)(array3[1] | 0x80);
|
||||
num6 = 1;
|
||||
}
|
||||
return engine.ProcessBlock(array, num6, array.Length - num6);
|
||||
}
|
||||
|
||||
private byte[] DecodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
byte[] bytes = engine.ProcessBlock(input, inOff, inLen);
|
||||
int num = 1;
|
||||
int num2 = (bitSize + 13) / 16;
|
||||
BigInteger bigInteger = new BigInteger(1, bytes);
|
||||
BigInteger bigInteger2;
|
||||
if (bigInteger.Mod(Sixteen).Equals(Six))
|
||||
{
|
||||
bigInteger2 = bigInteger;
|
||||
}
|
||||
else
|
||||
{
|
||||
bigInteger2 = modulus.Subtract(bigInteger);
|
||||
if (!bigInteger2.Mod(Sixteen).Equals(Six))
|
||||
{
|
||||
throw new InvalidCipherTextException("resulting integer iS or (modulus - iS) is not congruent to 6 mod 16");
|
||||
}
|
||||
}
|
||||
bytes = bigInteger2.ToByteArrayUnsigned();
|
||||
if ((bytes[^1] & 0xF) != 6)
|
||||
{
|
||||
throw new InvalidCipherTextException("invalid forcing byte in block");
|
||||
}
|
||||
bytes[^1] = (byte)(((ushort)(bytes[^1] & 0xFF) >> 4) | (inverse[(bytes[^2] & 0xFF) >> 4] << 4));
|
||||
bytes[0] = (byte)((shadows[(bytes[1] & 0xFF) >>> 4] << 4) | shadows[bytes[1] & 0xF]);
|
||||
bool flag = false;
|
||||
int num3 = 0;
|
||||
for (int num4 = bytes.Length - 1; num4 >= bytes.Length - 2 * num2; num4 -= 2)
|
||||
{
|
||||
int num5 = (shadows[(bytes[num4] & 0xFF) >>> 4] << 4) | shadows[bytes[num4] & 0xF];
|
||||
if (((bytes[num4 - 1] ^ num5) & 0xFF) != 0)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
throw new InvalidCipherTextException("invalid tsums in block");
|
||||
}
|
||||
flag = true;
|
||||
num = (bytes[num4 - 1] ^ num5) & 0xFF;
|
||||
num3 = num4 - 1;
|
||||
}
|
||||
}
|
||||
bytes[num3] = 0;
|
||||
byte[] array = new byte[(bytes.Length - num3) / 2];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
array[i] = bytes[2 * i + num3 + 1];
|
||||
}
|
||||
padBits = num - 1;
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Encodings;
|
||||
|
||||
public class OaepEncoding : IAsymmetricBlockCipher
|
||||
{
|
||||
private byte[] defHash;
|
||||
|
||||
private IDigest mgf1Hash;
|
||||
|
||||
private IAsymmetricBlockCipher engine;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
public string AlgorithmName => engine.AlgorithmName + "/OAEPPadding";
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher)
|
||||
: this(cipher, new Sha1Digest(), null)
|
||||
{
|
||||
}
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher, IDigest hash)
|
||||
: this(cipher, hash, null)
|
||||
{
|
||||
}
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher, IDigest hash, byte[] encodingParams)
|
||||
: this(cipher, hash, hash, encodingParams)
|
||||
{
|
||||
}
|
||||
|
||||
public OaepEncoding(IAsymmetricBlockCipher cipher, IDigest hash, IDigest mgf1Hash, byte[] encodingParams)
|
||||
{
|
||||
engine = cipher;
|
||||
this.mgf1Hash = mgf1Hash;
|
||||
defHash = new byte[hash.GetDigestSize()];
|
||||
hash.Reset();
|
||||
if (encodingParams != null)
|
||||
{
|
||||
hash.BlockUpdate(encodingParams, 0, encodingParams.Length);
|
||||
}
|
||||
hash.DoFinal(defHash, 0);
|
||||
}
|
||||
|
||||
public IAsymmetricBlockCipher GetUnderlyingCipher()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters param)
|
||||
{
|
||||
if (param is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
|
||||
random = parametersWithRandom.Random;
|
||||
}
|
||||
else
|
||||
{
|
||||
random = new SecureRandom();
|
||||
}
|
||||
engine.Init(forEncryption, param);
|
||||
this.forEncryption = forEncryption;
|
||||
}
|
||||
|
||||
public int GetInputBlockSize()
|
||||
{
|
||||
int inputBlockSize = engine.GetInputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return inputBlockSize - 1 - 2 * defHash.Length;
|
||||
}
|
||||
return inputBlockSize;
|
||||
}
|
||||
|
||||
public int GetOutputBlockSize()
|
||||
{
|
||||
int outputBlockSize = engine.GetOutputBlockSize();
|
||||
if (forEncryption)
|
||||
{
|
||||
return outputBlockSize;
|
||||
}
|
||||
return outputBlockSize - 1 - 2 * defHash.Length;
|
||||
}
|
||||
|
||||
public byte[] ProcessBlock(byte[] inBytes, int inOff, int inLen)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return EncodeBlock(inBytes, inOff, inLen);
|
||||
}
|
||||
return DecodeBlock(inBytes, inOff, inLen);
|
||||
}
|
||||
|
||||
private byte[] EncodeBlock(byte[] inBytes, int inOff, int inLen)
|
||||
{
|
||||
Check.DataLength(inLen > GetInputBlockSize(), "input data too long");
|
||||
byte[] array = new byte[GetInputBlockSize() + 1 + 2 * defHash.Length];
|
||||
Array.Copy(inBytes, inOff, array, array.Length - inLen, inLen);
|
||||
array[array.Length - inLen - 1] = 1;
|
||||
Array.Copy(defHash, 0, array, defHash.Length, defHash.Length);
|
||||
byte[] nextBytes = SecureRandom.GetNextBytes(random, defHash.Length);
|
||||
byte[] array2 = maskGeneratorFunction1(nextBytes, 0, nextBytes.Length, array.Length - defHash.Length);
|
||||
for (int i = defHash.Length; i != array.Length; i++)
|
||||
{
|
||||
byte[] array4;
|
||||
byte[] array3 = (array4 = array);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array3[num] = (byte)(array4[num2] ^ array2[i - defHash.Length]);
|
||||
}
|
||||
Array.Copy(nextBytes, 0, array, 0, defHash.Length);
|
||||
array2 = maskGeneratorFunction1(array, defHash.Length, array.Length - defHash.Length, defHash.Length);
|
||||
for (int j = 0; j != defHash.Length; j++)
|
||||
{
|
||||
byte[] array4;
|
||||
byte[] array5 = (array4 = array);
|
||||
int num3 = j;
|
||||
nint num2 = num3;
|
||||
array5[num3] = (byte)(array4[num2] ^ array2[j]);
|
||||
}
|
||||
return engine.ProcessBlock(array, 0, array.Length);
|
||||
}
|
||||
|
||||
private byte[] DecodeBlock(byte[] inBytes, int inOff, int inLen)
|
||||
{
|
||||
byte[] array = engine.ProcessBlock(inBytes, inOff, inLen);
|
||||
byte[] array2 = new byte[engine.GetOutputBlockSize()];
|
||||
bool flag = array2.Length < 2 * defHash.Length + 1;
|
||||
if (array.Length <= array2.Length)
|
||||
{
|
||||
Array.Copy(array, 0, array2, array2.Length - array.Length, array.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Copy(array, 0, array2, 0, array2.Length);
|
||||
flag = true;
|
||||
}
|
||||
byte[] array3 = maskGeneratorFunction1(array2, defHash.Length, array2.Length - defHash.Length, defHash.Length);
|
||||
for (int i = 0; i != defHash.Length; i++)
|
||||
{
|
||||
byte[] array5;
|
||||
byte[] array4 = (array5 = array2);
|
||||
int num = i;
|
||||
nint num2 = num;
|
||||
array4[num] = (byte)(array5[num2] ^ array3[i]);
|
||||
}
|
||||
array3 = maskGeneratorFunction1(array2, 0, defHash.Length, array2.Length - defHash.Length);
|
||||
for (int j = defHash.Length; j != array2.Length; j++)
|
||||
{
|
||||
byte[] array5;
|
||||
byte[] array6 = (array5 = array2);
|
||||
int num3 = j;
|
||||
nint num2 = num3;
|
||||
array6[num3] = (byte)(array5[num2] ^ array3[j - defHash.Length]);
|
||||
}
|
||||
bool flag2 = false;
|
||||
for (int k = 0; k != defHash.Length; k++)
|
||||
{
|
||||
if (defHash[k] != array2[defHash.Length + k])
|
||||
{
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
int num4 = array2.Length;
|
||||
for (int l = 2 * defHash.Length; l != array2.Length; l++)
|
||||
{
|
||||
if ((array2[l] != 0) & (num4 == array2.Length))
|
||||
{
|
||||
num4 = l;
|
||||
}
|
||||
}
|
||||
bool flag3 = (num4 > array2.Length - 1) | (array2[num4] != 1);
|
||||
num4++;
|
||||
if (flag2 || flag || flag3)
|
||||
{
|
||||
Arrays.Fill(array2, 0);
|
||||
throw new InvalidCipherTextException("data wrong");
|
||||
}
|
||||
byte[] array7 = new byte[array2.Length - num4];
|
||||
Array.Copy(array2, num4, array7, 0, array7.Length);
|
||||
return array7;
|
||||
}
|
||||
|
||||
private void ItoOSP(int i, byte[] sp)
|
||||
{
|
||||
sp[0] = (byte)((uint)i >> 24);
|
||||
sp[1] = (byte)((uint)i >> 16);
|
||||
sp[2] = (byte)((uint)i >> 8);
|
||||
sp[3] = (byte)i;
|
||||
}
|
||||
|
||||
private byte[] maskGeneratorFunction1(byte[] Z, int zOff, int zLen, int length)
|
||||
{
|
||||
byte[] array = new byte[length];
|
||||
byte[] array2 = new byte[mgf1Hash.GetDigestSize()];
|
||||
byte[] array3 = new byte[4];
|
||||
int i = 0;
|
||||
mgf1Hash.Reset();
|
||||
for (; i < length / array2.Length; i++)
|
||||
{
|
||||
ItoOSP(i, array3);
|
||||
mgf1Hash.BlockUpdate(Z, zOff, zLen);
|
||||
mgf1Hash.BlockUpdate(array3, 0, array3.Length);
|
||||
mgf1Hash.DoFinal(array2, 0);
|
||||
Array.Copy(array2, 0, array, i * array2.Length, array2.Length);
|
||||
}
|
||||
if (i * array2.Length < length)
|
||||
{
|
||||
ItoOSP(i, array3);
|
||||
mgf1Hash.BlockUpdate(Z, zOff, zLen);
|
||||
mgf1Hash.BlockUpdate(array3, 0, array3.Length);
|
||||
mgf1Hash.DoFinal(array2, 0);
|
||||
Array.Copy(array2, 0, array, i * array2.Length, array.Length - i * array2.Length);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Encodings;
|
||||
|
||||
public class Pkcs1Encoding : IAsymmetricBlockCipher
|
||||
{
|
||||
public const string StrictLengthEnabledProperty = "Org.BouncyCastle.Pkcs1.Strict";
|
||||
|
||||
private const int HeaderLength = 10;
|
||||
|
||||
private static readonly bool[] strictLengthEnabled;
|
||||
|
||||
private SecureRandom random;
|
||||
|
||||
private IAsymmetricBlockCipher engine;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
private bool forPrivateKey;
|
||||
|
||||
private bool useStrictLength;
|
||||
|
||||
private int pLen = -1;
|
||||
|
||||
private byte[] fallback = null;
|
||||
|
||||
private byte[] blockBuffer = null;
|
||||
|
||||
public static bool StrictLengthEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return strictLengthEnabled[0];
|
||||
}
|
||||
set
|
||||
{
|
||||
strictLengthEnabled[0] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string AlgorithmName => engine.AlgorithmName + "/PKCS1Padding";
|
||||
|
||||
static Pkcs1Encoding()
|
||||
{
|
||||
string environmentVariable = Platform.GetEnvironmentVariable("Org.BouncyCastle.Pkcs1.Strict");
|
||||
strictLengthEnabled = new bool[1] { environmentVariable?.Equals("true") ?? true };
|
||||
}
|
||||
|
||||
public Pkcs1Encoding(IAsymmetricBlockCipher cipher)
|
||||
{
|
||||
engine = cipher;
|
||||
useStrictLength = StrictLengthEnabled;
|
||||
}
|
||||
|
||||
public Pkcs1Encoding(IAsymmetricBlockCipher cipher, int pLen)
|
||||
{
|
||||
engine = cipher;
|
||||
useStrictLength = StrictLengthEnabled;
|
||||
this.pLen = pLen;
|
||||
}
|
||||
|
||||
public Pkcs1Encoding(IAsymmetricBlockCipher cipher, byte[] fallback)
|
||||
{
|
||||
engine = cipher;
|
||||
useStrictLength = StrictLengthEnabled;
|
||||
this.fallback = fallback;
|
||||
pLen = fallback.Length;
|
||||
}
|
||||
|
||||
public IAsymmetricBlockCipher GetUnderlyingCipher()
|
||||
{
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
AsymmetricKeyParameter asymmetricKeyParameter;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
|
||||
random = parametersWithRandom.Random;
|
||||
asymmetricKeyParameter = (AsymmetricKeyParameter)parametersWithRandom.Parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
random = new SecureRandom();
|
||||
asymmetricKeyParameter = (AsymmetricKeyParameter)parameters;
|
||||
}
|
||||
engine.Init(forEncryption, parameters);
|
||||
forPrivateKey = asymmetricKeyParameter.IsPrivate;
|
||||
this.forEncryption = forEncryption;
|
||||
blockBuffer = new byte[engine.GetOutputBlockSize()];
|
||||
if (pLen > 0 && fallback == null && random == null)
|
||||
{
|
||||
throw new ArgumentException("encoder requires random");
|
||||
}
|
||||
}
|
||||
|
||||
public int GetInputBlockSize()
|
||||
{
|
||||
int inputBlockSize = engine.GetInputBlockSize();
|
||||
if (!forEncryption)
|
||||
{
|
||||
return inputBlockSize;
|
||||
}
|
||||
return inputBlockSize - 10;
|
||||
}
|
||||
|
||||
public int GetOutputBlockSize()
|
||||
{
|
||||
int outputBlockSize = engine.GetOutputBlockSize();
|
||||
if (!forEncryption)
|
||||
{
|
||||
return outputBlockSize - 10;
|
||||
}
|
||||
return outputBlockSize;
|
||||
}
|
||||
|
||||
public byte[] ProcessBlock(byte[] input, int inOff, int length)
|
||||
{
|
||||
if (!forEncryption)
|
||||
{
|
||||
return DecodeBlock(input, inOff, length);
|
||||
}
|
||||
return EncodeBlock(input, inOff, length);
|
||||
}
|
||||
|
||||
private byte[] EncodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (inLen > GetInputBlockSize())
|
||||
{
|
||||
throw new ArgumentException("input data too large", "inLen");
|
||||
}
|
||||
byte[] array = new byte[engine.GetInputBlockSize()];
|
||||
if (forPrivateKey)
|
||||
{
|
||||
array[0] = 1;
|
||||
for (int i = 1; i != array.Length - inLen - 1; i++)
|
||||
{
|
||||
array[i] = byte.MaxValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
random.NextBytes(array);
|
||||
array[0] = 2;
|
||||
for (int j = 1; j != array.Length - inLen - 1; j++)
|
||||
{
|
||||
while (array[j] == 0)
|
||||
{
|
||||
array[j] = (byte)random.NextInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
array[array.Length - inLen - 1] = 0;
|
||||
Array.Copy(input, inOff, array, array.Length - inLen, inLen);
|
||||
return engine.ProcessBlock(array, 0, array.Length);
|
||||
}
|
||||
|
||||
private static int CheckPkcs1Encoding(byte[] encoded, int pLen)
|
||||
{
|
||||
int num = 0;
|
||||
num |= encoded[0] ^ 2;
|
||||
int num2 = encoded.Length - (pLen + 1);
|
||||
for (int i = 1; i < num2; i++)
|
||||
{
|
||||
int num3 = encoded[i];
|
||||
num3 |= num3 >> 1;
|
||||
num3 |= num3 >> 2;
|
||||
num3 |= num3 >> 4;
|
||||
num |= (num3 & 1) - 1;
|
||||
}
|
||||
num |= encoded[^(pLen + 1)];
|
||||
num |= num >> 1;
|
||||
num |= num >> 2;
|
||||
num |= num >> 4;
|
||||
return ~((num & 1) - 1);
|
||||
}
|
||||
|
||||
private byte[] DecodeBlockOrRandom(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (!forPrivateKey)
|
||||
{
|
||||
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
|
||||
}
|
||||
byte[] array = engine.ProcessBlock(input, inOff, inLen);
|
||||
byte[] array2;
|
||||
if (fallback == null)
|
||||
{
|
||||
array2 = new byte[pLen];
|
||||
random.NextBytes(array2);
|
||||
}
|
||||
else
|
||||
{
|
||||
array2 = fallback;
|
||||
}
|
||||
byte[] array3 = ((useStrictLength & (array.Length != engine.GetOutputBlockSize())) ? blockBuffer : array);
|
||||
int num = CheckPkcs1Encoding(array3, pLen);
|
||||
byte[] array4 = new byte[pLen];
|
||||
for (int i = 0; i < pLen; i++)
|
||||
{
|
||||
array4[i] = (byte)((array3[i + (array3.Length - pLen)] & ~num) | (array2[i] & num));
|
||||
}
|
||||
Arrays.Fill(array3, 0);
|
||||
return array4;
|
||||
}
|
||||
|
||||
private byte[] DecodeBlock(byte[] input, int inOff, int inLen)
|
||||
{
|
||||
if (pLen != -1)
|
||||
{
|
||||
return DecodeBlockOrRandom(input, inOff, inLen);
|
||||
}
|
||||
byte[] array = engine.ProcessBlock(input, inOff, inLen);
|
||||
bool flag = useStrictLength & (array.Length != engine.GetOutputBlockSize());
|
||||
byte[] array2 = ((array.Length >= GetOutputBlockSize()) ? array : blockBuffer);
|
||||
byte b = (byte)((!forPrivateKey) ? 1u : 2u);
|
||||
byte b2 = array2[0];
|
||||
bool flag2 = b2 != b;
|
||||
int num = FindStart(b2, array2);
|
||||
num++;
|
||||
if (flag2 || num < 10)
|
||||
{
|
||||
Arrays.Fill(array2, 0);
|
||||
throw new InvalidCipherTextException("block incorrect");
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
Arrays.Fill(array2, 0);
|
||||
throw new InvalidCipherTextException("block incorrect size");
|
||||
}
|
||||
byte[] array3 = new byte[array2.Length - num];
|
||||
Array.Copy(array2, num, array3, 0, array3.Length);
|
||||
return array3;
|
||||
}
|
||||
|
||||
private int FindStart(byte type, byte[] block)
|
||||
{
|
||||
int num = -1;
|
||||
bool flag = false;
|
||||
for (int i = 1; i != block.Length; i++)
|
||||
{
|
||||
byte b = block[i];
|
||||
if (b == 0 && num < 0)
|
||||
{
|
||||
num = i;
|
||||
}
|
||||
flag = flag || (type == 1 && num < 0 && b != byte.MaxValue);
|
||||
}
|
||||
if (!flag)
|
||||
{
|
||||
return num;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user