密码算法
加密是用某种方法伪装消息以隐藏内容的过程,即是通过加密算法将明文转换为密文,相反解密是将密文转换为明文的过程。 加密又分为对称加密、非对称加密和哈希(散列函数)加密。
.Net Framework / .Net Standard 中提供了很多加密算法类,Fireasy 仅仅是将它们集中封装,使用 CryptographyFactory
类的 Create 方法获取相应的 ICryptoProvider
实例。ICryptoProvider
接口是所有加密算法的抽象,它提供加密解密的方法。
1、密码算法工厂
CryptographyFactory
类用于根据 CryptoAlgorithm
枚举或一个算法名称创建一个 ICryptoProvider
对象,如下所示:
[TestMethod]
public void TestCreateCryptor()
{
var md5 = CryptographyFactory.Create(CryptoAlgorithm.MD5);
var des = CryptographyFactory.Create("DES");
}
另外,CreateSymmetric、CreateAsymmetric 和 CreateHash 方法分别用于创建对称加密、非对称加密和散列哈希的实例,如果使用了非对应的密码算法,则会抛出 不支持 XXX 密码算法
的提示。
2、对称加密
常见的对称加密算法有:DES
、AES
、RC2
、RC4
、Rijndael
和 TripleDES
,对应的密码类为 SymmetricCrypt
。
SymmetricCrypto
类使用时需要指定密钥 CryptKey 和初始化向量 CryptIV,也可以使用默认的数据。各算法 CryptKey 和 CryptIV 的位数如下表:
算法 | CryptKey 位数 | CryptIV 位数 |
---|---|---|
DES、RC2、Rijndael | 8 | 8 |
AES | 8 | - |
TripleDES | 24 | 8 |
RC4 | 不限 | - |
对称加密与解密如下所示:
[TestMethod]
public void TestSymmetricCrypt()
{
var encrypt = CryptographyFactory.Create(CryptoAlgorithm.DES) as SymmetricCrypto;
//var encrypt = CryptographyFactory.CreateSymmetric(CryptoAlgorithm.DES);
encrypt.CryptKey = new byte[] { 34, 44, 56, 123, 34, 56, 78, 75 };
encrypt.CryptIV = new byte[] { 89, 35, 250, 56, 23, 67, 33, 45 };
var bytes = encrypt.Encrypt("fireasy", Encoding.Default);
Console.WriteLine(Encoding.Default.GetString(bytes));
var str = encrypt.Decrypt(bytes, Encoding.Default);
Console.WriteLine(str);
}
也可以使用 SetKey 方法指定一个字符串,该字符串将被转换成相应位数的 CryptKey 和 CryptIV,它会根据不同的密码算法进行截断或补齐,不建议使用该方法指定它们,除非加解密都使用 Fireasy 来完成。如下所示:
[TestMethod]
public void TestSymmetricCrypt()
{
var encrypt = CryptographyFactory.Create(CryptoAlgorithm.DES) as SymmetricCrypto;
//var encrypt = CryptographyFactory.CreateSymmetric(CryptoAlgorithm.DES);
encrypt.SetKey("faib studio");
var bytes = encrypt.Encrypt("fireasy", Encoding.Default);
Console.WriteLine(Encoding.Default.GetString(bytes));
var str = encrypt.Decrypt(bytes, Encoding.Default);
Console.WriteLine(str);
}
3、非对称加密
常见的对称加密算法有:DSA
和 RSA
,对应的密码类为 AsymmetricCrypto
。
AsymmetricCrypto
类使用时设定公钥 PublicKey 和私钥 PrivateKey 两个属性。如下所示:
[TestMethod]
public void TestAsymmetricCrypto()
{
var encrypt = CryptographyFactory.Create(CryptoAlgorithm.RSA) as AsymmetricCrypto;
//var encrypt = CryptographyFactory.CreateAsymmetric(CryptoAlgorithm.RSA);
encrypt.PublicKey = "<RSAKeyValue><Modulus>4UdQ4HttFv3wLdm5cQ8zU3u9YjMXVLsJkmG3E/60G7nxNMJ4gBLQiSGfj4ByKBR0Pvyk2HJ4PCVb3csHjgORjmzF2UeNQgu2SiqD1P+6nU1i2eugp4AxAJed91WRXn6dSb3vqTcwi+KaswcngR0/+YJ9szHi/VADsAQtORc3zBU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
encrypt.PrivateKey = "<RSAKeyValue><Modulus>4UdQ4HttFv3wLdm5cQ8zU3u9YjMXVLsJkmG3E/60G7nxNMJ4gBLQiSGfj4ByKBR0Pvyk2HJ4PCVb3csHjgORjmzF2UeNQgu2SiqD1P+6nU1i2eugp4AxAJed91WRXn6dSb3vqTcwi+KaswcngR0/+YJ9szHi/VADsAQtORc3zBU=</Modulus><Exponent>AQAB</Exponent><P>9YuKs6X7UU+rtQ0NFRAhr1KMbSe/k7L2OuKkNo9NpHUa3bubb2SY0sNACmLVgp7/wOcflSP1lJcH04J2P/gJHQ==</P><Q>6t7eKKSOZJIqWAQZDEr2SsGecKK3dM+1yMwKe78JfwhyQRdAq9rgblqyD4QvSpvn+mTZIlf+2cwgN+m6Pu5VWQ==</Q><DP>YiqUnDf6nspkUnDSTx5w6R/uhmFCxTDiIi6kCjAGkX5D7Gvpu4ITWwe2XbCfvaYFh8CfLsf+kZZECbp5vh9SvQ==</DP><DQ>uCgLVR7Br0WUAfMkmKjmOHNcAcDzy5lZVZn21lRR49MBktvij11M//oJB3WDhyJ7X69XOUB5yNfuoyiWKeXB8Q==</DQ><InverseQ>x9BzXYBzpw2chFdo+pyTDno5KuilsDGkMiwyqnIsb5eyu5XZm3B2hSpPyBmCzpIJE5z6PJRJiKtrpgEJ3unljw==</InverseQ><D>Xqxv6sc0I1N42mwDqOXwdgcsodZC2dL4xNHX9Mk3u+c63SdVKM2/YcIFonMihoGCEO5wAJ6qtOwmXWFzvVT2mBBsZSROl9VKQboWdjLyBb/q81pnR1skolrBVs913eOHxOdBXVl+yIuhOBr83MFsP/pshafnIS5hHoOF7CzHG8E=</D></RSAKeyValue>";
var bytes = encrypt.Encrypt("fireasy", Encoding.Default);
Console.WriteLine(Encoding.Default.GetString(bytes));
var str = encrypt.Decrypt(bytes, Encoding.Default);
Console.WriteLine(str);
}
PublicKey 和 PrivateKey 可以使用 GeneratePublicKey 和 GeneratePrivateKey 两个方法生成,注意它俩必须在同一个实例里生成。如下所示:
[TestMethod]
public void TestGenerateKeys()
{
var encrypt = CryptographyFactory.Create(CryptoAlgorithm.RSA) as AsymmetricCrypto;
//var encrypt = CryptographyFactory.CreateAsymmetric(CryptoAlgorithm.RSA);
var publicKey = encrypt.GeneratePublicKey();
var privateKey = encrypt.GeneratePrivateKey();
}
CreateSignature 和 VerifySignature 方法分别用于生成签名和验证签名,在使用之前,需要使用散列哈希函数生成数据。如下所示:
[TestMethod]
public void TestCreateAndVerifySignature()
{
var encrypt = CryptographyFactory.CreateAsymmetric(CryptoAlgorithm.RSA);
encrypt.PublicKey = encrypt.GeneratePublicKey();
encrypt.PrivateKey = encrypt.GeneratePrivateKey();
var sha1 = CryptographyFactory.CreateHash(CryptoAlgorithm.SHA1);
var bytes = sha1.Encrypt(Encoding.Default.GetBytes("fireasy"));
var signatures = encrypt.CreateSignature(bytes, "SHA1");
var verify = encrypt.VerifySignature(bytes, signatures, "SHA1");
Assert.IsTrue(verify);
}
4、散列哈希
常见的对称加密算法有:MD5
、SHA1
、SHA256
、SHA384
和 SHA512
,对应的密码类为 HashCrypto
。如下所示:
[TestMethod]
public void TestHashCrypt()
{
var encrypt = CryptographyFactory.Create(CryptoAlgorithm.MD5);
//var encrypt = CryptographyFactory.CreateHash(CryptoAlgorithm.MD5);
var bytes = encrypt.Encrypt("fireasy", Encoding.Default);
Console.WriteLine(Encoding.Default.GetString(bytes));
}
HashCrypto
类的 Decrypt 方法将抛出异常。