需求:
不知道大家有没有遇到过这样的需求:自己的服务器出于对数据库安全的保护,需要对存储的数据进行加密保护。这样万一数据库被人拿到,别人也不能拿到数据库里面的内容。这里还有一个前提:前端的展示页面是不对外公开的,需要验证才能进入。为什么提这个,就是因为前端所展现的内容一定是明文的,不然管理人员如何阅读查看呢(这也给爬虫留下了机会,不过关键还是在于你能够拿到管理人员的密码)。
背景介绍:
寻找突破口:
从这里面我们大概可以发现有两个地方可以下手:
比较下两种方法的优缺点:
第一种方案:实现很简单,但不适合大项目。项目一旦大了,对数据库的操作不太可能完全通过某个数据库操作模块来实现,这样修改起来就很麻烦了;
第二种方案:对业务逻辑是透明的。并不需要对网站代码进行修改,但需要对 pymongo 的源码进行分析,找出增删改查相应的关键点,在这些关键点上进行加解密操作。
由于自己的项目确实不小,存在很多模块。所以选择了第二种方案。
具体步骤:
既然需要用到加解密操作,那么显然需要实现自己的加解密函数。具体实现中我使用了 pycrypto 加密库,利用其中的 AES 加密算法对文档进行加解密。加解密过程不难,利用里递归实现,代码实现如下:
View Code
- 1 from Crypto.Cipher import AES 2 import bson 3 from bson.binary import Binary,
- UUIDLegacy 4 from pymongo import config 5 6 key = config.key 7 8 obj = AES.new(key) 9 10 def encrypt_helper(s) : 11 length = 16 - (len(s) % 16) 12 s += chr(length) * length 13 s = obj.encrypt(s) 14 s = Binary(s, 1) 15
- return s 16 17 def decrypt_helper(s) : 18 s = obj.decrypt(s) 19 buf = bytearray(s) 20 length = buf[ - 1] 21 s = s[: -length] 22
- return s 23 24 def encrypt_doc(doc) : 25
- if isinstance(doc, str) : 26
- return encrypt_helper(doc) 27
- if isinstance(doc, dict) : 28
- for key in doc: 29
- if cmp(key, "channel") != 0 : 30 doc[key] = encrypt_doc(doc[key]) 31
- return doc 32 33
- if isinstance(doc, list) : 34
- for i in range(len(doc)) : 35 doc[i] = encrypt_doc(doc[i]) 36
- return doc 37
- return doc 38 39 40 def decrypt_doc(doc) : 41
- if isinstance(doc, Binary) : 42
- return decrypt_helper(doc) 43
- if isinstance(doc, dict) : 44 temp_doc = {}
- 45
- for key in doc: 46#version 1 47#doc[key] = decrypt_doc(doc[key]) 48 49#version 2 50 temp_doc[str(key)] = decrypt_doc(doc[key]) 51 doc = temp_doc 52
- return doc 53 54
- if isinstance(doc, list) : 55
- for i in range(len(doc)) : 56 doc[i] = decrypt_doc(doc[i]) 57
- return doc 58
- return doc
2. 找到 pymongo 中进行增删改查操作的代码并插入加解密的操作
经过研读 pymongo 的代码发现,增删改查的操作主要是在两个文件里面进行的:collection.py,cursor.py。所以在实现过程中,我只对这两个文件的相关部分进行了修改(注意,我使用 pymongo 版本是 2.7,如果使用其他版本的可能会有差别)。
我就简单列举一下我修改的函数吧,大家有兴趣可以上 github 具体查看下整个实现:
有兴趣的可以看看代码,github 地址:
思考和总结
这个功能的必要性,我自己是持怀疑态度的。由于对黑客技术也不是很了解,也说不出个所以然来。大家如果有什么想法或建议的,可以留言,相互交流学习一下。
来源: http://www.cnblogs.com/yan-boy/p/5864536.html