原文链接:转载请注明出处
C#里的一些加密解密标准函数示例——DES,SHA1,RSA
最近收到了很多朋友的来信说希望提供DES的C#代码,但是我个人认为,.NET 提供了很多标准函数,没有必要自己写,所以我也只发布了C++的代码,如果大家一定要熟悉加密过程的话,也可以自己动手实现整个过程,这个可以参考我博客里的DES 算法介绍,和yxyDES2 Class的代码,代码注释相当的清楚。
.NET 提供了很多标准加密、解密函数,我简要介绍一下DES,SHA1,RSA的标准函数的使用。如果你想做一个网络安全模块,只需将三种算法结合起来设计一个模型,我相信可以实现很多复杂的功能。
示例本身并不复杂,我也不做过多解释,我也学Linus Torvalds一样吼一句:"Read the f**ing code”,哈哈,开个玩笑,我相信大家肯定能看懂。
注:以下示例需引用命名空间 : using System.Security.Cryptography;
一. DES 加密、解密
我相信一下注释相当清楚了,加上我博客里关于DES的文章确实不少,所以DES不做任何解释,怎么调用就更不用解释了吧,呵呵:
// 默认密钥向量 private byte [] Keys = { 0xEF , 0xAB , 0x56 , 0x78 , 0x90 , 0x34 , 0xCD , 0x12 }; /// <summary> /// DES加密字符串 /// </summary> /// <param name="encryptString"> 待加密的字符串 </param> /// <param name="encryptKey"> 加密密钥,要求为8位 </param> /// <returns> 加密成功返回加密后的字符串,失败返回源串 </returns> public string EncryptDES( string encryptString, string encryptKey) { try { byte [] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring( 0 , 8 )); byte [] rgbIV = Keys; byte [] inputByteArray = Encoding.UTF8.GetBytes(encryptString); DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0 , inputByteArray.Length); cStream.FlushFinalBlock(); return Convert.ToBase64String(mStream.ToArray()); } catch { return encryptString; } } /// <summary> /// DES解密字符串 /// </summary> /// <param name="decryptString"> 待解密的字符串 </param> /// <param name="decryptKey"> 解密密钥,要求为8位,和加密密钥相同 </param> /// <returns> 解密成功返回解密后的字符串,失败返源串 </returns> public string DecryptDES( string decryptString, string decryptKey) { try { byte [] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring( 0 , 8 )); byte [] rgbIV = Keys; byte [] inputByteArray = Convert.FromBase64String(decryptString); DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider(); MemoryStream mStream = new MemoryStream(); CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0 , inputByteArray.Length); cStream.FlushFinalBlock(); return Encoding.UTF8.GetString(mStream.ToArray()); } catch { return decryptString; } }
二. SHA1 加密 (HASH算法没有解密)
安全哈希算法( Secure Hash Algorithm )主要适用于数字签名标准( Digital Signature Standard DSS )里面定义的数字签名算法( Digital Signature Algorithm DSA )。对于长度小于 2^64 位的消息, SHA1 会产生一个 160 位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要。
SHA1有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消息摘要。
代码如下:
/// <summary> /// use sha1 to encrypt string /// </summary> public string SHA1_Encrypt( string Source_String) { byte [] StrRes = Encoding.Default.GetBytes(Source_String); HashAlgorithm iSHA = new SHA1CryptoServiceProvider(); StrRes = iSHA.ComputeHash(StrRes); StringBuilder EnText = new StringBuilder(); foreach ( byte iByte in StrRes) { EnText.AppendFormat( " {0:x2} " , iByte); } return EnText.ToString(); }
三.RSA 加密、解密 (本例来自 MSDN)
RSA加密算法是一种非对称加密算法。在公钥加密标准和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法的可靠性基于分解极大的整数是很困难的。假如有人找到一种很快的分解因子的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
具体算法过程请参考
代码示例如下(来自MSDN):
using System; using System.Security.Cryptography; using System.IO; using System.Text; namespace Microsoft.Samples.Security.PublicKey{ class App { // Main entry point static void Main( string [] args) { // Instantiate 3 People for example. See the Person class below Person alice = new Person( " Alice " ); Person bob = new Person( " Bob " ); Person steve = new Person( " Steve " ); // Messages that will exchanged. See CipherMessage class below CipherMessage aliceMessage; CipherMessage bobMessage; CipherMessage steveMessage; // Example of encrypting/decrypting your own message Console.WriteLine( " Encrypting/Decrypting Your Own Message " ); Console.WriteLine( " ----------------------------------------- " ); // Alice encrypts a message using her own public key aliceMessage = alice.EncryptMessage( " Alice wrote this message " ); // then using her private key can decrypt the message alice.DecryptMessage(aliceMessage); // Example of Exchanging Keys and Messages Console.WriteLine(); Console.WriteLine( " Exchanging Keys and Messages " ); Console.WriteLine( " ----------------------------------------- " ); // Alice Sends a copy of her public key to Bob and Steve bob.GetPublicKey(alice); steve.GetPublicKey(alice); // Bob and Steve both encrypt messages to send to Alice bobMessage = bob.EncryptMessage( " Hi Alice! - Bob. " ); steveMessage = steve.EncryptMessage( " How are you? - Steve " ); // Alice can decrypt and read both messages alice.DecryptMessage(bobMessage); alice.DecryptMessage(steveMessage); Console.WriteLine(); Console.WriteLine( " Private Key required to read the messages " ); Console.WriteLine( " ----------------------------------------- " ); // Steve cannot read the message that Bob encrypted steve.DecryptMessage(bobMessage); // Not even Bob can use the Message he encrypted for Alice. // The RSA private key is required to decrypt the RS2 key used // in the decryption. bob.DecryptMessage(bobMessage); } // method Main } // class App class CipherMessage { public byte [] cipherBytes; // RC2 encrypted message text public byte [] rc2Key; // RSA encrypted rc2 key public byte [] rc2IV; // RC2 initialization vector } class Person { private RSACryptoServiceProvider rsa; private RC2CryptoServiceProvider rc2; private string name; // Maximum key size for the RC2 algorithm const int keySize = 128 ; // Person constructor public Person( string p_Name) { rsa = new RSACryptoServiceProvider(); rc2 = new RC2CryptoServiceProvider(); rc2.KeySize = keySize; name = p_Name; } // Used to send the rsa public key parameters public RSAParameters SendPublicKey() { RSAParameters result = new RSAParameters(); try { result = rsa.ExportParameters( false ); } catch (CryptographicException e) { Console.WriteLine(e.Message); } return result; } // Used to import the rsa public key parameters public void GetPublicKey(Person receiver) { try { rsa.ImportParameters(receiver.SendPublicKey()); } catch (CryptographicException e) { Console.WriteLine(e.Message); } } public CipherMessage EncryptMessage( string text) { // Convert string to a byte array CipherMessage message = new CipherMessage(); byte [] plainBytes = Encoding.Unicode.GetBytes(text.ToCharArray()); // A new key and iv are generated for every message rc2.GenerateKey(); rc2.GenerateIV(); // The rc2 initialization doesnt need to be encrypted, but will // be used in conjunction with the key to decrypt the message. message.rc2IV = rc2.IV; try { // Encrypt the RC2 key using RSA encryption message.rc2Key = rsa.Encrypt(rc2.Key, false ); } catch (CryptographicException e) { // The High Encryption Pack is required to run this sample // because we are using a 128-bit key. See the readme for // additional information. Console.WriteLine( " Encryption Failed. Ensure that the " + " High Encryption Pack is installed. " ); Console.WriteLine( " Error Message: " + e.Message); Environment.Exit( 0 ); } // Encrypt the Text Message using RC2 (Symmetric algorithm) ICryptoTransform sse = rc2.CreateEncryptor(); MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, sse, CryptoStreamMode.Write); try { cs.Write(plainBytes, 0 , plainBytes.Length); cs.FlushFinalBlock(); message.cipherBytes = ms.ToArray(); } catch (Exception e) { Console.WriteLine(e.Message); } finally { ms.Close(); cs.Close(); } return message; } // method EncryptMessage public void DecryptMessage(CipherMessage message) { // Get the RC2 Key and Initialization Vector rc2.IV = message.rc2IV; try { // Try decrypting the rc2 key rc2.Key = rsa.Decrypt(message.rc2Key, false ); } catch (CryptographicException e) { Console.WriteLine( " Decryption Failed: " + e.Message); return ; } ICryptoTransform ssd = rc2.CreateDecryptor(); // Put the encrypted message in a memorystream MemoryStream ms = new MemoryStream(message.cipherBytes); // the CryptoStream will read cipher text from the MemoryStream CryptoStream cs = new CryptoStream(ms, ssd, CryptoStreamMode.Read); byte [] initialText = new Byte[message.cipherBytes.Length]; try { // Decrypt the message and store in byte array cs.Read(initialText, 0 , initialText.Length); } catch (Exception e) { Console.WriteLine(e.Message); } finally { ms.Close(); cs.Close(); } // Display the message received Console.WriteLine(name + " received the following message: " ); Console.WriteLine( " " + Encoding.Unicode.GetString(initialText)); } // method DecryptMessage } // class Person } // namespace PublicKey