Silverlight信息加密 - 通过Rfc2898DeriveBytes类使用基于HMACSHA1的伪随机数生成器实现PBKDF2
2011-08-21 19:36
501 查看
在上一篇文章当中,介绍到了通过Silverlight获取web.config中的值,最后提到了加密的问题,因此首先对该安全问题做一个简单的描述。
问题描述
1. 下方是我的web.config文件,当中配置这一个媒体文件服务器的IP地址
2. 当在Silverlight程序中获取到该config中的值时,我们可以发现,通过查看页面的Source Code,是可以看到这个IP地址的,它是以明文的方式显示出来的,这样会引发安全性问题,我相信没有人愿意将自己的服务器IP地址暴露在外面
解决方法
在Page页面获取到web.config后,对该文件当中的内容进行加密,从而有效地解决了明文显示的问题,这样,别人就不能通过查看源代码的方式从前台获取你的服务器IP地址或者其他机密信息了,其实现方法如下:
1. 在Page页面后台的.cs文件中,加入机密算法,使用Rfc2898DeriveBytes 获取密码、salt 值和迭代次数,然后通过调用 GetBytes 方法生成密钥:
2. 之后,在Silverlight页面获取config数据的时候,通过解密算法进行解密,得到真正的IP地址信息:
最终实现效果如下,这时候我们通过查看源文件看到的则是被加密后的信息,而不是127.0.0.1,只有在Silverlight进行解密之后,才能看到我们想要的数据。
问题描述
1. 下方是我的web.config文件,当中配置这一个媒体文件服务器的IP地址
<?xml version="1.0"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 --> <configuration> <connectionStrings> <add name="VideoFiles_ConnectionString" connectionString="127.0.0.1"/> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> </configuration>
2. 当在Silverlight程序中获取到该config中的值时,我们可以发现,通过查看页面的Source Code,是可以看到这个IP地址的,它是以明文的方式显示出来的,这样会引发安全性问题,我相信没有人愿意将自己的服务器IP地址暴露在外面
解决方法
在Page页面获取到web.config后,对该文件当中的内容进行加密,从而有效地解决了明文显示的问题,这样,别人就不能通过查看源代码的方式从前台获取你的服务器IP地址或者其他机密信息了,其实现方法如下:
1. 在Page页面后台的.cs文件中,加入机密算法,使用Rfc2898DeriveBytes 获取密码、salt 值和迭代次数,然后通过调用 GetBytes 方法生成密钥:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Collections.Specialized; using System.Text; using System.Configuration; using System.Security.Cryptography; using System.IO; namespace GetWebConfig.Web { public partial class HostPage : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Clear the Cache Response.Cache.SetCacheability(HttpCacheability.NoCache); WriteInitParams(); } private void WriteInitParams() { string strConn = ConfigurationManager.ConnectionStrings["VideoFiles_ConnectionString"].ToString(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<param name=\"InitParams\" value=\""); stringBuilder.Append(Encrypt(strConn)); stringBuilder.Append("\"/>"); this.litInitParams.Text = stringBuilder.ToString(); } /**/ /// <summary> /// 加密数据 /// </summary> /// <param name="input">加密前的字符串</param> /// <returns>加密后的字符串</returns> public static string Encrypt(string input) { // salt值 string saltValue = "saltValue"; // 密码值 string pwdValue = "xuyue"; byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(input); byte[] salt = System.Text.UTF8Encoding.UTF8.GetBytes(saltValue); // AesManaged - 高级加密标准(AES) 对称算法的管理类 System.Security.Cryptography.AesManaged aes = new System.Security.Cryptography.AesManaged(); // Rfc2898DeriveBytes - 通过使用基于 HMACSHA1 的伪随机数生成器,实现基于密码的密钥派生功能 (PBKDF2 - 一种基于密码的密钥派生函数) // 通过 密码 和 salt 派生密钥 System.Security.Cryptography.Rfc2898DeriveBytes rfc = new System.Security.Cryptography.Rfc2898DeriveBytes(pwdValue, salt); /**/ /* * AesManaged.BlockSize - 加密操作的块大小(单位:bit) * AesManaged.LegalBlockSizes - 对称算法支持的块大小(单位:bit) * AesManaged.KeySize - 对称算法的密钥大小(单位:bit) * AesManaged.LegalKeySizes - 对称算法支持的密钥大小(单位:bit) * AesManaged.Key - 对称算法的密钥 * AesManaged.IV - 对称算法的密钥大小 * Rfc2898DeriveBytes.GetBytes(int 需要生成的伪随机密钥字节数) - 生成密钥 */ aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; aes.KeySize = aes.LegalKeySizes[0].MaxSize; aes.Key = rfc.GetBytes(aes.KeySize / 8); aes.IV = rfc.GetBytes(aes.BlockSize / 8); // 用当前的 Key 属性和初始化向量 IV 创建对称加密器对象 System.Security.Cryptography.ICryptoTransform encryptTransform = aes.CreateEncryptor(); // 加密后的输出流 System.IO.MemoryStream encryptStream = new System.IO.MemoryStream(); // 将加密后的目标流(encryptStream)与加密转换(encryptTransform)相连接 System.Security.Cryptography.CryptoStream encryptor = new System.Security.Cryptography.CryptoStream (encryptStream, encryptTransform, System.Security.Cryptography.CryptoStreamMode.Write); // 将一个字节序列写入当前 CryptoStream (完成加密的过程) encryptor.Write(data, 0, data.Length); encryptor.Close(); // 将加密后所得到的流转换成字节数组,再用Base64编码将其转换为字符串 string encryptedString = Convert.ToBase64String(encryptStream.ToArray()); return encryptedString; } } }
2. 之后,在Silverlight页面获取config数据的时候,通过解密算法进行解密,得到真正的IP地址信息:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Security.Cryptography; using System.IO; using System.Text; namespace GetWebConfig { public partial class MainPage : UserControl { private IDictionary<string, string> _config; public MainPage() { InitializeComponent(); _config = (Application.Current as App).Configurations; if (_config.Count > 0) lblWebconfig.Content = "Web.config connectionString: " + Decrypt(_config.ElementAt(0).Key.ToString() + "=="); } /// <summary> /// 解密数据 /// </summary> /// <param name="input">加密后的字符串</param> /// <returns>加密前的字符串</returns> public string Decrypt(string input) { // salt值(与加密时设置的值一致) string saltValue = "saltValue"; // 密码值(与加密时设置的值一致) string pwdValue = "xuyue"; byte[] encryptBytes = Convert.FromBase64String(input); byte[] salt = Encoding.UTF8.GetBytes(saltValue); System.Security.Cryptography.AesManaged aes = new System.Security.Cryptography.AesManaged(); System.Security.Cryptography.Rfc2898DeriveBytes rfc = new System.Security.Cryptography.Rfc2898DeriveBytes(pwdValue, salt); aes.BlockSize = aes.LegalBlockSizes[0].MaxSize; aes.KeySize = aes.LegalKeySizes[0].MaxSize; aes.Key = rfc.GetBytes(aes.KeySize / 8); aes.IV = rfc.GetBytes(aes.BlockSize / 8); // 用当前的 Key 属性和初始化向量 IV 创建对称解密器对象 System.Security.Cryptography.ICryptoTransform decryptTransform = aes.CreateDecryptor(); // 解密后的输出流 MemoryStream decryptStream = new MemoryStream(); // 将解密后的目标流(decryptStream)与解密转换(decryptTransform)相连接 System.Security.Cryptography.CryptoStream decryptor = new System.Security.Cryptography.CryptoStream( decryptStream, decryptTransform, System.Security.Cryptography.CryptoStreamMode.Write); // 将一个字节序列写入当前 CryptoStream (完成解密的过程) decryptor.Write(encryptBytes, 0, encryptBytes.Length); decryptor.Close(); // 将解密后所得到的流转换为字符串 byte[] decryptBytes = decryptStream.ToArray(); string decryptedString = UTF8Encoding.UTF8.GetString(decryptBytes, 0, decryptBytes.Length); return decryptedString; } } }
最终实现效果如下,这时候我们通过查看源文件看到的则是被加密后的信息,而不是127.0.0.1,只有在Silverlight进行解密之后,才能看到我们想要的数据。
相关文章推荐
- Silverlight信息加密 - 通过Rfc2898DeriveBytes类使用基于HMACSHA1的伪随机数生成器实现PBKDF2 (转)
- Silverlight信息加密 - 通过Rfc2898DeriveBytes类使用基于HMACSHA1的伪随机数生成器实现PBKDF2
- Silverlight信息加密 - 通过Rfc2898DeriveBytes类使用基于HMACSHA1的伪随机数生成器实现PBKDF2
- Silverlight信息加密 - 通过Rfc2898DeriveBytes类使用基于HMACSHA1的伪随机数生成器实现PBKDF2
- JS通过使用PDFJS实现基于文件流的预览功能
- 使用javacc实现语法生成器(基于miniC语法)
- shell脚本通过expect脚本实现自动输入密码(使用expect)
- 使用Spring 2.0新特性实现前置通知--基于Schema方式
- Python基于生成器迭代实现的八皇后问题示例
- 使用3.0实现微信打飞机——9.通过截屏实现暂停功能
- 基于jQuery通过jQuery.form.js插件实现异步上传
- 使用golang+java实现基于ecb的3eds加解密
- 多线程学习(一)——通过多线程为基于 .NET 的应用程序实现响应迅速的用户
- 使用WINHEX脚本实现批量(通过目录)提取JPG照片
- 使用poi实现Excel导入功能,数据库基于oracle(上)
- 通过多线程为基于.NET的应用程序实现响应迅速(3)
- 使用TensorFlow基于阿里云AI实现图像识别技术(HR)
- ASP.NET jQuery 实例12 通过使用jQuery validation插件简单实现用户注册页面验证功能
- 基于Jupyter平台通过python实现Spark的应用程序之wordCount
- 输入一组整型元素序列,使用尾插法建立一个带有头结点的单链表。 ② 实现该线性表的遍历。 ③ 在该单链表的第i个元素前插入一个整数。 ④ 删除该单链表中的第i个元素,其值通过参数将其返回。 ⑤ 建立两个