自己写的一个加密,解密(AES)组件
来源:互联网 发布:创世纪 许文彪 知乎 编辑:程序博客网 时间:2024/04/28 02:27
首先说明:这个组件的加密解密核心还是用的微软提供的AES程序加密、解密。除此之外,我还提供了一个很好的功能。
需求说明:
1. 用户A上传了一个文档附件,并设置一个密码。这样没有密码的人不能打开这个文件。
2. 用户A同时还选择了几个用户。这样不是选择的用户不能这个文档。
3. 谁能看到这个文档附件?我们限定在只有用户A,和他选定的几个用户。当然,他们还必须知道这个文档的password。
4 有意思的是,这个功能不是靠权限控制的。
测试用例:
试用nunit测试工具
- #region rar
- [Test]
- public void RarEncodeTest()
- {
- string inFilePath = @"d:/test_file.rar";
- string outFilePath = @"d:/test_file_encoded.rar";
- string key = "asp.net mvc rar";
- IList<string> users = new List<string>();
- users.Add("yaxino");
- users.Add("yinzhiqiang");
- string encodeKey = SecurityFacade.FileEncode(inFilePath, outFilePath, key, users);
- ENCLOSURE enc = new ENCLOSURE();
- enc.ENC_DOC_ID = 1;
- enc.ENC_REMARK = "测试Security rar";
- enc.ENC_URL = outFilePath;
- enc.ENC_PWD = encodeKey;
- int success = new EncLogic().Add(enc, GetDb());
- Assert.AreEqual(1, success, "添加附件信息到数据库失败!");
- }
- [Test]
- public void RarDecodeTest()
- {
- string inFilePath = @"d:/test_file_2.rar";
- string outFilePath = @"d:/test_file_encoded.rar";
- string randomkey = new EncLogic().Get(MaxID(), GetDb()).ENC_PWD; //从数据库取密码密文
- string key = "asp.net mvc rar";
- string user = "yaxino";
- string encodeKey = SecurityFacade.FileDecode(outFilePath, inFilePath, key, user, randomkey);
- Assert.AreEqual(randomkey, encodeKey, "保存密文VS解压密文");
- }
- [Test]
- public void RarDecodeTestWrongUser()
- {
- string inFilePath = @"d:/test_file_2.rar";
- string outFilePath = @"d:/test_file_encoded.rar";
- string randomkey = new EncLogic().Get(MaxID(), GetDb()).ENC_PWD; //从数据库取密码密文
- string key = "asp.net mvc rar";
- string user = "yaxin";
- string encodeKey = SecurityFacade.FileDecode(outFilePath, inFilePath, key, user, randomkey);
- Assert.AreEqual(randomkey, encodeKey, "保存密文VS解压密文");
- }
- [Test]
- public void RarDecodeTestWrongpwd()
- {
- string inFilePath = @"d:/test_file_2.rar";
- string outFilePath = @"d:/test_file_encoded.rar";
- string randomkey = new EncLogic().Get(MaxID(), GetDb()).ENC_PWD; //从数据库取密码密文
- string key = "rar wrong";
- string user = "yaxin";
- string encodeKey = SecurityFacade.FileDecode(outFilePath, inFilePath, key, user, randomkey);
- Assert.AreEqual(randomkey, encodeKey, "保存密文VS解压密文");
- }
- #endregion
对外接口,我叫它为安全外观:
- public sealed class SecurityFacade
- {
- private static ISecurity security = null;
- /// <summary>
- /// 文件加密外观
- /// </summary>
- /// <param name="inFilePath">输入文件路劲</param>
- /// <param name="outFilePath">输出文件路劲</param>
- /// <param name="key">密钥</param>
- /// <returns>消息</returns>
- public static string FileEncode(string inFilePath, string outFilePath, string key, IList<string> users)
- {
- try
- {
- security = new FileSecurity();
- //加密文件,返回随机密钥
- string randomKey = security.Encode(inFilePath, outFilePath, key);
- //得到随机密钥key+用户组信息明文
- string keyUsers = GenerateKeyAndUsers(randomKey, users);
- security = new TextSecurity();
- //二次密钥加密,并返回加密密文
- return security.Encode(keyUsers, "", key);
- }
- catch (Exception ex)
- {
- return ex.Message;
- }
- }
- /// <summary>
- /// 文件解密外观
- /// 没有异常抛出,返回不正确的文件
- /// </summary>
- /// <param name="outFilePath"></param>
- /// <param name="inFilePath"></param>
- /// <param name="key"></param>
- /// <param name="user"></param>
- /// <param name="randomkeyEncode"></param>
- /// <returns></returns>
- public static string FileDecode(string outFilePath, string inFilePath, string key, string user, string randomkeyEncode)
- {
- try
- {
- security = new TextSecurity();
- //解密的编码后的随机密码
- string randomKeyDecode = security.Decode(randomkeyEncode, "", key);
- //根据用户,得到随机密钥key
- string randomKey = GenerateRandomKey(randomKeyDecode, user);
- security = new FileSecurity();
- //解密文件
- return security.Decode(outFilePath, inFilePath, randomKey);
- }
- catch (Exception ex)
- {
- return ex.Message;
- }
- }
- #region "私有成员"
- private static string GenerateKeyAndUsers(string randomKey, IList<string> users)
- {
- string keyUsers = randomKey;
- foreach (string user in users)
- {
- keyUsers += "|" + user;
- }
- return keyUsers + "|";
- }
- private static string GenerateRandomKey(string randomKey, string user)
- {
- AesCryptoServiceProvider aes = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
- aes.GenerateIV();
- if (randomKey.IndexOf('|') < 0 || randomKey.IndexOf("|" + user + "|") < 0)
- {
- return Convert.ToBase64String(aes.IV) + Convert.ToBase64String(aes.Key);
- }
- return randomKey.Substring(0, randomKey.IndexOf('|'));
- }
- /// <summary>
- /// 文本加密外观
- /// </summary>
- /// <param name="inString"></param>
- /// <param name="key"></param>
- /// <returns></returns>
- public static string TextEncode(string inString, string key)
- {
- string outString = string.Empty;
- security = new TextSecurity();
- security.Encode(inString, outString, key);
- return outString;
- }
- #endregion
- /// <summary>
- /// 文本解密
- /// 无异常抛出,key不正确,返回密文
- /// </summary>
- /// <param name="inString"></param>
- /// <param name="key"></param>
- /// <returns></returns>
- public static string TextDecode(string inString, string key)
- {
- string outString = string.Empty;
- security = new TextSecurity();
- outString = security.Decode(inString, outString, key);
- return outString;
- }
- }
内部实现如下:
接口定义:
- interface ISecurity
- {
- string Encode(string encodeString, string decodedString, string key);
- string Decode(string decodeString, string decodedString, string key);
- }
抽象类:
internal abstract class AbstractSecurity : ISecurity
{
//文本加密用的向量
protected static readonly byte[] IV = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56};
#region ISecurity 成员
public abstract string Encode(string encodeString, string decodedString, string key);
public abstract string Decode(string decodeString, string decodedString, string key);
#endregion
}
具体实现类是两个,第一个FileSecurity.cs
- internal class FileSecurity : AbstractSecurity
- {
- #region ISecurity 成员
- /// <summary>
- /// 文件加密算法:
- /// 对制定路径的文件加密,
- /// 并返回随即生成的IV+密钥base64字符串
- /// 可能抛出异常
- /// </summary>
- /// <param name="inFileName">输入文件完全路劲</param>
- /// <param name="outFileName">输出文件完全路劲</param>
- /// <param name="key"> 随机密钥</param>
- /// <returns></returns>
- public override string Encode(string inFileName, string outFileName, string key)
- {
- FileStream fsInput = null;
- FileStream fsEncrypted = null;
- CryptoStream cryptostream = null;
- AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
- try
- {
- fsInput = new FileStream(inFileName, FileMode.Open, FileAccess.Read);
- fsEncrypted = new FileStream(outFileName, FileMode.Create, FileAccess.Write);
- AES.GenerateIV();
- //AES.IV = IV;
- cryptostream = new CryptoStream(fsEncrypted, AES.CreateEncryptor(), CryptoStreamMode.Write);
- byte[] bytearrayinput = new byte[fsInput.Length];
- fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
- cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
- cryptostream.FlushFinalBlock();
- return Convert.ToBase64String(AES.IV) + Convert.ToBase64String(AES.Key);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- fsInput.Close();
- fsEncrypted.Close();
- }
- }
- /// <summary>
- /// 文件解密算法
- /// 不抛出异常
- /// </summary>
- /// <param name="inFileName">输入文件完全路劲</param>
- /// <param name="outFileName">输出文件完全路劲</param>
- /// <param name="key">in 32位密钥</param>
- public override string Decode(string inFileName, string outFileName, string key)
- {
- FileStream fsInput = null;
- FileStream fsEncrypted = null;
- CryptoStream cryptostream = null;
- byte[] bytearrayinput = null;
- AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
- try
- {
- fsInput = new FileStream(inFileName, FileMode.Open, FileAccess.Read);
- fsEncrypted = new FileStream(outFileName, FileMode.Create, FileAccess.Write);
- //AES.GenerateIV();
- AES.IV = Convert.FromBase64String( key.Substring(0, key.IndexOf('=') + 2));
- AES.Key = Convert.FromBase64String(key.Substring(key.IndexOf('=') +2));
- cryptostream = new CryptoStream(fsEncrypted, AES.CreateDecryptor(), CryptoStreamMode.Write);
- bytearrayinput = new byte[fsInput.Length];
- fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
- cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
- cryptostream.FlushFinalBlock();
- return key;
- }
- catch
- {
- //throw ex;
- //出现异常把需要解密的文件直接输出
- //fsEncrypted.Write(bytearrayinput, 0, bytearrayinput.Length);
- return key;
- }
- finally
- {
- fsInput.Close();
- fsEncrypted.Close();
- }
- }
- #endregion
- }
第二个是TextSecurity.cs
- /// <summary>
- /// 文本安全类
- /// </summary>
- internal class TextSecurity : AbstractSecurity
- {
- /// <summary>
- /// 加密文本字符串:
- /// 返回加密后的字符密文
- /// 可能抛出异常
- /// </summary>
- /// <param name="encodeString"></param>
- /// <param name="encodedString"></param>
- /// <param name="key"></param>
- /// <returns></returns>
- public override string Encode(string inString, string nouse, string key)
- {
- try
- {
- AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
- string encodeKey = Utils.GetSubString(key, 32, "");
- encodeKey = encodeKey.PadRight(32, '*');
- AES.Key = Encoding.UTF8.GetBytes(encodeKey.Substring(0, 32));
- AES.IV = IV;
- //AES.GenerateIV();
- byte[] inputByteArray = Encoding.UTF8.GetBytes(inString);
- MemoryStream mStream = new MemoryStream();
- CryptoStream cStream = new CryptoStream(mStream, AES.CreateEncryptor(), CryptoStreamMode.Write);
- cStream.Write(inputByteArray, 0, inputByteArray.Length);
- cStream.FlushFinalBlock();
- return Convert.ToBase64String(mStream.ToArray());
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- /// <summary>
- /// 文本解密算法
- /// 不抛出异常
- /// </summary>
- /// <param name="inString"></param>
- /// <param name="nouse"></param>
- /// <param name="key"></param>
- /// <returns></returns>
- public override string Decode(string inString, string nouse, string key)
- {
- byte[] inputByteArray = null;
- try
- {
- AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
- string encodeKey = Utils.GetSubString(key, 32, "");
- encodeKey = encodeKey.PadRight(32, '*');
- AES.Key = Encoding.UTF8.GetBytes(encodeKey.Substring(0, 32));
- AES.IV = IV;
- //AES.GenerateIV();
- inputByteArray = Convert.FromBase64String(inString);
- MemoryStream mStream = new MemoryStream();
- CryptoStream cStream = new CryptoStream(mStream, AES.CreateDecryptor(), CryptoStreamMode.Write);
- cStream.Write(inputByteArray, 0, inputByteArray.Length);
- cStream.FlushFinalBlock();
- return Encoding.UTF8.GetString(mStream.ToArray());
- }
- catch (Exception ex)
- {
- //throw ex;
- //出现异常,直接返回inString
- return inString;
- }
- }
- }
打完收工。其中有一个数据库操作,自己弄一下吧。没什么难度。
有什么好的建议,请大家指教!
我的qq:124391404
email:yzq124391@126.com
- 自己写的一个加密,解密(AES)组件
- PHP的AES加密解密
- iOS AES的加密解密
- Java的AES加密解密
- iOS AES的加密解密
- PHP AES的加密解密
- 加密解密(DES,AES)
- js加密的密文PHP解密(AES算法)
- AES加密解密算法的FPGA实现(一)
- AES加密解密算法的FPGA实现(二)
- AES加密解密|及Base64的使用
- AES加密解密算法的Java实现
- AES加密解密|及Base64的使用
- AES加密解密|及Base64的使用
- AES加密以及解密的方法
- DES、AES加密解密的方法
- AES 带有位移量的加密、解密
- 理解AES加密解密的使用方法
- [贺新年] 更有效率的 Linux 操作命令
- HTML&&JS
- 久违了!
- [C学习笔记].编码规范
- __autoload()函数
- 自己写的一个加密,解密(AES)组件
- Larbin 搜索引擎源码赏析——(二)搜索引擎的全局变量类
- MOSS开发常见错误信息
- oracle学习笔记(六)-- 相关语法
- Hide Delegate(隐藏委托关系)
- C#.net 支付宝接口
- 幸福的定义是嘛?
- eclipse 无法运行main函数类的解决办法
- asp 过滤非法字符函数