首先说明:这个组件的加密解密核心还是用的微软提供的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.     }



打完收工。其中有一个数据库操作,自己弄一下吧。没什么难度。


有什么好的建议,请大家指教!