zoukankan      html  css  js  c++  java
  • Mongodb数据库加密存储(python)

     需求: 

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

     

    背景介绍:

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

     

    寻找突破口:

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

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

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

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

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

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

     

    具体步骤:

    1. 实现加解密函数库

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

     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
    View Code

      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

    思考和总结

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

     

  • 相关阅读:
    BZOJ4036 HAOI2015按位或(概率期望+容斥原理)
    洛谷p2661信息传递题解
    洛谷P1434滑雪题解及记忆化搜索的基本步骤
    二分图最大匹配
    线段树

    图论基本算法
    并查集
    RMQ--ST表
    矩阵快速幂和矩阵乘法
  • 原文地址:https://www.cnblogs.com/yan-boy/p/5864536.html
Copyright © 2011-2022 走看看