internal BlowfishCryptography(BlowfishAlgorithm algorithm) { _algorithm = algorithm; _encryptIv = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; _decryptIv = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; bf_key_st key = new bf_key_st(); key.P = new UInt32[16 + 2]; key.S = new UInt32[4 * 256]; _key = Marshal.AllocHGlobal(key.P.Length * sizeof(UInt32) + key.S.Length * sizeof(UInt32)); Marshal.StructureToPtr(key, _key, false); _encryptNum = 0; _decryptNum = 0; }
public Blowfish(BlowfishAlgorithm algorithm) { _algorithm = algorithm; _encryptIv = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; _decryptIv = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; bf_key_st key = new bf_key_st(); key.P = new UInt32[16 + 2]; key.S = new UInt32[4 * 256]; _key = Marshal.AllocHGlobal(key.P.Length * sizeof(UInt32) + key.S.Length * sizeof(UInt32)); Marshal.StructureToPtr(key, _key, false); _encryptNum = 0; _decryptNum = 0; }
/// <summary>Creates a new Blowfish stream.</summary> /// <param name="stm">The stream to read or write to.</param> /// <param name="mode">Operation mode</param> /// <param name="key">The buffer with the key material.</param> /// <param name="ofs">Where the key material starts in the buffer.</param> /// <param name="len">Length of the key material in bytes.</param> public static BlowfishStream Create( Stream stm, BlowfishStreamMode mode, byte[] key, int ofs, int len) { SHA1 sha = new SHA1CryptoServiceProvider(); BlowfishAlgorithm balg = new BlowfishAlgorithm(); balg.Key = sha.ComputeHash(key, ofs, len); balg.Padding = PaddingMode.PKCS7; balg.Mode = CipherMode.CBC; sha.Clear(); if (BlowfishStreamMode.Write == mode) { byte[] iv = balg.IV; stm.Write(iv, 0, iv.Length); return(new BlowfishStream(stm, balg.CreateEncryptor(), CryptoStreamMode.Write)); } else { byte[] iv = new byte[balg.BlockSize >> 3]; for (int i = 0; i < iv.Length; i++) { int ivb = stm.ReadByte(); if (-1 == ivb) { throw new IOException(Resources.JAVAIOP_CANNOT_READ_IV); } iv[i] = (byte)ivb; } balg.IV = iv; return(new BlowfishStream(stm, balg.CreateDecryptor(), CryptoStreamMode.Read)); } }
static void Main(string[] args) { long lLen; int nRead, nReadTotal; byte[] buf = new byte[3]; byte[] encData; byte[] decData; SymmetricAlgorithm alg; MemoryStream sin; MemoryStream sout; CryptoStream encStream; CryptoStream decStream; // set up the algorithm (false to go with AES for comparison purposes) alg = MakeAlgo(true); // we encrypt and decrypt from and to memory stream, // so first we have to set up a source and a target int nI, nC = 11; sin = new MemoryStream(); for (nI = 0; nI < nC; nI++) { sin.WriteByte((byte)nI); } sin.Position = 0; sout = new MemoryStream(); // now we create a crypto stream, to show that the // BlowfishAlgorithm plays together with a standard // .NET framework security component encStream = new CryptoStream( sout, alg.CreateEncryptor(), CryptoStreamMode.Write); lLen = sin.Length; nReadTotal = 0; while (nReadTotal < lLen) { nRead = sin.Read(buf, 0, buf.Length); encStream.Write(buf, 0, nRead); nReadTotal += nRead; } encStream.Close(); // show what we got as the encrypted data encData = sout.ToArray(); Console.WriteLine("plain : " + BufToStr(sin.ToArray())); Console.WriteLine("encrypted: " + BufToStr(encData)); // reset the streams and do the decryption the same way sin = new MemoryStream(encData); sout = new MemoryStream(nC + Blowfish.BLOCKSIZE); decStream = new CryptoStream( sin, alg.CreateDecryptor(), CryptoStreamMode.Read); lLen = sin.Length; nReadTotal = 0; while (nReadTotal < lLen) { nRead = decStream.Read(buf, 0, buf.Length); if (0 == nRead) { break; } sout.Write(buf, 0, nRead); nReadTotal += nRead; } decStream.Close(); decData = sout.ToArray(); Console.WriteLine("decrypted: " + BufToStr(decData)); // (NOTE: eventually we get back padding bytes, which we ignore in our test here) for (nI = 0; nI < nC; nI++) { if (decData[nI] != nI) { Console.WriteLine("decryption error"); break; } } // last stage: (almost) futile weak key test search (10k attempts) byte[] testKey = new byte[alg.KeySize]; Random rnd = new Random((int)DateTime.Now.Ticks); Console.Write("searching for weak keys "); nC = 10000; for (nI = 0; nI < nC; nI++) { rnd.NextBytes(testKey); if (BlowfishAlgorithm.IsWeakKey(testKey)) { Console.WriteLine("\nweak key found after " + nI + " attempt(s)"); Console.WriteLine(BufToStr(testKey)); break; } else { if (0 == (nI % (nC / 10))) { Console.Write("."); } } } if (nC == nI) { Console.WriteLine("\nno weak key found."); } }