经过大量的研究,我能够使用.NET的实现这两种算法。据我所知,这段代码已经过测试,并且正在完美地工作。但我不知道它是否得到了很好的执行,我想听听别人的意见。如果知道它是否正确,那就太好了,因为它将供其他开发人员使用。在安全性和性能方面有什么改进吗?有什么想法吗?
public class BCEngine
{
private readonly Encoding _encoding;
private readonly IBlockCipher _blockCipher;
private PaddedBufferedBlockCipher _cipher;
private IBlockCipherPadding _padding;
public BCEngine()
{
}
BCEngine(IBlockCipher blockCipher, Encoding encoding)
{
_blockCipher = blockCipher;
_encoding = encoding;
}
#region Public Methods
public static string TwoFishEncryption(string TextPlain, string Password, byte[] Salt)
{
Sha3Digest Sha3Digest = new Sha3Digest();
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(Sha3Digest);
gen.Init(Encoding.UTF8.GetBytes(Password), Salt, 1000);
KeyParameter param = (KeyParameter)gen.GenerateDerivedParameters(new TwofishEngine().AlgorithmName, 256);
BCEngine bcEngine = new BCEngine(new TwofishEngine(), Encoding.UTF8);
bcEngine.SetPadding(new Pkcs7Padding());
return bcEngine.Encrypt(TextPlain, param);
}
public static string TwoFishDecryption(string TextEncripted, string Password, byte[] Salt)
{
Sha3Digest Sha3Digest = new Sha3Digest();
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(Sha3Digest);
gen.Init(Encoding.UTF8.GetBytes(Password), Salt, 1000);
KeyParameter param = (KeyParameter)gen.GenerateDerivedParameters(new TwofishEngine().AlgorithmName, 256);
BCEngine bcEngine = new BCEngine(new TwofishEngine(), Encoding.UTF8);
bcEngine.SetPadding(new Pkcs7Padding());
return bcEngine.Decrypt(TextEncripted, param);
}
#endregion
#region Private Methods
void SetPadding(IBlockCipherPadding padding)
{
if (padding != null)
_padding = padding;
}
string Encrypt(string plain, ICipherParameters SetKeyParameter)
{
byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(plain), SetKeyParameter);
return Convert.ToBase64String(result);
}
string Decrypt(string cipher, ICipherParameters SetKeyParameter)
{
byte[] result = BouncyCastleCrypto(false, Convert.FromBase64String(cipher), SetKeyParameter);
return _encoding.GetString(result, 0, result.Length);
}
byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, ICipherParameters SetKeyParameter)
{
try
{
_cipher = _padding == null ?
new PaddedBufferedBlockCipher(_blockCipher) : new PaddedBufferedBlockCipher(_blockCipher, _padding);
_cipher.Init(forEncrypt, SetKeyParameter);
byte[] ret = _cipher.DoFinal(input);
return ret;
}
catch (CryptoException ex)
{
// throw new CryptoException(ex);
}
return null;
}
#endregion
}发布于 2017-06-14 16:20:48
公共BCEngine() {} BCEngine(IBlockCipher blockCipher,编码){ _blockCipher = blockCipher;_encoding =编码;}
默认构造函数应该为另一个构造函数初始化的两个字段提供合理的默认值,但是等待.这两个构造函数都是无用的,因为所有公共API都是静态的。唯一的实例成员是私有方法。我可以创建一个BCEngine实例,但是我不能用它做任何事情。
BCEngine bcEngine =新BCEngine(新的TwofishEngine(),Encoding.UTF8);bcEngine.SetPadding(新的Pkcs7Padding());返回的bcEngine.Encrypt(TextPlain,param);
但是再等等..。实例化它以调用私有实例方法。这是非常不一致和混乱的。
您应该使所有事物都是静态的,或者是所有的东西都是实例。
如果一个实例使用私有静态方法作为帮助器,这是可以的,但反过来则有点奇怪。至少默认构造函数也应该是私有的。
但是,您的实现使用私有字段,其中两个字段不是只读的,所以您可以使用它们来存储某种状态,但幸运的是它们不是静态的。您应该删除这些字段,并将所需的参数从一个方法传递到另一个方法。然后您将不需要任何实例,方法将是纯正 <-- LINK。
您应该检查您的代码的一次性类型。我很肯定他们有很多。加密通常需要处理一些东西。
区域很少是必要的,对于成员分组来说,几乎从来没有必要。没有它们就更容易读懂代码。
发布于 2017-06-14 16:55:45
_padding没有设置为null。TwoFishEncryption & TwoFishDecryption似乎具有几乎相同的主体,考虑重构重复的代码,只需在末尾调用1行代码即可。发布于 2017-06-14 20:03:07
我已经根据反馈修改了代码,我希望它有所改进。我接受更多的建议!感谢所有帮助我的人!
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
using Org.Cerberus.Utils;
using System;
using System.Text;
namespace BCEngine
{
public class BCEngineCore
{
Encoding _encoding;
IBlockCipher _blockCipher;
private PaddedBufferedBlockCipher _cipher;
private IBlockCipherPadding _padding;
KeyParameter KeyParameter;
#region Public Methods
public string TwoFishEncryption(string TextPlain, string Password, byte[] Salt, string Prefix = "")
{
TwoFish(TextPlain, Password, Salt, Prefix);
return Encrypt(TextPlain, KeyParameter);
}
public string TwoFishDecryption(string TextEncripted, string Password, byte[] Salt, string Prefix = "")
{
TwoFish(TextEncripted, Password, Salt, Prefix);
return Decrypt(TextEncripted, KeyParameter);
}
#endregion
#region Private Methods
void TwoFish(string TextPlain, string Password, byte[] Salt, string Prefix = "")
{
Sha3Digest Sha3Digest = new Sha3Digest((int)KeySizes.F256);
Pkcs5S2ParametersGenerator gen = new Pkcs5S2ParametersGenerator(Sha3Digest);
gen.Init(Encoding.UTF8.GetBytes(Password), Salt.PreFixSaltBytes(Prefix), Constants.NUM_ITERATOR);
KeyParameter = (KeyParameter)gen.GenerateDerivedParameters(BCEngines.TwofishEngine.AlgorithmName, 256);
SetPadding(new Pkcs7Padding());
SetBlockCipher(BCEngines.TwofishEngine);
SetEncoding(Encoding.UTF8);
}
void SetPadding(IBlockCipherPadding padding)
{
if (padding != null)
_padding = padding;
else
throw new NullReferenceException("Padding is null!");
}
void SetBlockCipher(IBlockCipher blockCipher)
{
if (blockCipher != null)
_blockCipher = blockCipher;
else
throw new NullReferenceException("BlockCipher is null!");
}
void SetEncoding(Encoding encoding)
{
if (encoding != null)
_encoding = encoding;
else
throw new NullReferenceException("Encoding is null!");
}
string Encrypt(string plain, ICipherParameters SetKeyParameter)
{
byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(plain), SetKeyParameter);
return Convert.ToBase64String(result);
}
string Decrypt(string cipher, ICipherParameters SetKeyParameter)
{
byte[] result = BouncyCastleCrypto(false, Convert.FromBase64String(cipher), SetKeyParameter);
return _encoding.GetString(result, 0, result.Length);
}
byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, ICipherParameters SetKeyParameter)
{
try
{
_cipher = _padding == null
? new PaddedBufferedBlockCipher(_blockCipher)
: new PaddedBufferedBlockCipher(_blockCipher, _padding);
_cipher.Init(forEncrypt, SetKeyParameter);
byte[] ret = _cipher.DoFinal(input);
return ret;
}
catch (CryptoException ex)
{
// throw new CryptoException(ex);
}
return null;
}
#endregion
}
public sealed class BCEngine
{
private static BCEngineCore instance;
private BCEngine() { }
public static BCEngineCore Instance
{
get
{
if (instance == null)
instance = new BCEngineCore();
return instance;
}
}
}
}https://codereview.stackexchange.com/questions/165776
复制相似问题