The NCiphers.Crypto library offers very simple interface for performing Blowfish encryption and decryption from C# and VB.NET.
- Introduction to Blowfish
- Padding and Block modes
- Encrypting and Decrypting a String
- Encrypting and Decrypting a File
- Encrypting and Decrypting a Stream
- Encrypting and Decrypting a Byte array
- Exception handling
Introduction to Blowfish
The Blowfish encryption is a symmetric cipher and uses the same key for encryption and decryption. The Blowfish algorithm accepts keys from 4 bytes (32 bits) up to 56 bytes (448 bits).
The methods provided by the library accept also a string password instead of a key, which is internally converted to a key with a chosen Hash function.
The optional initialization vector (IV) size is 8 bytes long, which is also the block size of the algorithm. This is summarized in the table below:
Key size (min) | Key size (max) |
4 bytes (32 bits) | 56 bytes (448 bits) |
IV size: 8 bytes |
Padding and Block modes
The Padding and Block mode are important settings for the Blowfish class, that affect the produced encrypted output.
The Padding is used to align the input data to the algorithm BlockSize (8 bytes). The default is PKCS7.
The Block Mode determines what transformation is performed on each processed block. The default one is CBC. It is very important to know what block mode was used for encryption, in order to be able to decrypt it! For example if we know that the encryption has used CTR block mode, we shall set the class to use that mode before decrypting:
Blowfish Blowfish = new Blowfish(); Blowfish.Mode = CipherBlockMode.CTR; Blowfish.Decrypt...
Blowfish encrypting and decrypting a String
The example below shows how to Blowfish encrypt and decrypt a String with a byte array key, with a password and by using or not the optional initialization vector (IV).
C# example
using System; using System.IO; using NCiphers.Ciphers; class Blowfish_Demo { public static void Main(string[] args) { Blowfish Blowfish = new Blowfish(); // 16 bytes long key for Blowfish bit encryption byte[] key = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230}; // optional 8 byte long initialization vector byte[] IV = {150, 9, 112, 39, 32, 5, 136, 289}; string message = "Hello World"; // encrypt with a key only string encryptedMessage = Blowfish.EncryptString(message, key); // encrypt with a key and IV string encryptedMessageWithIV = Blowfish.EncryptString(message, key, IV); // encrypt with a password string encryptedMessageWithPassword = Blowfish.EncryptString(message, "my password"); // encrypt with a password and IV string encryptedMessageWithPasswordAndIV = Blowfish.EncryptString(message, "my password", IV); message = Blowfish.DecryptString(encryptedMessage, key); message = Blowfish.DecryptString(encryptedMessageWithIV, key, IV); message = Blowfish.DecryptString(encryptedMessageWithPassword, "my password"); message = Blowfish.DecryptString(encryptedMessageWithPasswordAndIV, "my password", IV); } }
VB.NET Example
Imports System Imports System.IO Imports NCiphers.Ciphers Class Blowfish_Demo Public Shared Sub Execute() Dim Blowfish As New Blowfish() ' 16 bytes long key for Blowfish bit encryption Dim key As Byte() = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230} ' the 8 byte initialization vector is optional and can be skipped Dim IV As Byte() = {150, 9, 112, 39, 32, 5, 136, 289} Dim message As String = "Hello World" Dim encryptedMessage As String = Blowfish.EncryptString(message, key) Dim encryptedMessageWithIV As String = Blowfish.EncryptString(message, key, IV) Dim encryptedMessageWithPassword As String = Blowfish.EncryptString(message, "my password") Dim encryptedMessageWithPasswordAndIV As String = Blowfish.EncryptString(message, "my password", IV) message = Blowfish.DecryptString(encryptedMessage, key) message = Blowfish.DecryptString(encryptedMessageWithIV, key, IV) message = Blowfish.DecryptString(encryptedMessageWithPassword, "my password") message = Blowfish.DecryptString(encryptedMessageWithPasswordAndIV, "my password", IV) End Sub End Class
Encrypting and Decrypting a File
The file encryption is performed by calling the methods Blowfish.EncryptFile. The decryption is through the DecryptFile methods respectively:
C# example
using System; using System.IO; using NCiphers.Ciphers; class Blowfish_Demo { public static void Main(string[] args) { Blowfish Blowfish = new Blowfish(); // 16 bytes long key for Blowfish-128 bit encryption byte[] key = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230}; // the initialization vector is optional and can be skipped byte[] IV = {150, 9, 112, 39, 32, 5, 136, 289}; // Blowfish Encrypting Blowfish.EncryptFile(new FileInfo(@"Data\SampleFile.txt"), new FileInfo(@"Data\EncryptedFile.Blowfish"), key); Blowfish.EncryptFile(new FileInfo(@"Data\SampleFile.txt"), new FileInfo(@"Data\EncryptedFileWithIV.Blowfish"), key, IV); Blowfish.EncryptFile(new FileInfo(@"Data\SampleFile.txt"), new FileInfo(@"Data\EncryptedFileWithPassword.Blowfish"), "my password"); Blowfish.EncryptFile(new FileInfo(@"Data\SampleFile.txt"), new FileInfo(@"Data\EncryptedFileWithPasswordAndIV.Blowfish"), "my password", IV); // Blowfish Decrypting Blowfish.DecryptFile(new FileInfo(@"Data\EncryptedFile.Blowfish"), new FileInfo(@"Data\Output.txt"), key); Blowfish.DecryptFile(new FileInfo(@"Data\EncryptedFileWithIV.Blowfish"), new FileInfo(@"Data\Output.txt"), key, IV); Blowfish.DecryptFile(new FileInfo(@"Data\EncryptedFileWithPassword.Blowfish"), new FileInfo(@"Data\Output.txt"), "my password"); Blowfish.DecryptFile(new FileInfo(@"Data\EncryptedFileWithPasswordAndIV.Blowfish"), new FileInfo(@"Data\Output.txt"), "my password", IV); } }
VB.NET example
Imports System Imports System.IO Imports NCiphers.Ciphers Class Blowfish_Demo Public Shared Sub Execute() Dim Blowfish As New Blowfish() ' 16 bytes long key for Blowfish-128 bit encryption Dim key As Byte() = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230} ' the 8 byte initialization vector is optional Dim IV As Byte() = {150, 9, 112, 39, 32, 5, 136, 289} ' Blowfish encrypting Blowfish.EncryptFile(New FileInfo("Data\SampleFile.txt"), New FileInfo("Data\EncryptedFile.Blowfish"), key) Blowfish.EncryptFile(New FileInfo("Data\SampleFile.txt"), New FileInfo("Data\EncryptedWithIV.Blowfish"), key) Blowfish.EncryptFile(New FileInfo("Data\SampleFile.txt"), New FileInfo("Data\EncryptedWithPassword.Blowfish"), key) Blowfish.EncryptFile(New FileInfo("Data\SampleFile.txt"), New FileInfo("Data\EncryptedWithPasswordAndIV.Blowfish"), key) ' Blowfish decrypting Blowfish.DecryptFile(New FileInfo("Data\EncryptedFile.Blowfish"), New FileInfo("Data\Output.txt"), key) Blowfish.DecryptFile(New FileInfo("Data\EncryptedWithIV.Blowfish"), New FileInfo("Data\Output.txt"), key) Blowfish.DecryptFile(New FileInfo("Data\EncryptedWithPassword.Blowfish"), New FileInfo("Data\Output.txt"), key) Blowfish.DecryptFile(New FileInfo("Data\EncryptedWithPasswordAndIV.Blowfish"), New FileInfo("Data\Output.txt"), key) End Sub End Class
Blowfish Encrypting and decrypting a Stream
The Stream encryption is performed by reading the data from a Stream opened for reading and writing the encrypted output to a Stream that accepts write operations. After the method execution, the output Stream Position will be at the end of the encrypted data.
C# code
using System; using System.IO; using NCiphers.Ciphers; class Blowfish_Demo { public static void Main(string[] args) { Blowfish Blowfish = new Blowfish(); // 16 bytes long key for Blowfish-128 bit encryption byte[] key = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230}; // optional 8 bytes long initialization vector byte[] IV = {150, 9, 112, 39, 32, 5, 136, 289}; using (Stream dataStream = File.OpenRead(@"Data\SampleFile.txt")) using (Stream encryptedStream = File.Create(@"Data\SampleFile.Blowfish")) { Blowfish.EncryptStream(dataStream, encryptedStream, key, IV); } Stream decryptedStream = new MemoryStream(); using (Stream encryptedStream = File.OpenRead(@"Data\SampleFile.Blowfish")) { Blowfish.DecryptStream(encryptedStream, decryptedStream, key, IV); } // the output stream Position must be reset in order to read the decrypted data afterwards decryptedStream.Position = 0; } }
VB.NET code
Imports System Imports System.IO Imports NCiphers.Ciphers Class Blowfish_Demo Public Shared Sub Execute() Dim Blowfish As New Blowfish() ' 16 bytes long key for Blowfish-128 bit encryption Dim key As Byte() = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230} ' optional 8 bytes long initialization vector Dim IV As Byte() = {150, 9, 112, 39, 32, 5, 136, 289} Using dataStream As Stream = File.OpenRead("Data\SampleFile.txt") Using encryptedStream As Stream = File.Create("Data\SampleFile.Blowfish") Blowfish.EncryptStream(dataStream, encryptedStream, key, IV) End Using End Using Dim decryptedStream As New MemoryStream() Using encryptedStream As Stream = File.OpenRead("Data\SampleFile.Blowfish") Using Blowfish.DecryptStream(encryptedStream, decryptedStream, key, IV) End Using End Using ' the output stream Position must be reset in order to read the decrypted data afterwards decryptedStream.Position = 0 End Sub End Class
Encrypting and Decrypting a Byte array
The EncryptBytes and DecryptBytes methods accept byte array as input and return the output as byte array. The example below demonstrates the four possibilities for Blowfish key and initialization vector (IV) offered by the library:
C# example
using System; using System.IO; using NCiphers.Ciphers; class Blowfish_Demo { public static void Main(string[] args) { Blowfish Blowfish = new Blowfish(); // 16 bytes long key for Blowfish-128 bit encryption byte[] key = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230}; // optional 8 bytes long initialization vector byte[] IV = {150, 9, 112, 39, 32, 5, 136, 289}; byte[] data = {150, 9, 112, 39, 32, 5, 136, 289, 251, 43, 44, 191, 217, 236, 3, 106}; byte[] encryptedBytes = Blowfish.EncryptBytes(data, key); byte[] encryptedBytesWithIV = Blowfish.EncryptBytes(data, key, IV); byte[] encryptedBytesWithPassword = Blowfish.EncryptBytes(data, "my password"); byte[] encryptedBytesWithPasswordAndIV = Blowfish.EncryptBytes(data, "my password", IV); byte[] decryptedBytes = Blowfish.DecryptBytes(encryptedBytes, key); decryptedBytes = Blowfish.DecryptBytes(encryptedBytesWithIV, key, IV); decryptedBytes = Blowfish.DecryptBytes(encryptedBytesWithPassword, "my password"); decryptedBytes = Blowfish.DecryptBytes(encryptedBytesWithPasswordAndIV, "my password", IV); } }
VB.NET example
Imports System Imports System.IO Imports NCiphers.Ciphers Class Blowfish_Demo Public Shared Sub Main(args As String()) Dim Blowfish As New Blowfish() ' 16 bytes long key for Blowfish-128 bit encryption Dim key As Byte() = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230} ' optional 8 bytes long initialization vector Dim IV As Byte() = {150, 9, 112, 39, 32, 5, 136, 289} Dim data As Byte() = {150, 9, 112, 39, 32, 5, 136, 289, 251, 43, 44, 191, 217, 236, 3, 106} Dim encryptedBytes As Byte() = Blowfish.EncryptBytes(data, key) Dim encryptedBytesWithIV As Byte() = Blowfish.EncryptBytes(data, key, IV) Dim encryptedBytesWithPassword As Byte() = Blowfish.EncryptBytes(data, "my password") Dim encryptedBytesWithPasswordAndIV As Byte() = Blowfish.EncryptBytes(data, "my password", IV) Dim decryptedBytes As Byte() = Blowfish.DecryptBytes(encryptedBytes, key) decryptedBytes = Blowfish.DecryptBytes(encryptedBytesWithIV, key, IV) decryptedBytes = Blowfish.DecryptBytes(encryptedBytesWithPassword, "my password") decryptedBytes = Blowfish.DecryptBytes(encryptedBytesWithPasswordAndIV, "my password", IV) End Sub End Class
Exception handling
During the Blowfish encryption and decryption operations errors can appear. In order to handle them more gracefully, the library offers a set of typed exceptions that can help us identify the cause of the error.
Below is an example class that demonstrates the various exceptions that can be expected during encryption and decryption. The methods that deal with files and streams of course may also throw System.IO.IOException sub classes:
C# code
using System; using System.IO; using NCiphers.Ciphers; class Blowfish_Exceptions { public static void Main(string[] args) { Blowfish Blowfish = new Blowfish(); // 16 bytes long key for Blowfish bit encryption byte[] key = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230}; try { Blowfish.EncryptFile(new FileInfo(@"Data\SampleFile.txt"), new FileInfo(@"Data\EncryptedFile.Blowfish"), key); } catch (System.ArgumentException) { Console.WriteLine("key size doesn't match algorithm or IV doesn't match the BlockSize"); } catch (NCiphers.Exceptions.DataException) { if (Blowfish.Padding.Equals(CipherPaddingMode.NoPadding)) { Console.WriteLine("input size not BlockSize aligned"); } else { Console.WriteLine("this should never happen"); } } catch (System.IO.IOException) { Console.WriteLine("I/O error"); } try { Blowfish.DecryptFile(new FileInfo(@"Data\EncryptedFile.Blowfish"), new FileInfo(@"Data\Output.txt"), key); } catch (System.ArgumentException) { Console.WriteLine("key size doesn't match algorithm or IV doesn't match the BlockSize"); } catch (NCiphers.Exceptions.CipherException) { Console.WriteLine("wrong key or password was supplied for decryption"); Console.WriteLine("or different CipherBlockMode (property Blowfish.Mode) was used for encryption"); } catch (NCiphers.Exceptions.DataException) { Console.WriteLine("encrypted input is corrupted"); } catch (System.IO.IOException) { Console.WriteLine("I/O error"); } } }
VB.NET code
Imports System Imports System.IO Imports NCiphers.Ciphers Class Blowfish_Exceptions Public Shared Sub Main(args As String()) Dim Blowfish As New Blowfish() ' 16 bytes long key for Blowfish encryption Dim key As Byte() = {50, 199, 10, 159, 132, 55, 236, 189, 51, 243, 244, 91, 17, 136, 39, 230} Try Blowfish.EncryptFile(New FileInfo("Data\SampleFile.txt"), New FileInfo("Data\EncryptedFile.Blowfish"), key) Catch generatedExceptionName As System.ArgumentException Console.WriteLine("key size doesn't match algorithm or IV doesn't match the BlockSize") Catch generatedExceptionName As NCiphers.Exceptions.DataException If Blowfish.Padding.Equals(CipherPaddingMode.NoPadding) Then Console.WriteLine("input size not BlockSize aligned") Else Console.WriteLine("this should never happen") End If Catch generatedExceptionName As System.IO.IOException Console.WriteLine("I/O error") End Try Try Blowfish.DecryptFile(New FileInfo("Data\EncryptedFile.Blowfish"), New FileInfo("Data\Output.txt"), key) Catch generatedExceptionName As System.ArgumentException Console.WriteLine("key size doesn't match algorithm or IV doesn't match the BlockSize") Catch generatedExceptionName As NCiphers.Exceptions.CipherException Console.WriteLine("wrong key or password was supplied for decryption") Console.WriteLine("or different CipherBlockMode (property Blowfish.Mode) was used for encryption") Catch generatedExceptionName As NCiphers.Exceptions.DataException Console.WriteLine("encrypted input is corrupted") Catch generatedExceptionName As System.IO.IOException Console.WriteLine("I/O error") End Try End Sub End Class
Summary
This chapter illustrated how to perform Blowfish encryption and decryption with the help of NCiphers.Crypto library.