init commit
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Signers;
|
||||
|
||||
public class X931Signer : ISigner
|
||||
{
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_IMPLICIT = 188;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_RIPEMD160 = 12748;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_RIPEMD128 = 13004;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_SHA1 = 13260;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_SHA256 = 13516;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_SHA512 = 13772;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_SHA384 = 14028;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_WHIRLPOOL = 14284;
|
||||
|
||||
[Obsolete("Use 'IsoTrailers' instead")]
|
||||
public const int TRAILER_SHA224 = 14540;
|
||||
|
||||
private IDigest digest;
|
||||
|
||||
private IAsymmetricBlockCipher cipher;
|
||||
|
||||
private RsaKeyParameters kParam;
|
||||
|
||||
private int trailer;
|
||||
|
||||
private int keyBits;
|
||||
|
||||
private byte[] block;
|
||||
|
||||
public virtual string AlgorithmName => digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31";
|
||||
|
||||
public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
|
||||
{
|
||||
this.cipher = cipher;
|
||||
this.digest = digest;
|
||||
if (isImplicit)
|
||||
{
|
||||
trailer = 188;
|
||||
return;
|
||||
}
|
||||
if (IsoTrailers.NoTrailerAvailable(digest))
|
||||
{
|
||||
throw new ArgumentException("no valid trailer", "digest");
|
||||
}
|
||||
trailer = IsoTrailers.GetTrailer(digest);
|
||||
}
|
||||
|
||||
public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
|
||||
: this(cipher, digest, isImplicit: false)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Init(bool forSigning, ICipherParameters parameters)
|
||||
{
|
||||
kParam = (RsaKeyParameters)parameters;
|
||||
cipher.Init(forSigning, kParam);
|
||||
keyBits = kParam.Modulus.BitLength;
|
||||
block = new byte[(keyBits + 7) / 8];
|
||||
Reset();
|
||||
}
|
||||
|
||||
private void ClearBlock(byte[] block)
|
||||
{
|
||||
Array.Clear(block, 0, block.Length);
|
||||
}
|
||||
|
||||
public virtual void Update(byte b)
|
||||
{
|
||||
digest.Update(b);
|
||||
}
|
||||
|
||||
public virtual void BlockUpdate(byte[] input, int off, int len)
|
||||
{
|
||||
digest.BlockUpdate(input, off, len);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
digest.Reset();
|
||||
}
|
||||
|
||||
public virtual byte[] GenerateSignature()
|
||||
{
|
||||
CreateSignatureBlock();
|
||||
BigInteger bigInteger = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
|
||||
ClearBlock(block);
|
||||
bigInteger = bigInteger.Min(kParam.Modulus.Subtract(bigInteger));
|
||||
int unsignedByteLength = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
|
||||
return BigIntegers.AsUnsignedByteArray(unsignedByteLength, bigInteger);
|
||||
}
|
||||
|
||||
private void CreateSignatureBlock()
|
||||
{
|
||||
int digestSize = digest.GetDigestSize();
|
||||
int num;
|
||||
if (trailer == 188)
|
||||
{
|
||||
num = block.Length - digestSize - 1;
|
||||
digest.DoFinal(block, num);
|
||||
block[block.Length - 1] = 188;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = block.Length - digestSize - 2;
|
||||
digest.DoFinal(block, num);
|
||||
block[block.Length - 2] = (byte)(trailer >> 8);
|
||||
block[block.Length - 1] = (byte)trailer;
|
||||
}
|
||||
block[0] = 107;
|
||||
for (int num2 = num - 2; num2 != 0; num2--)
|
||||
{
|
||||
block[num2] = 187;
|
||||
}
|
||||
block[num - 1] = 186;
|
||||
}
|
||||
|
||||
public virtual bool VerifySignature(byte[] signature)
|
||||
{
|
||||
try
|
||||
{
|
||||
block = cipher.ProcessBlock(signature, 0, signature.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BigInteger bigInteger = new BigInteger(1, block);
|
||||
BigInteger n;
|
||||
if ((bigInteger.IntValue & 0xF) == 12)
|
||||
{
|
||||
n = bigInteger;
|
||||
}
|
||||
else
|
||||
{
|
||||
bigInteger = kParam.Modulus.Subtract(bigInteger);
|
||||
if ((bigInteger.IntValue & 0xF) != 12)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
n = bigInteger;
|
||||
}
|
||||
CreateSignatureBlock();
|
||||
byte[] b = BigIntegers.AsUnsignedByteArray(block.Length, n);
|
||||
bool result = Arrays.ConstantTimeAreEqual(block, b);
|
||||
ClearBlock(block);
|
||||
ClearBlock(b);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user