在前面的加密和解密方法,我们通过Rfc2898DeriveBytes获取密码、salt 值和迭代次数,然后通过调用GetBytes方法生成密钥。
现在我们已经完成了通用的对称加密算法我们只需一组加密和解密方法就可以随意的使用任意一种对称加密算法了而不是为每个加密和解密算法编写相应的加密和解密方法。非对称加密算法.NET Framework中提供四种非对称加密算法DSAECDiffieHellman ECDsa和RSA它们都继承于抽象类AsymmetricAlgorithm接下来我们将提供RSA算法的实现。RSA加密算法是一种非对称和双钥加密算法在公钥加密标准和电子商业中RSA被广泛使用。在双钥加密的情况下密钥有两把一把是公开的公钥还有一把是不公开的私钥。双钥加密的原理如下a) 公钥和私钥是一一对应的关系有一把公钥就必然有一把与之对应的、独一无二的私钥反之亦成立。b) 所有的公钥, 私钥对都是不同的。c) 用公钥可以解开私钥加密的信息反之亦成立。d) 同时生成公钥和私钥应该相对比较容易但是从公钥推算出私钥应该是很困难或者是不可能的。现在的数字签名加密主要是使用RSA算法什么是数字签名大家请点这里中文和这里英文。现在我们知道RSA算法是使用公钥和密钥进行加密和解密所以我们先定义一个方法来生成公钥和密钥。/// summary /// Generates the RSA public and private key. /// /summary /// param namealgorithmThe algorithm to creates key./param /// returns/returns public static void GenerateRSAKey(RSACryptoServiceProvider algorithm) { // Contains public and private key. RSAPrivateKey algorithm.ToXmlString(true); using (var streamWriter new StreamWriter(PublicPrivateKey.xml)) { streamWriter.Write(RSAPrivateKey); } // Only contains public key. RSAPubicKey algorithm.ToXmlString(false); using (var streamWriter new StreamWriter(PublicOnlyKey.xml)) { streamWriter.Write(RSAPubicKey); } }通过RSACryptoServiceProvider的ToXmlString()方法我们生成了一对公钥和密钥当参数为true 表示同时包含 RSA 公钥和私钥反之表示仅包含公钥。/// summary /// Encrypts with the specified RSA algorithm. /// /summary /// param namersaA RSA object./param /// param nameplainTextThe plain text to decrypt./param /// param namekeyThe key./param /// param nameencodingThe encoding./param /// returns/returns public static string Encrypt(RSACryptoServiceProvider rsa, string plainText, string key, Encoding encoding) { if (null rsa) throw new ArgumentNullException(rsa); if (String.IsNullOrEmpty(plainText)) throw new ArgumentNullException(plainText); if (String.IsNullOrEmpty(key)) throw new ArgumentNullException(key); if (null encoding) throw new ArgumentNullException(encoding); string publicKey; // Reads public key. using (var streamReader new StreamReader(PublicOnlyKey.xml)) { publicKey streamReader.ReadToEnd(); } rsa.FromXmlString(publicKey); byte[] cipherBytes rsa.Encrypt(plainText.ToBytesEncoding(encoding), true); rsa.Clear(); return cipherBytes.ToBase64String(); }接着我们定义RSA的加密方法首先我们从流中读取密钥和公钥然后传递给FromXmlString()方法最后对平文进行加密。/// summary /// Decrypts with the specified RSA algorithm. /// /summary /// param namersaa RSA object./param /// param namecipherTextThe cipher text to encrypt./param /// param namekeyThe key./param /// param nameencodingThe encoding./param /// returns/returns public static string Decrypt(RSACryptoServiceProvider rsa, string cipherText, string key, Encoding encoding) { string privateKey; // Reads the private key. using (var streamReader new StreamReader(PublicPrivateKey.xml)) { privateKey streamReader.ReadToEnd(); } rsa.FromXmlString(privateKey); byte[] plainBytes rsa.Decrypt(cipherText.FromBase64String(), true); rsa.Clear(); return plainBytes.FromByteToString(encoding); }参照加密方法我们很快的实现RSA的解密方法同样我们从流中读取密钥然后传递给FromXmlString()方法最后对密文进行解密注意调用的是RSA算法的Decrypt()方法在使用胶水代码时千万别忘记修改了。现在我们终于完成了通用的加密解密方法接下来肯定是要测试一下这些方法的效果如何这次我使用单元测试如果大家要参考应用程序效果可以点这里。[TestMethod] public void TestStart() { try { string cipherText; string plainText; #region Hash Algo cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateHashAlgoMd5(), 您们好Hello everyone.); Assert.IsTrue(CryptographyUtils.IsHashMatch( CryptographyUtils.CreateHashAlgoMd5(), cipherText, 您们好Hello everyone.)); cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateHashAlgoSHA1(), 您们好Hello everyone.); Assert.IsTrue(CryptographyUtils.IsHashMatch( CryptographyUtils.CreateHashAlgoSHA1(), cipherText, 您们好Hello everyone.)); #endregion #region Asymm Algo CryptographyUtils.GenerateRSAKey(CryptographyUtils.CreateAsymmAlgoRSA()); cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateAsymmAlgoRSA(), %dkJK.RusH, c579D-E?$)_); plainText CryptographyUtils.Decrypt( CryptographyUtils.CreateAsymmAlgoRSA(), cipherText, c579D-E?$)_); Assert.AreEqualstring(%dkJK.RusH, plainText); #endregion #region Symm Algo cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateSymmAlgoAes(), JK_huangJK_huangJK_huang黄钧航, JK_huangJK_huang, 256); plainText CryptographyUtils.Decrypt( CryptographyUtils.CreateSymmAlgoAes(), cipherText, JK_huangJK_huang, 256); Assert.AreEqualstring(JK_huangJK_huangJK_huang黄钧航, plainText); cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateSymmAlgoDES(), JK_huangJK_huangJK_huang黄钧航, JK_huangJK_huang, 64); plainText CryptographyUtils.Decrypt( CryptographyUtils.CreateSymmAlgoDES(), cipherText, JK_huangJK_huang, 64); Assert.AreEqualstring(JK_huangJK_huangJK_huang黄钧航, plainText); cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateSymmAlgoRC2(), JK_huangJK_huangJK_huang黄钧航, JK_huangJK_huang, 128); plainText CryptographyUtils.Decrypt(CryptographyUtils.CreateSymmAlgoRC2(), cipherText, JK_huangJK_huang, 128); Assert.AreEqualstring(JK_huangJK_huangJK_huang黄钧航, plainText); cipherText CryptographyUtils.Encrypt( CryptographyUtils.CreateSymmAlgoRijndael(), JK_huangJK_huangJK_huang黄钧航,