📄 blowfishdemo.cs
字号:
/*
Copyright 2001-2007 Markus Hahn
All rights reserved. See documentation for license details.
*/
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using BlowfishNET;
using BlowfishNET.JavaInterop;
using BlowfishNET.Demo.Properties;
namespace BlowfishNET.Demo
{
/// <summary>Command line Blowfish.NET demonstration.</summary>
class Demo1
{
// We use on central random number generator for all the examples. In the
// real word we would rather use a secure random number random generator,
// e.g. the one in System.Security.Cryptography.RNGCryptoServiceProvider.
static RandomNumberGenerator _rng = RandomNumberGenerator.Create();
#region Show Basics
static void ShowBlowfishECB()
{
int i;
byte[] key, plain;
byte[] encrypted;
byte[] decrypted;
BlowfishECB bfe;
// Run the self test to make sure the implementation is fine.
if (!BlowfishECB.RunSelfTest())
{
System.Console.WriteLine(Resources.BFDEMO_SELFTEST_FAILED);
return;
}
else
{
System.Console.WriteLine(Resources.BFDEMO_SELFTEST_PASSED);
}
// Encrypt and decrypt an array of bytes. Motice that we create an
// aligned array for this, so we don't have to take care about
// padding here.
plain = new byte[BlowfishECB.BLOCK_SIZE * 100];
encrypted = new byte[plain.Length];
decrypted = new byte[plain.Length];
// They key gets generated out of random data, which is a common
// practice in the real world for dynamic purposes. Other methods are
// e.g. to hash down a password using SHA.
key = new byte[BlowfishECB.MAX_KEY_LENGTH];
_rng.GetBytes(key);
// Now we initialize a Blowfish ECB instance with this key.
bfe = new BlowfishECB(key, 0, key.Length);
// Check if this is a good key.
if (bfe.IsWeakKey)
{
Console.WriteLine(Resources.BFDEMO_WEAK_KEY_DETECTED);
}
// Generate "plaintext" data.
for (i = 0; i < plain.Length; i++)
{
plain[i] = (byte)i;
}
// Make sure that the output buffers are clean.
Array.Clear(encrypted, 0, encrypted.Length);
Array.Clear(decrypted, 0, decrypted.Length);
// Encrypt this data in one pass.
bfe.Encrypt(plain, 0, encrypted, 0, plain.Length);
// Actually not necessary, but just to demonstrate things, we reuse
// the already created instance with the same key.
bfe.Initialize(key, 0, key.Length);
// Decrypt the data.
bfe.Decrypt(encrypted, 0, decrypted, 0, encrypted.Length);
// Now compare that we actually got the right data back.
for (i = 0; i < plain.Length; i++)
{
if (plain[i] != decrypted[i])
{
// This should never happen.
Console.WriteLine(Resources.BFDEMO_DATAMISMATCH_1, i);
return;
}
}
Console.WriteLine(Resources.BFDEMO_ECB_DECRYPT_OK);
// Clean up the instance.
bfe.Invalidate();
}
static void ShowBlowfishCBC()
{
int i;
byte[] key, plain, iv;
byte[] encrypted;
byte[] decrypted;
BlowfishCBC bfc;
// Most of the code here is similar to the one in TestBlowfishECB(),
// yet we have to take care about managing the initialization vector
// (IV), so here we go and create our IV. It needs to be stored
// together with the encrypted data, since it's needed for decryption,
// as you can see below.
iv = new byte[BlowfishCBC.BLOCK_SIZE];
_rng.GetBytes(iv);
plain = new byte[BlowfishECB.BLOCK_SIZE * 100];
encrypted = new byte[plain.Length];
decrypted = new byte[plain.Length];
key = new byte[BlowfishECB.MAX_KEY_LENGTH];
_rng.GetBytes(key);
bfc = new BlowfishCBC(key, 0, key.Length);
for (i = 0; i < plain.Length; i++)
{
plain[i] = (byte)i;
}
Array.Clear(encrypted, 0, encrypted.Length);
Array.Clear(decrypted, 0, decrypted.Length);
// Before we can start the encryption we need to set our IV. If we
// don't do this then the resulting will be unpredictable.
bfc.IV = iv; // (the property _copies_ the content)
bfc.Encrypt(plain, 0, encrypted, 0, plain.Length);
// For decryption we have to do the same, so we set the IV back after
// we initialized the instance again. This time we use the setter
// method rather than the property.
bfc.Initialize(key, 0, key.Length);
bfc.SetIV(iv, 0);
// Just for demo purposes we use a clone of our actual instance.
bfc = (BlowfishCBC) bfc.Clone();
bfc.Decrypt(encrypted, 0, decrypted, 0, encrypted.Length);
for (i = 0; i < plain.Length; i++)
{
if (plain[i] != decrypted[i])
{
Console.WriteLine(Resources.BFDEMO_DATAMISMATCH_1, i);
return;
}
}
// You may ask when you ever want to _get_ the IV value. It might be
// necessary to do this to simply get a nice random value, but most of
// the time it is applied in advanced streaming solutions.
iv = bfc.IV; // (again this is a _copy_)
Console.WriteLine(Resources.BFDEMO_CBC_DECRYPT_OK);
bfc.Invalidate();
}
static void ShowBlowfishCFB()
{
// CFB is the most convenient mode when it comes to block ciphers,
// since there's no aligment work necessary, but just an
// initialization vector to store alongside with the encrypted
// data.
byte[] iv = new byte[BlowfishCFB.BLOCK_SIZE];
(new RNGCryptoServiceProvider()).GetBytes(iv);
// (use a "raw" key here, although hashing with a digest algorithm
// like SHA-256 is highly recommended)
byte[] key = Encoding.UTF8.GetBytes("some key that is");
BlowfishCFB bff = new BlowfishCFB(key, 0, key.Length);
bff.IV = iv;
byte[] plainText = Encoding.UTF8.GetBytes("This message was protected with Blowfish/CFB.");
byte[] cipherText = new byte[plainText.Length];
bff.Encrypt(plainText, 0, cipherText, 0, 11); // (in two steps, just for fun)
bff.Encrypt(plainText, 11, cipherText, 11, plainText.Length - 11);
bff = new BlowfishCFB(key, 0, key.Length);
bff.SetIV(iv, 0);
byte[] decryptedText = new byte[plainText.Length];
bff.Decrypt(cipherText, 0, decryptedText, 0, cipherText.Length);
Console.WriteLine(Encoding.UTF8.GetString(decryptedText));
bff.Invalidate();
}
#endregion
#region Show BlowfishSimple
static void ShowBlowfishSimple()
{
BlowfishSimple bfs;
String sPassw, sOrig, sEnc, sDec, sChkSum;
// show the most simple way to deal with BlowfishSimple
sPassw = "word";
bfs = new BlowfishSimple(sPassw);
sOrig = "it doesn't get easier than this, so use BlowfishSimple";
sEnc = bfs.Encrypt(sOrig);
Console.WriteLine(sEnc);
sDec = bfs.Decrypt(sEnc);
if (sDec != sOrig)
{
Console.WriteLine(Resources.BFDEMO_SIMPLE_FLAW);
}
// This demonstrates of how to verify a password with the secue key
// hash gathered out of the original password.
sChkSum = bfs.KeyChecksum;
Console.WriteLine(sChkSum);
if (BlowfishSimple.VerifyKey("not correct", sChkSum))
{
Console.WriteLine(Resources.BFDEMO_SIMPLE_UNEXPECTED_MATCH);
}
if (!BlowfishSimple.VerifyKey(sPassw, sChkSum))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -