需求: 

  不知道大家有没有遇到过这样的需求:自己的服务器出于对数据库安全的保护,需要对存储的数据进行加密保护。这样万一数据库被人拿到,别人也不能拿到数据库里面的内容。这里还有一个前提:前端的展示页面是不对外公开的,需要验证才能进入。为什么提这个,就是因为前端所展现的内容一定是明文的,不然管理人员如何阅读查看呢(这也给爬虫留下了机会,不过关键还是在于你能够拿到管理人员的密码)。

背景介绍:

  •   系统数据库采用的是Mongodb;
  •   后台使用的语言是Python;
  •   python与数据库的交互主要借助于Pymongo。

寻找突破口:

  从这里面我们大概可以发现有两个地方可以下手:

  1. 每次进行数据库操作的时候对数据进行加解密操作。具体来说就是:增删改查之前对数据进行加密(这样才能在数据库中找到),查找之后对数据进行解密(这样才能得到明文的内容进行展示);
  2. 修改与数据库进行交互的库Pymongo,让其实现加密存储,解密读取。

  比较下两种方法的优缺点:

  第一种方案:实现很简单,但不适合大项目。项目一旦大了,对数据库的操作不太可能完全通过某个数据库操作模块来实现,这样修改起来就很麻烦了;

  第二种方案:对业务逻辑是透明的。并不需要对网站代码进行修改,但需要对pymongo的源码进行分析,找出增删改查相应的关键点,在这些关键点上进行加解密操作。

  由于自己的项目确实不小,存在很多模块。所以选择了第二种方案。

具体步骤:

  1. 实现加解密函数库

    既然需要用到加解密操作,那么显然需要实现自己的加解密函数。具体实现中我使用了pycrypto加密库,利用其中的AES加密算法对文档进行加解密。加解密过程不难,利用里递归实现,代码实现如下:

 from Crypto.Cipher import AES
import bson
from bson.binary import Binary, UUIDLegacy
from pymongo import config key = config.key obj = AES.new(key) def encrypt_helper(s):
length = 16 - (len(s) % 16)
s += chr(length) * length
s = obj.encrypt(s)
s = Binary(s, 1)
return s def decrypt_helper(s):
s = obj.decrypt(s)
buf = bytearray(s)
length = buf[-1]
s = s[: -length]
return s def encrypt_doc(doc):
if isinstance(doc, str):
return encrypt_helper(doc)
if isinstance(doc, dict):
for key in doc:
if cmp(key, "channel") != 0:
doc[key] = encrypt_doc(doc[key])
return doc if isinstance(doc, list):
for i in range(len(doc)):
doc[i] = encrypt_doc(doc[i])
return doc
return doc def decrypt_doc(doc):
if isinstance(doc, Binary):
return decrypt_helper(doc)
if isinstance(doc, dict):
temp_doc = {}
for key in doc:
#version 1
#doc[key] = decrypt_doc(doc[key]) #version 2
temp_doc[str(key)] = decrypt_doc(doc[key])
doc = temp_doc
return doc if isinstance(doc, list):
for i in range(len(doc)):
doc[i] = decrypt_doc(doc[i])
return doc
return doc

  2. 找到pymongo中进行增删改查操作的代码并插入加解密的操作

    经过研读pymongo的代码发现,增删改查的操作主要是在两个文件里面进行的:collection.py,cursor.py。所以在实现过程中,我只对这两个文件的相关部分进行了修改(注意,我使用pymongo版本是2.7,如果使用其他版本的可能会有差别)。

    我就简单列举一下我修改的函数吧,大家有兴趣可以上github具体查看下整个实现:

    •  collection.py:

      • insert
      • update
      • find_one
      • remove
      • aggregate
    •  cursor.py
      • __getitem__
      • __send_message

    有兴趣的可以看看代码,github地址:https://github.com/ybAmazing/encrypt_pymongo

思考和总结

  这个功能的必要性,我自己是持怀疑态度的。由于对黑客技术也不是很了解,也说不出个所以然来。大家如果有什么想法或建议的,可以留言,相互交流学习一下。

Mongodb数据库加密存储(python)的更多相关文章

  1. mongodb数据库的存储问题

    MongoDB在Windows中默认的数据库目录是c:\data.如果在没有该目录的情况下,直接运行mongod.exe,就会报如下错误(并没有把mongodb设置为服务,所以通过命令行的形式启动,注 ...

  2. Python爬取豆瓣音乐存储MongoDB数据库(Python爬虫实战1)

    1.  爬虫设计的技术 1)数据获取,通过http获取网站的数据,如urllib,urllib2,requests等模块: 2)数据提取,将web站点所获取的数据进行处理,获取所需要的数据,常使用的技 ...

  3. python操作MONGODB数据库,提取部分数据再存储

    目标:从一个数据库中提取几个集合中的部分数据,组合起来一共一万条.几个集合,不足一千条数据的集合就全部提取,够一千条的就用一万减去不足一千的,再除以大于一千的集合个数,得到的值即为所需提取文档的个数. ...

  4. 浅析MongoDB数据库的海量数据存储应用

    [摘要]当今已进入大数据时代,特别是大规模互联网web2.0应用不断发展及云计算所需要的海量存储和海量计算发展,传统的关系型数据库已无法满足这方面的需求.随着NoSQL数据库的不断发展和成熟,可以较好 ...

  5. python连接数据库(pymysql)及数据库加密

    内容: 1.pymysql介绍 2.pymysql基本使用 3.数据库加密 参考:http://www.cnblogs.com/wupeiqi/articles/5713330.html 1.pymy ...

  6. python学习笔记——mongodb数据库

    1 概述 1.1 文件管理阶段 优点:可以长期保存 能存储大量数据 缺点:没有结构化的组织 查找不方便 数据容易冗余 1.2 数据库管理阶段 有文件存储的优点,同时解决了文件存储的问题 缺点 : 操作 ...

  7. 第一篇:一天学会MongoDB数据库之Python操作

    本文仅仅学习使用,转自:https://www.cnblogs.com/suoning/p/6759367.html#3682005 里面新增了如果用用Python代码进行增删改查 什么是MongoD ...

  8. Python全栈 MongoDB 数据库(聚合、二进制、GridFS、pymongo模块)

    断网了2天  今天补上     聚合操作: 对文档的信息进行整理统计的操作 返回:统计后的文档集合 db.collection.aggregate() 功能:聚合函数,完成聚合操作 参数:聚合条件,配 ...

  9. Python全栈 MongoDB 数据库(概念、安装、创建数据)

    什么是关系型数据库?           是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据,             同时也是一个被组织成一组拥有正式描述性的表格( ...

随机推荐

  1. ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习

    一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...

  2. 在caffe中添加新的layer

    比如现在要添加一个vision layer,名字叫Ly_Layer:(一般命名第一个字母大写,其余小写.) 1.属于哪个类型的layer(共五种:common_layer, data_layer, l ...

  3. js获取一个对象的所以属性和值

    在HTML DOM中,获取某个元素对象的时候,往往记不住它的很多属性,可以通过下面的例子来查找一下: <!DOCTYPE html> <html> <body> & ...

  4. 得到UIView中某个非子视图在UIView中的位置

    使用 convertRect: fromView: 或者 convertRect: toView:例如一个视图控制器的view中有一个UITableView,UITableView的某个cell中有个 ...

  5. 【转】Myeclipse建立Maven项目

    原文地址: http://b-l-east.iteye.com/blog/1246482 1. 使用Maven创建webapp工程----原因是使用Maven时一般需要遵循一定的目录结构,虽然也可以使 ...

  6. KMP(fail数组应用) LA 3026 Period

    题目传送门 题意:(训练指南P213) 求每个前缀的最短循环节 分析:利用失配函数的性质,如果i % (i - fail[i]) == 0,那么正好错位移动一个循环节长度. #include < ...

  7. js 数组(Array)

    一.数组 稠密数组(非稀疏数组) 稀疏数组 二.数组的添加和删除 我们已经常见过添加数组元素最简单的方法:为新索引赋值;也可以使用push()方法在数组末尾增加一个或者多个元素: a = []; a. ...

  8. HTML与HTML5笔记

    doctype作用 1.告诉浏览器使用什么样的html或者xhtml规范来解析html文档 2.影响浏览器的渲染模式. 浏览器解析css的两种渲染模式:标准模式strict mode和怪异模式quir ...

  9. 读取和写入 文件 (NSFIleManger 与 NSFileHandle)

    读取和写入 文件 //传递文件路径方法 -(id)initPath:(NSString *)srcPath targetPath:(NSString *)targetPath { self = [su ...

  10. IOS关于UIViewController之间的切换

    IOS关于UIViewController之间的切换 1.NavigationController切换UIViewController的两种方式 方法一右侧进入 1 SecondViewControl ...