这个想法是生成实用程序类,因此每当这些人破解当前已知的最佳算法并且新的算法进入市场时,开发人员必须做的唯一想法是添加NewHighTechEncryptingAlgorithm_Encryptor类并更改全局应用程序设置NewHighTechEncryptingAlgorithm_As_String
这样就可以了 string myNewEncryptedString = Encryptor.Encrypt(StringToEncrypt,strAlgorithmName)
编辑:我删除了旧代码并粘贴了答案,由rwwilden提供了调用代码
我认为正确的措辞是“Enhashing”反对“加密”,因为这里没有盐...这似乎是根据提议的“规范”的最佳解决方案
using System;
using System.Text;
using System.Security.Cryptography;
namespace GenApp.Utils.Security
{
/// <summary>
/// Summary description for Encrypter
/// </summary>
public class Encrypter
{
/// <summary>
/// Encrypts according to the passed plain name for hasing algorithm
/// see CryptoConfig class from MSDN for more details
/// </summary>
/// <param name="strPlainTxt">the plain text to encrypt</param>
/// <param name="strAlgorithmName">The plain name of the hashing algorithm </param>
/// <returns> the encrypted string </returns>
public static string Encrypt ( string strPlainTxt, string strAlgorithmName )
{
string strHashedTxt = String.Empty;
byte[] bytPlain = System.Text.Encoding.UTF8.GetBytes ( strPlainTxt );
using (HashAlgorithm objAlgorithm = HashAlgorithm.Create ( strAlgorithmName ))
{
byte[] bytHash = objAlgorithm.ComputeHash ( bytPlain );
strHashedTxt = Convert.ToBase64String ( bytHash );
return strHashedTxt;
}
} //eof method
///// OLD CODE - REQUIRES RECODING
///// <summary>
///// Encrypts according to the passed plain name for hasing algorithm
///// see CryptoConfig class from MSDN for more details
///// </summary>
///// <param name="strPlainTxt">the plain text to encrypt</param>
///// <param name="strAlgorithmName">The plain name of the hashing algorithm </param>
///// <returns> the encrypted string </returns>
//public static string Encrypt ( string strPlainTxt, string strAlgorithmName )
//{
// string strHashedTxt = String.Empty;
// byte[] bytPlains = System.Text.Encoding.UTF8.GetBytes ( strPlainTxt );
// byte[] bytHash;
// //CryptoConfig objCryptoConfig = new CryptoConfig ();
// switch (strAlgorithmName)
// {
// case "SHA1":
// SHA1CryptoServiceProvider objProvForSHA1alg =
// (SHA1CryptoServiceProvider)CryptoConfig.CreateFromName ( strAlgorithmName );
// bytHash = objProvForSHA1alg.ComputeHash ( bytPlains );
// objProvForSHA1alg.Clear ();
// strHashedTxt = Convert.ToBase64String ( bytHash );
// break;
// case "MD5" :
// MD5CryptoServiceProvider objProvForMD5alg =
// (MD5CryptoServiceProvider)CryptoConfig.CreateFromName ( strAlgorithmName );
// bytHash = objProvForMD5alg.ComputeHash ( bytPlains );
// strHashedTxt = Convert.ToBase64String ( bytHash );
// objProvForMD5alg.Clear ();
// break;
// } //eof switch
// if (String.IsNullOrEmpty ( strHashedTxt ))
// throw new Exception ( "Encryption provider called by invalide simple name " );
// return strHashedTxt;
//} //eof method
} //eof class
class Program
{
static void Main ( string[] args )
{
string strPlainTxt = "UnEncryptedText";
string strAlgorithmName = "SHA1"; //the type of al
string strHashedTxt = String.Empty;
//START WITH ONE ALGORITHM
Console.WriteLine ( "Using the " + strAlgorithmName + " START " );
Console.WriteLine ( "The plain text is " + strPlainTxt );
Console.WriteLine ( "The encrypting algorithm is " + strAlgorithmName );
strHashedTxt = Encrypter.Encrypt ( strPlainTxt, strAlgorithmName );
Console.WriteLine ( "The hashed text is " + strHashedTxt );
Console.WriteLine ( "Using the " + strAlgorithmName + " END " );
//NOW CHANGE THE ALGORITHM
strAlgorithmName = "MD5";
Console.WriteLine ( "Using the " + strAlgorithmName + " START " );
Console.WriteLine ( "The plain text is " + strPlainTxt );
Console.WriteLine ( "The encrypting algorithm is " + strAlgorithmName );
strHashedTxt = Encrypter.Encrypt ( strPlainTxt, strAlgorithmName );
Console.WriteLine ( "The hashed text is " + strHashedTxt );
Console.WriteLine ( "Using the " + strAlgorithmName + " END " );
strAlgorithmName = "SHA256";
Console.WriteLine ( "Using the " + strAlgorithmName + " START " );
Console.WriteLine ( "The plain text is " + strPlainTxt );
Console.WriteLine ( "The encrypting algorithm is " + strAlgorithmName );
strHashedTxt = Encrypter.Encrypt ( strPlainTxt, strAlgorithmName );
Console.WriteLine ( "The hashed text is " + strHashedTxt );
Console.WriteLine ( "Using the " + strAlgorithmName + " END " );
Console.WriteLine ( "Hit enter to exit" );
Console.ReadLine ();
}
}
} //eof namespace
答案 0 :(得分:2)
你应该看一下CryptoConfig课程。特别是方法CreateFromName。它提供了一种基于名称(您在配置中提供)获取加密算法的方法。更改配置中的名称会自动更改使用的算法。
如果您已选择是使用对称加密还是非对称加密,则应使用更具体的SymmetricAlgorithm.Create(string)或AsymmetricAlgorithm.Create(string)方法。
由于您需要散列解决方案,因此应使用HashAlgorithm.Create(string)。实现它的原因如下所示,当您决定使用其他哈希算法时,您不必更改任何代码。在您的代码中,您必须添加另一个case
语句。
public static string Encrypt(string toEncrypt, string algorithmName)
{
byte[] bytePlain = System.Text.Encoding.UTF8.GetBytes ( strPlainTxt );
using (HashAlgorithm algorithm = HashAlgorithm.Create(algorithm))
{
byte[] byteHash = algorithm.ComputeHash(bytePlain);
string strHashedTxt = Convert.ToBase64String (byteHash);
return strHashedTxt;
}
}
答案 1 :(得分:2)
我建议使用Resharper或Coderush的副本来修复编码器失明的问题。大括号突出显示在框中。
此外,这是经典或基本的接口+工厂模式。正如其他人所说,MEF和ICryptoTransform很可能是最干净的起点,因为框架为您提供,但如果您想了解基础知识:
制作界面:
public interface IEncrypter {
string Encrypt(string plaintext);
}
然后实施它:
public class MD5Encrypter : IEncrypter {
public string Encrypt(string plaintext) {
//code goes here.
}
}
public class SHA1Encrypter : IEncrypter {
public string Encrypt(string plaintext) {
//code goes here.
}
}
然后,建立工厂:
public class EncryptionFactory {
public static IEncrypter GetEncrypter() {
//work out which one to return, maybe based on a config value?
// I'm just going to return an MD5, but you'd want to use a switch statement etc
// to decide which one to return.
return new MD5Encrypter();
}
}
并像这样使用它:
IEncrypter encrypter = EncryptionFactory.GetEncrypter();
string garbageText = encrypter.Encrypt("Hello, world");
你改变的只是工厂,或者更好的是,工厂读入的配置,使其使用其他东西。如果你真的想要的话,你可以把它放在一天中的时间:)你编写的使用接口的代码并不关心对象实际上是什么 - 它只关心它有一个:string Encrypt(string)方法。
MEF在某些方面为你做这件事。
使用接口还意味着你可以返回一个假的IEncrypter,它什么都不做,所以你可以针对它编写单元测试,而不需要实际进行加密。在这种情况下不是超级有用,但总的来说这是很好的做法。
另外,您可以在Factory中使用@rwwilden的建议来生成它 - 您从config读取一个字符串,并使用他正在讨论的Asymetric / Symetric创建方法来创建底层类.....
答案 2 :(得分:1)
//eof class
和//eof namespace
垃圾箱有什么意义?
为了记录:你想要实现的基本上是一个有限的插件架构。请参阅MEF了解如何做到这一点。
顺便说一下,你知道ICryptoTransform吗?