上海虹口龙之梦项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

230 lines
6.5 KiB

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Signers
{
/**
* X9.31-1998 - signing using a hash.
* <p>
* The message digest hash, H, is encapsulated to form a byte string as follows
* </p>
* <pre>
* EB = 06 || PS || 0xBA || H || TRAILER
* </pre>
* where PS is a string of bytes all of value 0xBB of length such that |EB|=|n|, and TRAILER is the ISO/IEC 10118 part number† for the digest. The byte string, EB, is converted to an integer value, the message representative, f.
*/
public class X931Signer
: ISigner
{
public const int TRAILER_IMPLICIT = 0xBC;
public const int TRAILER_RIPEMD160 = 0x31CC;
public const int TRAILER_RIPEMD128 = 0x32CC;
public const int TRAILER_SHA1 = 0x33CC;
public const int TRAILER_SHA256 = 0x34CC;
public const int TRAILER_SHA512 = 0x35CC;
public const int TRAILER_SHA384 = 0x36CC;
public const int TRAILER_WHIRLPOOL = 0x37CC;
public const int TRAILER_SHA224 = 0x38CC;
private IDigest digest;
private IAsymmetricBlockCipher cipher;
private RsaKeyParameters kParam;
private int trailer;
private int keyBits;
private byte[] block;
/**
* Generate a signer with either implicit or explicit trailers for X9.31.
*
* @param cipher base cipher to use for signature creation/verification
* @param digest digest to use.
* @param implicit whether or not the trailer is implicit or gives the hash.
*/
public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest, bool isImplicit)
{
this.cipher = cipher;
this.digest = digest;
if (isImplicit)
{
trailer = IsoTrailers.TRAILER_IMPLICIT;
}
else if (IsoTrailers.NoTrailerAvailable(digest))
{
throw new ArgumentException("no valid trailer", "digest");
}
else
{
trailer = IsoTrailers.GetTrailer(digest);
}
}
public virtual string AlgorithmName
{
get { return digest.AlgorithmName + "with" + cipher.AlgorithmName + "/X9.31"; }
}
/**
* Constructor for a signer with an explicit digest trailer.
*
* @param cipher cipher to use.
* @param digest digest to sign with.
*/
public X931Signer(IAsymmetricBlockCipher cipher, IDigest digest)
: this(cipher, digest, 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();
}
/// <summary> clear possible sensitive data</summary>
private void ClearBlock(byte[] block)
{
Array.Clear(block, 0, block.Length);
}
/**
* update the internal digest with the byte b
*/
public virtual void Update(byte b)
{
digest.Update(b);
}
/**
* update the internal digest with the byte array in
*/
public virtual void BlockUpdate(byte[] input, int off, int len)
{
digest.BlockUpdate(input, off, len);
}
/**
* reset the internal state
*/
public virtual void Reset()
{
digest.Reset();
}
/**
* generate a signature for the loaded message using the key we were
* initialised with.
*/
public virtual byte[] GenerateSignature()
{
CreateSignatureBlock();
BigInteger t = new BigInteger(1, cipher.ProcessBlock(block, 0, block.Length));
ClearBlock(block);
t = t.Min(kParam.Modulus.Subtract(t));
int size = BigIntegers.GetUnsignedByteLength(kParam.Modulus);
return BigIntegers.AsUnsignedByteArray(size, t);
}
private void CreateSignatureBlock()
{
int digSize = digest.GetDigestSize();
int delta;
if (trailer == IsoTrailers.TRAILER_IMPLICIT)
{
delta = block.Length - digSize - 1;
digest.DoFinal(block, delta);
block[block.Length - 1] = (byte)IsoTrailers.TRAILER_IMPLICIT;
}
else
{
delta = block.Length - digSize - 2;
digest.DoFinal(block, delta);
block[block.Length - 2] = (byte)(trailer >> 8);
block[block.Length - 1] = (byte)trailer;
}
block[0] = 0x6b;
for (int i = delta - 2; i != 0; i--)
{
block[i] = (byte)0xbb;
}
block[delta - 1] = (byte)0xba;
}
/**
* return true if the signature represents a ISO9796-2 signature
* for the passed in message.
*/
public virtual bool VerifySignature(byte[] signature)
{
try
{
block = cipher.ProcessBlock(signature, 0, signature.Length);
}
catch (Exception)
{
return false;
}
BigInteger t = new BigInteger(1, block);
BigInteger f;
if ((t.IntValue & 15) == 12)
{
f = t;
}
else
{
t = kParam.Modulus.Subtract(t);
if ((t.IntValue & 15) == 12)
{
f = t;
}
else
{
return false;
}
}
CreateSignatureBlock();
byte[] fBlock = BigIntegers.AsUnsignedByteArray(block.Length, f);
bool rv = Arrays.ConstantTimeAreEqual(block, fBlock);
ClearBlock(block);
ClearBlock(fBlock);
return rv;
}
}
}
#pragma warning restore
#endif