📄 blowfishalgorithm.cs
字号:
KeyValue = new byte[KeySizeValue >> 3];
this.rng.GetBytes(KeyValue);
}
/// <see cref="System.Security.Cryptography.SymmetricAlgorithm.GenerateIV"/>
public override void GenerateIV()
{
if (null == this.rng)
{
this.rng = new RNGCryptoServiceProvider();
}
IVValue = new byte[BlowfishECB.BLOCK_SIZE];
this.rng.GetBytes(IVValue);
}
/// <see cref="System.Security.Cryptography.ICryptoTransform.CanReuseTransform"/>
public bool CanReuseTransform
{
get
{
return true;
}
}
/// <see cref="System.Security.Cryptography.ICryptoTransform.CanTransformMultipleBlocks"/>
public bool CanTransformMultipleBlocks
{
get
{
return true;
}
}
/// <see cref="System.Security.Cryptography.ICryptoTransform.InputBlockSize"/>
public int InputBlockSize
{
get
{
return BlowfishECB.BLOCK_SIZE;
}
}
/// <see cref="System.Security.Cryptography.ICryptoTransform.OutputBlockSize"/>
public int OutputBlockSize
{
get
{
return BlowfishECB.BLOCK_SIZE;
}
}
/// <see cref="System.Security.Cryptography.ICryptoTransform.TransformBlock"/>
public int TransformBlock(byte[] bufIn, int ofsIn, int count, byte[] bufOut, int ofsOut)
{
if (0 == count)
{
return 0;
}
if (0 != count % BlowfishECB.BLOCK_SIZE)
{
throw new CryptographicException("unexpected unaligned data");
}
if (this.isEncryptor)
{
if (null == this.bfe) return this.bfc.Encrypt(bufIn, ofsIn, bufOut, ofsOut, count);
else return this.bfe.Encrypt(bufIn, ofsIn, bufOut, ofsOut, count);
}
else
{
// for decryption we have to buffer the last block, since it could be the very last one
int outp = 0;
if (null == this.block)
{
this.block = new byte[BlowfishECB.BLOCK_SIZE];
}
else
{
// and also flush the former last one
if (null == this.bfe) this.bfc.Decrypt(this.block, 0, bufOut, ofsOut, BlowfishECB.BLOCK_SIZE);
else this.bfe.Decrypt(this.block, 0, bufOut, ofsOut, BlowfishECB.BLOCK_SIZE);
ofsOut += BlowfishECB.BLOCK_SIZE;
outp += BlowfishECB.BLOCK_SIZE;
}
count -= BlowfishECB.BLOCK_SIZE;
// keep the last block as _ciphertext_ (for safety reasons)
Array.Copy(bufIn, ofsIn + count, this.block, 0, this.block.Length);
if (null == this.bfe) return outp + this.bfc.Decrypt(bufIn, ofsIn, bufOut, ofsOut, count);
else return outp + this.bfe.Decrypt(bufIn, ofsIn, bufOut, ofsOut, count);
}
}
/// <see cref="System.Security.Cryptography.ICryptoTransform.TransformFinalBlock"/>
public byte[] TransformFinalBlock(byte[] buf, int ofs, int count)
{
int resLen, rest, i;
byte pval;
byte[] tmp, result;
if (BlowfishECB.BLOCK_SIZE < count)
{
throw new CryptographicException(String.Format(Resources.BFALGO_UNEXPECTED_LAST_BLOCK_COUNT_1, count));
}
if (this.isEncryptor)
{
resLen = BlowfishECB.BLOCK_SIZE +
(BlowfishECB.BLOCK_SIZE == count ? BlowfishECB.BLOCK_SIZE : 0);
result = new byte[resLen];
if (PaddingMode.PKCS7 == PaddingValue)
{
pval = (byte)(resLen - count);
for (i = count; i < resLen; i++) result[i] = pval;
}
else if (PaddingMode.Zeros == PaddingValue)
{
for (i = count; i < resLen; i++) result[i] = 0;
}
else if (PaddingMode.ANSIX923 == PaddingValue)
{
for (i = count; i < resLen - 1; i++) result[i] = 0;
result[resLen - 1] = (byte)(resLen - count);
}
else if (PaddingMode.ISO10126 == PaddingValue)
{
RandomNumberGenerator.Create().GetBytes(result);
}
else
{
throw new CryptographicException(String.Format(Resources.BFALGO_UNKNOWN_PADDING_ENCRYPT_1, PaddingValue));
}
Array.Copy(buf, ofs, result, 0, count);
if (null == this.bfe) this.bfc.Encrypt(result, 0, result, 0, BlowfishECB.BLOCK_SIZE);
else this.bfe.Encrypt(result, 0, result, 0, BlowfishECB.BLOCK_SIZE);
}
else
{
if (0 == count)
{
if (null == (tmp = this.block))
{
// special case: nothing to do at all
return new byte[0];
}
}
else
{
if (null == this.bfe) this.bfc.Decrypt(this.block, 0, this.block, 0, BlowfishECB.BLOCK_SIZE);
else this.bfe.Decrypt(this.block, 0, this.block, 0, BlowfishECB.BLOCK_SIZE);
tmp = new byte[BlowfishECB.BLOCK_SIZE];
// NOTE: we use 'count', but only some padding schemes will really work if it is
// not aligned to the block size (but even then very likely produce garbage)
Array.Copy(buf, ofs, tmp, 0, count);
}
if (null == this.bfe) this.bfc.Decrypt(tmp, 0, tmp, 0, BlowfishECB.BLOCK_SIZE);
else this.bfe.Decrypt(tmp, 0, tmp, 0, BlowfishECB.BLOCK_SIZE);
// make sure the padding looks ok as far as we can tell
if (PaddingMode.PKCS7 == PaddingValue)
{
pval = tmp[tmp.Length - 1];
if (BlowfishECB.BLOCK_SIZE < (int)pval)
{
throw new CryptographicException(String.Format(Resources.BFALGO_INVALID_PADVAL_PKCS7_1, pval));
}
rest = tmp.Length - pval;
for (i = tmp.Length - 2; i >= rest; i--)
{
if (tmp[i] != pval)
{
throw new CryptographicException(String.Format(Resources.BFALGO_INVALID_PADDATA_PKCS7_2, pval, i));
}
}
}
else if (PaddingMode.Zeros == PaddingValue ||
PaddingMode.ISO10126 == PaddingValue)
{
// (there's no real way of telling, since the plaintext could be padding or vice versa)
rest = tmp.Length;
}
else if (PaddingMode.ANSIX923 == PaddingValue)
{
pval = tmp[tmp.Length - 1];
if (BlowfishECB.BLOCK_SIZE < pval)
{
throw new CryptographicException(String.Format(Resources.BFALGO_INVALID_PADVAL_ANSIX923_1, pval));
}
rest = tmp.Length - pval;
for (i = tmp.Length - 2; i >= rest; i--)
{
if (tmp[i] != 0)
{
throw new CryptographicException(String.Format(Resources.BFALGO_NONZERO_PADDATA_ANSIX923_2, pval, i));
}
}
}
else
{
throw new CryptographicException(String.Format(Resources.BFALGO_UNKNOWN_PADDING_DECRYPT_1, PaddingValue));
}
if (tmp == this.block)
{
result = new byte[rest];
Array.Copy(tmp, 0, result, 0, rest);
}
else
{
result = new byte[BlowfishECB.BLOCK_SIZE + rest];
Array.Copy(this.block, 0, result, 0, BlowfishECB.BLOCK_SIZE);
Array.Copy(tmp, 0, result, BlowfishECB.BLOCK_SIZE, rest);
}
}
return result;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -