/// <summary> /// Purpose: To encrypt a raw byte buffer using the specified mode. The output is a raw byte buffer /// </summary> /// <param name="inBuffer"></param> /// <param name="iMode"></param> /// <returns></returns> public byte[] EncryptBuffer(byte[] inBuffer) { int inBufferSize = inBuffer.Length; if (inBufferSize == 0) return new byte[0]; // Since this is a block cypher algorithm, we have to encrypt full blocks of data so we // have to create a new buffer that is an even block size byte pad = 0; if (inBufferSize % 8 != 0) pad = (byte)(8 - (inBufferSize % 8)); else pad = 8; int internalBufferSize = inBufferSize + pad; byte[] internalBuffer = new byte[internalBufferSize]; // Set the pad bytes to the appropriate value for (int i = inBufferSize; i < internalBufferSize; i++) internalBuffer[i] = pad; byte[] outBuffer = new byte[internalBufferSize]; inBuffer.CopyTo(internalBuffer, 0); //Check the buffer's length - should be > 0 and multiple of 8 if ((internalBufferSize != 0) && (internalBufferSize % 8 == 0)) { switch (mode) { case Mode.CBC: BlowfishCBC bfCBC = new BlowfishCBC(key); bfCBC.Encrypt(internalBuffer, 0, outBuffer, 0, internalBuffer.Length); break; case Mode.ECB: BlowfishECB bfECB = new BlowfishECB(key); bfECB.Encrypt(internalBuffer, 0, outBuffer, 0, internalBuffer.Length); break; } } return outBuffer; }
////////////////////////////////////////////////////////////////////// /// <summary> /// Returns an identical, non-shallow copy of the current instance. /// This can be very useful if you need multiple instances all using /// the same key, since the expensive cipher setup will be bypassed. /// </summary> /// <returns> /// The new instance, which usually typecasted back. /// </returns> public object Clone() { BlowfishECB result; result = new BlowfishECB(); result.m_pbox = (uint[])this.m_pbox.Clone(); result.m_sbox1 = (uint[])this.m_sbox1.Clone(); result.m_sbox2 = (uint[])this.m_sbox2.Clone(); result.m_sbox3 = (uint[])this.m_sbox3.Clone(); result.m_sbox4 = (uint[])this.m_sbox4.Clone(); result.m_block = (byte[])this.m_block.Clone(); result.m_nIsWeakKey = this.m_nIsWeakKey; return result; }
/// <summary> /// Purpose: To decrypt an encrypted buffer using the specified mode /// </summary> /// <param name="inBuffer"></param> /// <param name="iMode"></param> /// <returns></returns> public byte[] DecryptBuffer(byte[] inBuffer) { int internalBufferSize = inBuffer.Length; if (internalBufferSize % 8 != 0) internalBufferSize += (8 - (internalBufferSize % 8)); byte[] internalBuffer = new byte[internalBufferSize]; inBuffer.CopyTo(internalBuffer, 0); byte[] outBuffer = new byte[internalBufferSize]; switch (mode) { case Mode.CBC: BlowfishCBC bfCBC = new BlowfishCBC(key); bfCBC.Decrypt(inBuffer, 0, outBuffer, 0, inBuffer.Length); break; case Mode.ECB: BlowfishECB bfECB = new BlowfishECB(key); bfECB.Decrypt(inBuffer, 0, outBuffer, 0, inBuffer.Length); break; } return outBuffer; }
/// <summary> /// Executes a selftest /// </summary> /// <remarks> /// Call this method to make sure that the instance is able to produce /// valid output according to the specification. /// </remarks> /// <returns> /// true: selftest passed / false: selftest failed /// </returns> public static bool RunSelfTest() { uint unHi, unLo; BlowfishECB bfe; unHi = TEST_VECTOR_PLAIN[0]; unLo = TEST_VECTOR_PLAIN[1]; bfe = new BlowfishECB(TEST_KEY, 0, TEST_KEY.Length); bfe.EncryptBlock(unHi, unLo, out unHi, out unLo); if ((TEST_VECTOR_CIPHER[0] != unHi) || (TEST_VECTOR_CIPHER[1] != unLo)) { return false; } bfe.DecryptBlock(unHi, unLo, out unHi, out unLo); if ((TEST_VECTOR_PLAIN[0] != unHi) || (TEST_VECTOR_PLAIN[1] != unLo)) { return false; } return true; }