知识大全 浅谈.NET中加密和解密的实现方法

Posted

篇首语:知识为进步之母,而进步又为富强之源泉。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 浅谈.NET中加密和解密的实现方法相关的知识,希望对你有一定的参考价值。

浅谈.NET中加密和解密的实现方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   NET将原来独立的API和SDK合并到一个框架中 这对于程序开发人员非常有利 它将CryptoAPI改编进 NET的System Security Cryptography名字空间 使密码服务摆脱了SDK平台的神秘性 变成了简单的 NET名字空间的使用 由于随着整个框架组件一起共享 密码服务更容易实现了 现在仅仅需要学习System Security Cryptography名字空间的功能和用于解决特定方案的类

  加密和解密的算法

  System Security Cryptography名字空间包含了实现安全方案的类 例如加密和解密数据 管理密钥 验证数据的完整性并确保数据没有被篡改等等 本文重点讨论加密和解密

  加密和解密的算法分为对称(symmetric)算法和不对称(asymmetric)算法 对称算法在加密和解密数据时使用相同的密钥和初始化矢量 典型的有DES TripleDES和Rijndael算法 它适用于不需要传递密钥的情况 主要用于本地文档或数据的加密 不对称算法有两个不同的密钥 分别是公共密钥和私有密钥 公共密钥在网络中传递 用于加密数据 而私有密钥用于解密数据 不对称算法主要有RSA DSA等 主要用于网络数据的加密

  加密和解密本地文档

  下面的例子是加密和解密本地文本 使用的是Rijndael对称算法

  对称算法在数据流通过时对它进行加密 因此首先需要建立一个正常的流(例如I/O流) 文章使用FileStream类将文本文件读入字节数组 也使用该类作为输出机制

  接下来定义相应的对象变量 在定义SymmetricAlgorithm抽象类的对象变量时我们可以指定任何一种对称加密算法提供程序 代码使用的是Rijndael算法 但是很容易改为DES或者TripleDES算法 NET使用强大的随机密钥设置了提供程序的实例 选择自己的密钥是比较危险的 接受计算机产生的密钥是一个更好的选择 文中的代码使用的是计算机产生的密钥

  下一步 算法实例提供了一个对象来执行实际数据传输 每种算法都有CreateEncryptor和CreateDecryptor两个方法 它们返回实现ICryptoTransform接口的对象

  最后 现在使用BinaryReader的ReadBytes方法读取源文件 它会返回一个字节数组 BinaryReader读取源文件的输入流 在作为CryptoStream Write方法的参数时调用ReadBytes方法 指定的CryptoStream实例被告知它应该操作的下层流 该对象将执行数据传递 无论流的目的是读或者写

  下面是加密和解密一个文本文件的源程序片断

  namespace billdawson crypto

  

  class TextFileCrypt

  

  public static void Main(string[] args)

  

  string file = args[ ];

  string tempfile = Path GetTempFileName();

  //打开指定的文件

  FileStream fsIn = File Open(file FileMode Open

  FileAccess Read);

  FileStream fsOut = File Open(tempfile FileMode Open

  FileAccess Write);

  //定义对称算法对象实例和接口

  SymmetricAlgorithm symm = new RijndaelManaged();

  ICryptoTransform transform = symm CreateEncryptor();

  CryptoStream cstream = new CryptoStream(fsOut transform

  ryptoStreamMode Write);

  BinaryReader br = new BinaryReader(fsIn);

  // 读取源文件到cryptostream

  cstream Write(br ReadBytes((int)fsIn Length) (int)fsIn Length);

  cstream FlushFinalBlock();

  cstream Close();

  fsIn Close();

  fsOut Close();

  Console WriteLine( created encrypted file tempfile);

  Console WriteLine( will now decrypt and show contents );

  // 反向操作 解密刚才加密的临时文件

  fsIn = File Open(tempfile FileMode Open FileAccess Read);

  transform = symm CreateDecryptor();

  cstream = new CryptoStream(fsIn transform

  CryptoStreamMode Read);

  StreamReader sr = new StreamReader(cstream);

  Console WriteLine( decrypted file text: + sr ReadToEnd());

  fsIn Close();

  

  

  

  如果我有一个只想自己看到的文档 我不会简单的通过e mail发送给你 我将使用对称算法加密它 如果有人截取了它 他们也不能阅读该文档 因为他们没有用于加密的唯一密钥 但是你也没有密钥 我需要使用某种方式将密钥给你 这样你才能解密文档 但是不能冒密钥和文档被截取的风险

  非对称算法就是一种解决方案 这类算法使用的两个密钥有如下关系 使用公共密钥加密的信息只能被相应的私有密钥解密 因此 我首要求你给我发送你的公共密钥 在发送给我的途中可能有人会截取它 但是没有关系 因为他们只能使用该密钥给你的信息加密 我使用你的公共密钥加密文档并发送给你 你使用私有密钥解密该文档 这是唯一可以解密的密钥 并且没有通过网络传递

  不对称算法比对称算法计算的花费多 速度慢 因此我们不希望在线对话中使用不对称算法加密所有信息 相反 我们使用对称算法 下面的例子中我们使用不对称加密来加密对称密钥 接着就使用对称算法加密了 实际上安全接口层(SSL)建立服务器和浏览器之间的安全对话使用的就是这种工作方式

  示例是一个TCP程序 分为服务器端和客户端 服务器端的工作流程是

  从客户端接收公共密钥

  使用公共密钥加密未来使用的对称密钥

  将加密了的对称密钥发送给客户端

  给客户端发送使用该对称密钥加密的信息

  

  代码如下

  namespace billdawson crypto

  

  public class CryptoServer

  

  private const int RSA_KEY_SIZE_BITS = ;

  private const int RSA_KEY_SIZE_BYTES = ;

  private const int TDES_KEY_SIZE_BITS = ;

  public static void Main(string[] args)

  

  int port;

  string msg;

  TcpListener listener;

  TcpClient client;

  SymmetricAlgorithm symm;

  RSACryptoServiceProvider rsa;

  //获取端口

  try

  

  port = Int Parse(args[ ]);

  msg = args[ ];

  

  catch

  

  Console WriteLine(USAGE);

  return;

  

  //建立监听

  try

  

  listener = new TcpListener(port);

  listener Start();

  Console WriteLine( Listening on port port);

  client = listener AcceptTcpClient();

  Console WriteLine( connection );

  

  catch (Exception e)

  

  Console WriteLine(e Message);

  Console WriteLine(e StackTrace);

  return;

  

  try

  

  rsa = new RSACryptoServiceProvider();

  rsa KeySize = RSA_KEY_SIZE_BITS;

  // 获取客户端公共密钥

  rsa ImportParameters(getClientPublicKey(client));

  symm = new TripleDESCryptoServiceProvider();

  symm KeySize = TDES_KEY_SIZE_BITS;

  //使用客户端的公共密钥加密对称密钥并发送给客

  encryptAndSendSymmetricKey(client rsa symm);

  //使用对称密钥加密信息并发送

  encryptAndSendSecretMessage(client symm msg);

  

  catch (Exception e)

  

  Console WriteLine(e Message);

  Console WriteLine(e StackTrace);

  

  finally

  

  try

  

  client Close();

  listener Stop();

  

  catch

  

  //错误

  

  Console WriteLine( Server exiting );

  

  

  private static RSAParameters getClientPublicKey(TcpClient client)

  

  // 从字节流获取串行化的公共密钥 通过串并转换写入类的实例

  byte[] buffer = new byte[RSA_KEY_SIZE_BYTES];

  NeorkStream ns = client GetStream();

  MemoryStream ms = new MemoryStream();

  BinaryFormatter bf = new BinaryFormatter();

  RSAParameters result;

  int len = ;

  int totalLen = ;

  while(totalLen (len = ns Read(buffer buffer Length))> )

  

  totalLen+=len;

  ms Write(buffer len);

  

  ms Position= ;

  result = (RSAParameters)bf Deserialize(ms);

  ms Close();

  return result;

  

  private static void encryptAndSendSymmetricKey(

  TcpClient client

  RSACryptoServiceProvider rsa

  SymmetricAlgorithm symm)

  

  // 使用客户端的公共密钥加密对称密钥

  byte[] symKeyEncrypted;

  byte[] symIVEncrypted;

  NeorkStream ns = client GetStream();

  symKeyEncrypted = rsa Encrypt(symm Key false);

  symIVEncrypted = rsa Encrypt(symm IV false);

  ns Write(symKeyEncrypted symKeyEncrypted Length);

  ns Write(symIVEncrypted symIVEncrypted Length);

  

  private static void encryptAndSendSecretMessage(TcpClient client

  SymmetricAlgorithm symm

  string secretMsg)

  

  

  // 使用对称密钥和初始化矢量加密信息并发送给客户端

  byte[] msgAsBytes;

  NeorkStream ns = client GetStream();

  ICryptoTransform transform =

  symm CreateEncryptor(symm Key symm IV);

  CryptoStream cstream =

  new CryptoStream(ns transform CryptoStreamMode Write);

  msgAsBytes = Encoding ASCII GetBytes(secretMsg);

  cstream Write(msgAsBytes msgAsBytes Length);

  cstream FlushFinalBlock();

  

  

  客户端的工作流程是

  建立和发送公共密钥给服务器

  从服务器接收被加密的对称密钥

  解密该对称密钥并将它作为私有的不对称密钥

  接收并使用不对称密钥解密信息

  代码如下

  namespace billdawson crypto

  

  public class CryptoClient

  

  private const int RSA_KEY_SIZE_BITS = ;

  private const int RSA_KEY_SIZE_BYTES = ;

  private const int TDES_KEY_SIZE_BITS = ;

  private const int TDES_KEY_SIZE_BYTES = ;

  private const int TDES_IV_SIZE_BYTES = ;

  public static void Main(string[] args)

  

  int port;

  string host;

  TcpClient client;

  SymmetricAlgorithm symm;

  RSACryptoServiceProvider rsa;

  if (args Length!= )

  

  Console WriteLine(USAGE);

  return;

  

  try

  

  host = args[ ];

  port = Int Parse(args[ ]);

  

  catch

  

  Console WriteLine(USAGE);

  return;

  

  try //连接

  

  client = new TcpClient();

  client Connect(host port);

  

  catch(Exception e)

  

  Console WriteLine(e Message);

  Console Write(e StackTrace);

  return;

  

  try

  

  Console WriteLine( Connected Sending public key );

  rsa = new RSACryptoServiceProvider();

  rsa KeySize = RSA_KEY_SIZE_BITS;

  sendPublicKey(rsa ExportParameters(false) client);

  symm = new TripleDESCryptoServiceProvider();

  symm KeySize = TDES_KEY_SIZE_BITS;

  MemoryStream ms = getRestOfMessage(client);

  extractSymmetricKeyInfo(rsa symm ms);

  showSecretMessage(symm ms);

  

  catch(Exception e)

  

  Console WriteLine(e Message);

  Console Write(e StackTrace);

  

  finally

  

  try

  

  client Close();

  

  catch //错误

  

  

  

  private static void sendPublicKey(

  RSAParameters key

  TcpClient client)

  

  NeorkStream ns = client GetStream();

  BinaryFormatter bf = new BinaryFormatter();

  bf Serialize(ns key);

  

  private static MemoryStream getRestOfMessage(TcpClient client)

  

  //获取加密的对称密钥 初始化矢量 秘密信息 对称密钥用公共RSA密钥

  //加密 秘密信息用对称密钥加密

  MemoryStream ms = new MemoryStream();

  NeorkStream ns = client GetStream();

  byte[] buffer = new byte[ ];

  int len= ;

  // 将NetStream 的数据写入内存流

  while((len = ns Read(buffer buffer Length))> )

  

  ms Write(buffer len);

  

  ms Position = ;

  return ms;

  

  private static void extractSymmetricKeyInfo(

  RSACryptoServiceProvider rsa

  SymmetricAlgorithm symm

  MemoryStream msOrig)

  

  MemoryStream ms = new MemoryStream();

  // 获取TDES密钥 它被公共RSA密钥加密 使用私有密钥解密

  byte[] buffer = new byte[TDES_KEY_SIZE_BYTES];

  msOrig Read(buffer buffer Length);

  symm Key = rsa Decrypt(buffer false);

  // 获取TDES初始化矢量

  buffer = new byte[TDES_IV_SIZE_BYTES];

  msOrig Read(buffer buffer Length);

  symm IV = rsa Decrypt(buffer false);

  

  private static void showSecretMessage(

  SymmetricAlgorithm symm

  MemoryStream msOrig)

  

  //内存流中的所有数据都被加密了

  byte[] buffer = new byte[ ];

  int len = msOrig Read(buffer buffer Length);

  MemoryStream ms = new MemoryStream();

  ICryptoTransform transform =

  symm CreateDecryptor(symm Key symm IV);

  CryptoStream cstream =new CryptoStream(ms transform

  CryptoStreamMode Write);

  cstream Write(buffer len);

  cstream FlushFinalBlock();

  // 内存流现在是解密信息 是字节的形式 将它转换为字符串

  ms Position = ;

  len = ms Read(buffer (int) ms Length);

  ms Close();

  string msg = Encoding ASCII GetString(buffer len);

  Console WriteLine( The host sent me this secret message: );

  Console WriteLine(msg);

  

  

  

  结论

cha138/Article/program/net/201311/11946

相关参考

知识大全 .NET中加密与解密QueryString的方法

.NET中加密与解密QueryString的方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&n

知识大全 加密和解密ASP.NET配置文件(Web.config)

加密和解密ASP.NET配置文件(Web.config)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 Asp.net,C# 加密解密字符串

Asp.net,C#加密解密字符串  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  首先在nfig

知识大全 Java中3DES加密解密示例

Java中3DES加密解密示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在java中调用s

知识大全 Java中3DES加密解密调用示例

Java中3DES加密解密调用示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在java中调

知识大全 java密码加密与解密

  以下两个类可以很方便的完成字符串的加密和解密  加密CryptHelperencrypt(password)  解密CrypHelperdecrypt(password)  代码如下  Crypt

知识大全 用C#实现Des加密和解密

小技巧:用C#实现Des加密和解密  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  usingSy

知识大全 3DES加密解密调用示例

3DES加密解密调用示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在java中调用sun公

知识大全 用ASP写个简单的加密和解密的类实例

用ASP写个简单的加密和解密的类实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  用asp写个

甲方和乙方采用公钥密码体制对数据文件进行加密传送,甲方用乙方的公钥加密数据文件,乙方要对数据文件进行解密应该使用__

甲方和乙方采用公钥密码体制对数据文件进行加密传送,甲方用乙方的公钥加密数据文件,乙方要对数据文件进行解密应该使用_____。A、乙的公钥B、乙的私钥C、甲的公钥D、甲的私钥答案:B解析:公开密钥密码体