密码算法
加密是用某种方法伪装消息以隐藏内容的过程,即是通过加密算法将明文转换为密文,相反解密是将密文转换为明文的过程。 加密又分为对称加密、非对称加密和哈希(散列函数)加密。
.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 方法将抛出异常。