首先说明:这个组件的加密解密核心还是用的微软提供的AES程序加密、解密。除此之外,我还提供了一个很好的功能。
需求说明:
1. 用户A上传了一个文档附件,并设置一个密码。这样没有密码的人不能打开这个文件。
2. 用户A同时还选择了几个用户。这样不是选择的用户不能这个文档。
3. 谁能看到这个文档附件?我们限定在只有用户A,和他选定的几个用户。当然,他们还必须知道这个文档的password。
4 有意思的是,这个功能不是靠权限控制的。
测试用例:
试用nunit测试工具
1. #region rar
2.
3.
4. [Test]
5. public void
6. {
7. string inFilePath = @"d:/test_file.rar";
8. string outFilePath = @"d:/test_file_encoded.rar";
9. string key = "asp.net mvc rar";
10. string> users = new List<string>();
11. "yaxino");
12. "yinzhiqiang");
13.
14. string
15.
16.
17. new
18. enc.ENC_DOC_ID = 1;
19. "测试Security rar";
20. enc.ENC_URL = outFilePath;
21. enc.ENC_PWD = encodeKey;
22. int success = new
23.
24. "添加附件信息到数据库失败!");
25.
26.
27. }
28.
29. [Test]
30. public void
31. {
32. string inFilePath = @"d:/test_file_2.rar";
33. string outFilePath = @"d:/test_file_encoded.rar";
34. string randomkey = new EncLogic().Get(MaxID(), GetDb()).ENC_PWD; //从数据库取密码密文
35. string key = "asp.net mvc rar";
36. string user = "yaxino";
37.
38. string
39.
40.
41. "保存密文VS解压密文");
42.
43.
44. }
45.
46. [Test]
47. public void
48. {
49. string inFilePath = @"d:/test_file_2.rar";
50. string outFilePath = @"d:/test_file_encoded.rar";
51. string randomkey = new EncLogic().Get(MaxID(), GetDb()).ENC_PWD; //从数据库取密码密文
52. string key = "asp.net mvc rar";
53. string user = "yaxin";
54.
55. string
56.
57.
58. "保存密文VS解压密文");
59.
60.
61. }
62.
63. [Test]
64. public void
65. {
66. string inFilePath = @"d:/test_file_2.rar";
67. string outFilePath = @"d:/test_file_encoded.rar";
68. string randomkey = new EncLogic().Get(MaxID(), GetDb()).ENC_PWD; //从数据库取密码密文
69. string key = "rar wrong";
70. string user = "yaxin";
71.
72. string
73.
74.
75. "保存密文VS解压密文");
76.
77.
78.
79.
80.
81. #endregion
对外接口,我叫它为安全外观:
1. public sealed class
2. {
3. private static ISecurity security = null;
4.
5.
6. /// <summary>
7. /// 文件加密外观
8. /// </summary>
9. /// <param name="inFilePath">输入文件路劲</param>
10. /// <param name="outFilePath">输出文件路劲</param>
11. /// <param name="key">密钥</param>
12. /// <returns>消息</returns>
13. public static string FileEncode(string inFilePath, string outFilePath, string key, IList<string> users)
14. {
15.
16. try
17. {
18. new
19. //加密文件,返回随机密钥
20. string
21. //得到随机密钥key+用户组信息明文
22. string
23.
24. new
25. //二次密钥加密,并返回加密密文
26. return security.Encode(keyUsers, "", key);
27.
28. }
29. catch
30. {
31. return
32. }
33.
34. }
35.
36.
37.
38. /// <summary>
39. /// 文件解密外观
40. /// 没有异常抛出,返回不正确的文件
41. /// </summary>
42. /// <param name="outFilePath"></param>
43. /// <param name="inFilePath"></param>
44. /// <param name="key"></param>
45. /// <param name="user"></param>
46. /// <param name="randomkeyEncode"></param>
47. /// <returns></returns>
48. public static string FileDecode(string outFilePath, string inFilePath, string key, string user, string
49. {
50. try
51. {
52. new
53. //解密的编码后的随机密码
54. string randomKeyDecode = security.Decode(randomkeyEncode, "", key);
55.
56. //根据用户,得到随机密钥key
57. string
58.
59. new
60. //解密文件
61. return
62.
63. }
64. catch
65. {
66. return
67. }
68.
69.
70. #region "私有成员"
71.
72. private static string GenerateKeyAndUsers(string randomKey, IList<string> users)
73. {
74. string
75. foreach (string user in
76. {
77. "|"
78. }
79. return keyUsers + "|";
80. }
81.
82. private static string GenerateRandomKey(string randomKey, string
83. {
84. AesCryptoServiceProvider aes = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
85. aes.GenerateIV();
86. if (randomKey.IndexOf('|') < 0 || randomKey.IndexOf("|" + user + "|") < 0)
87. {
88. return
89. }
90.
91. return randomKey.Substring(0, randomKey.IndexOf('|'));
92.
93.
94. }
95.
96.
97.
98. /// <summary>
99. /// 文本加密外观
100. /// </summary>
101. /// <param name="inString"></param>
102. /// <param name="key"></param>
103. /// <returns></returns>
104. public static string TextEncode(string inString, string
105. {
106. string outString = string.Empty;
107.
108. new
109. security.Encode(inString, outString, key);
110.
111. return
112.
113.
114.
115. #endregion
116. /// <summary>
117. /// 文本解密
118. /// 无异常抛出,key不正确,返回密文
119. /// </summary>
120. /// <param name="inString"></param>
121. /// <param name="key"></param>
122. /// <returns></returns>
123. public static string TextDecode(string inString, string
124. {
125. string outString = string.Empty;
126.
127. new
128. outString = security.Decode(inString, outString, key);
129.
130. return
131. }
132.
133.
134. }
内部实现如下:
接口定义:
1. interface
2. {
3. string Encode(string encodeString, string decodedString, string
4. string Decode(string decodeString, string decodedString, string
5. }
抽象类:
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
1. internal class
2.
3. #region ISecurity 成员
4.
5. /// <summary>
6. /// 文件加密算法:
7. /// 对制定路径的文件加密,
8. /// 并返回随即生成的IV+密钥base64字符串
9. /// 可能抛出异常
10. /// </summary>
11. /// <param name="inFileName">输入文件完全路劲</param>
12. /// <param name="outFileName">输出文件完全路劲</param>
13. /// <param name="key"> 随机密钥</param>
14. /// <returns></returns>
15. public override string Encode(string inFileName, string outFileName, string
16. {
17.
18.
19. null;
20.
21. null;
22.
23. null;
24. AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
25. try
26. {
27.
28. new
29. new
30. AES.GenerateIV();
31. //AES.IV = IV;
32. new
33.
34. byte[] bytearrayinput = new byte[fsInput.Length];
35. fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
36. cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
37.
38. cryptostream.FlushFinalBlock();
39.
40.
41. return
42. }
43. catch
44. {
45. throw
46.
47. }
48. finally
49. {
50. fsInput.Close();
51. fsEncrypted.Close();
52.
53. }
54.
55. }
56.
57. /// <summary>
58. /// 文件解密算法
59. /// 不抛出异常
60. /// </summary>
61. /// <param name="inFileName">输入文件完全路劲</param>
62. /// <param name="outFileName">输出文件完全路劲</param>
63. /// <param name="key">in 32位密钥</param>
64. public override string Decode(string inFileName, string outFileName, string
65. {
66.
67. null;
68.
69. null;
70.
71. null;
72.
73. byte[] bytearrayinput = null;
74.
75. AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
76.
77. try
78. {
79.
80. new
81. new
82. //AES.GenerateIV();
83.
84. '=') + 2));
85. '=') +2));
86. new
87.
88. new byte[fsInput.Length];
89. fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
90. cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
91.
92. cryptostream.FlushFinalBlock();
93.
94. return
95. }
96. catch
97. {
98. //throw ex;
99. //出现异常把需要解密的文件直接输出
100. //fsEncrypted.Write(bytearrayinput, 0, bytearrayinput.Length);
101. return
102.
103. }
104. finally
105. {
106. fsInput.Close();
107. fsEncrypted.Close();
108. }
109.
110.
111.
112.
113.
114. #endregion
115.
116.
117. }
第二个是TextSecurity.cs
1. /// <summary>
2. /// 文本安全类
3. /// </summary>
4. internal class
5. {
6. /// <summary>
7. /// 加密文本字符串:
8. /// 返回加密后的字符密文
9. /// 可能抛出异常
10. /// </summary>
11. /// <param name="encodeString"></param>
12. /// <param name="encodedString"></param>
13. /// <param name="key"></param>
14. /// <returns></returns>
15. public override string Encode(string inString, string nouse, string
16. {
17. try
18. {
19. AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
20. string encodeKey = Utils.GetSubString(key, 32, "");
21. '*');
22. AES.Key = Encoding.UTF8.GetBytes(encodeKey.Substring(0, 32));
23. AES.IV = IV;
24. //AES.GenerateIV();
25. byte[] inputByteArray = Encoding.UTF8.GetBytes(inString);
26.
27. new
28. new
29. cStream.Write(inputByteArray, 0, inputByteArray.Length);
30. cStream.FlushFinalBlock();
31. return
32. }
33. catch
34. {
35. throw
36. }
37. }
38.
39.
40. /// <summary>
41. /// 文本解密算法
42. /// 不抛出异常
43. /// </summary>
44. /// <param name="inString"></param>
45. /// <param name="nouse"></param>
46. /// <param name="key"></param>
47. /// <returns></returns>
48. public override string Decode(string inString, string nouse, string
49. {
50. byte[] inputByteArray = null;
51. try
52. {
53. AesCryptoServiceProvider AES = (AesCryptoServiceProvider)AesCryptoServiceProvider.Create();
54. string encodeKey = Utils.GetSubString(key, 32, "");
55. '*');
56. AES.Key = Encoding.UTF8.GetBytes(encodeKey.Substring(0, 32));
57. AES.IV = IV;
58. //AES.GenerateIV();
59. inputByteArray = Convert.FromBase64String(inString);
60.
61. new
62. new
63. cStream.Write(inputByteArray, 0, inputByteArray.Length);
64. cStream.FlushFinalBlock();
65. return
66. }
67. catch
68. {
69. //throw ex;
70. //出现异常,直接返回inString
71. return
72. }
73. }
74.
75. }
打完收工。其中有一个数据库操作,自己弄一下吧。没什么难度。
有什么好的建议,请大家指教!