博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django开发密码管理表实例【附源码】
阅读量:6577 次
发布时间:2019-06-24

本文共 7301 字,大约阅读时间需要 24 分钟。

  hot3.png

文章及代码比较基础,适合初、中级人员,高手略过

阅读此篇文章你可以:

  • 获取一个Django实现增删改查的案例源码
  • 了解数据加密的使用场景和方法以及如何在Python3中使用

背景介绍

DBA需要维护一张密码表,主要记录数据库中创建的账号密码信息,大概如下:

目前的维护方式还是最传统的Excel,一个人更新给多个人同步,Excel设置密码以保证安全性,原始且效率低下,既然我们已经上线了overmind数据库运维系统,何不在系统里边集成这个功能呢?

技术实现

简单分析就可以知道,我们要实现的功能如下:

1.最基础的表单增删改查

2.涉及到密码存储需要加密

update_or_create

表单增删改查大家应该都比较熟悉了,实现方式有很多,我们采用了最简单的view方法来实现,详细内容查看源代码。

代码中用到了Django的一个QuerySet API可能部分人没有用过update_or_create,这里详细介绍下

update_or_create(defaults=None, **kwargs)

看到方法的命名大概也能猜出来这个方法的主要作用就是更新或者创建model数据,那么究竟什么情况下更新?什么情况下创建呢?主要根据传入的**kwargs来判断,defaults为要更新的数据。一句话概括为filter kwargs,create/update defaults

例如对于一张用户表我们要判断username为devops,且email为 的用户是否存在,如果不存在则创建这个用户,且设置用户的site为 ,如果存在则更新这个用户的site为 ,则可以这样写

object, created = User.objects.update_or_create(    username='devops',    email='devops@ops-coffee.cn',    defaults={        'username':'devops',        'email':'devops@ops-coffee.cn',        'site':'https://ops-coffee.cn'    })

额,上边的例子是不是有点复杂了,拿我们项目里边的实例为例,就是判断id是否存在,如果存在则更新,如果不存在则创建

object, created = Table.objects.update_or_create(    id=postdata.get('id'),    defaults=postdata)

update_or_create方法返回结果为一个元组(object, created),object为新建或者更新的对象,created为一个布尔值,表示是新建还是更新,True为新建

密码加密

对于密码加密,我们知道加密算法有很多,究竟哪种适合我们呢?

看一下我们的需求,存储的时候要加密存储,但也要能对加密后的数据进行解密以获取原始密码,那么就要求加密算法既支持加密,也支持解密,对于md5这种只支持加密的单向算法就不能选择了,在支持加解密的算法中应用最为广泛的当属RSA了,我们最终也选择了RSA,其实单单对于这个场景来说用3DES之类的对称加密就够了,速度也会快很多,但是考虑到系统里边有其他的加密需求选择RSA能满足更多情景。

RSA加密算法非常复杂,感兴趣的可以查询专业资料,RSA需要一对秘钥称为公钥和私钥,公钥可以对字符串进行加密生成加密字符串,拿私钥可以将加密字符串还原。

python3中RSA的使用

生成RSA秘钥对代码

from Cryptodome.PublicKey import RSAdef create_rsa_key():    '''生成RSA秘钥对'''    try:        # 选择秘钥位数,位数越高越安全,同时加密速度也越慢        key = RSA.generate(2048)        encrypted_key = key.exportKey(pkcs=8)        public_key = key.publickey().exportKey().decode('utf-8')        private_key = encrypted_key.decode('utf-8')        return {'state': 1, 'message': {'public_key': public_key, 'private_key': private_key}}    except Exception as err:        return {'state': 0, 'message': str(err)}if __name__ == '__main__':    print(create_rsa_key())

执行脚本生成RSA秘钥对,将RSA秘钥对配置在加解密的代码中

RSA加密解密代码

import binasciifrom Cryptodome.PublicKey import RSAfrom Cryptodome.Cipher import PKCS1_v1_5class RsaCrypto():    '''RSA 加解密'''    def __init__(self):        self.private_key = '''-----BEGIN PRIVATE KEY-----        MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDLetN9MfsVWZj2        K+i1vPQqeDKb8Fe52pHKvRtQggTF+x3YRCyk7UNQ27VupohM8t+Qzi2Zm3GnZY5X        H7W8UGLnI1X1ykpWOWVueP3KCA7DCtswDp5hkJgHzPPZC/DlFh0uCpAmUkgHP7WU        XRZoR9mmcVOdWN9c+NWS0JA6cwHSI+J78Edb1lfef5YOwseL2GiOmBiJ7THYfjrw        FwGQaZVjhsp3Pkt7Yt/Huc5NU234wA9j+TFFnubpOrE9mFT8qCkhFhWIEcNsuTqD        DDI9BX0lLaEEn+vg9cnEZ97VgdQQG2D6Ozw4Gldpfoq1XB6BqXg+YsCvyD/h/4QD        LpejZy/VAgMBAAECggEADJkoj6omNevb459Tri+VHS1fUiEEXXZ3QQqKWWa4wu/0        U2030mek8P8EHGYP2avOmcRE4IDWUvCfv9cvxQljxj8oKwABBZZSKGUyBBiRnr6E        /v8OC/5hhgIeNZm0ADW+osN2qgNoKu1lNwVjG3EaEbXB4TkdGJWI1lPhdNelYjby        7/4vnXO7yplSFlDLiqjmEV9Vva3Jf3N3vf92ZfUJg6NHklYDlP+L4unNtS++HKtv        C3TWSz0esVrK67t4Vut+RdKrSQzzWkPAqNwktUavQq6Nb+KMrf9tsQujPZaXkEUn        LUwtVNwhT3BiyPswHN1ycjlP3lN391rnawDQc751dQKBgQDZSFBq1JaGm4zK2YHm        BbxCJ++6l1Qmu9yhk/zic1M/oGoFRdzkeWrYsxhLupp+4PjcCPEiZqivSeJXsFVO        diSjWsBkfO51HRuEzRE2Z/tiTRzJsGAcrBsWwBYNZR/PADG7MEYhIYH0p6Jp3jrq        pNs0f5Gz8XToPi2TQXmRyAltFwKBgQDvvOFlJFfx1ld2wLuZ0w1yMpUoyFYCWSh+        ylREFETod8ufbQxRzvvSA3gFO+xwYZoA+Wq/TyGrfVnN9m4R1goPsQjsuUYQeAIi        MBKmG5znTAmu8dQ5wLKtb10CV0MuFGOSv8xvlccKepY7IDtxOaO410o4PFEjAziU        90b8RiRV8wKBgHDsUD71NTXH6agS2pu9J1YKg2Cp/SYURFoFG0xlO0K6D9+lq2Ni        ZtEwYtQYqup96VgRnaCPUeOntmZ0UiFw7SGorIyNETD0a7TdDrED4XX5NZjsfUbp        ezqbodpcT+e45h+uuwPE8lFAPfxfbqc7/mCOXB70whlhFzaMtK27FIsJAoGAVtTJ        qnF8bPpeWYO7Lx7TOu55Ofk9tcIHOc0csj/JKY3iMY80rBjU+p8JBJRMsfOX7Qxp        jnshzdQsB75e5ZTptf9AJUWBzAs7cpiI2KMdtGTFCRlL7dMOpGS2gleK3JDD8+4G        JNBR9EisSyQEg6EF3LgViMLH/G95OfNKQatCE+MCgYEAhRIuEMaL2idD9NKOVdgC        fuSbiP5G69IBVD4uoDYFPQJjxqVOg3pORa8+cJTe+ZFaCkTGV3112eM5Vtm4Vd9Q        pOh7VgJP1l3puZnUoSWGoWansx6aKok5FwuUrZWPjqr/Zrre8XXJyaiR520tuf0i        StMfNAsijJgi2pq2PTMovhE=        -----END PRIVATE KEY-----'''        self.public_key = '''-----BEGIN PUBLIC KEY-----        MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy3rTfTH7FVmY9ivotbz0        Kngym/BXudqRyr0bUIIExfsd2EQspO1DUNu1bqaITPLfkM4tmZtxp2WOVx+1vFBi        5yNV9cpKVjllbnj9yggOwwrbMA6eYZCYB8zz2Qvw5RYdLgqQJlJIBz+1lF0WaEfZ        pnFTnVjfXPjVktCQOnMB0iPie/BHW9ZX3n+WDsLHi9hojpgYie0x2H468BcBkGmV        Y4bKdz5Le2Lfx7nOTVNt+MAPY/kxRZ7m6TqxPZhU/KgpIRYViBHDbLk6gwwyPQV9        JS2hBJ/r4PXJxGfe1YHUEBtg+js8OBpXaX6KtVwegal4PmLAr8g/4f+EAy6Xo2cv        1QIDAQAB        -----END PUBLIC KEY-----'''    def encrypt(self, plaintext):        '''加密方法'''        try:            recipient_key = RSA.import_key(self.public_key)            cipher_rsa = PKCS1_v1_5.new(recipient_key)            en_data = cipher_rsa.encrypt(plaintext.encode('utf-8'))            hex_data = binascii.hexlify(en_data).decode('utf-8')            return {'state': 1, 'message': hex_data}        except Exception as err:            return {'state': 0, 'message': str(err)}    def decrypt(self, hex_data):        '''解密方法'''        try:            private_key = RSA.import_key(self.private_key)            cipher_rsa = PKCS1_v1_5.new(private_key)            en_data = binascii.unhexlify(hex_data.encode('utf-8'))            data = cipher_rsa.decrypt(en_data, None).decode('utf-8')            return {'state': 1, 'message': data}        except Exception as err:            return {'state': 0, 'message': str(err)}if __name__ == '__main__':    print(RsaCrypto().encrypt())

对原始密码加密

>>> _t = RsaCrypto().encrypt('ops_coffee.cn')>>> print(_t){'state': 1, 'message': 'ae3e52eede23a7c9dd348244f0ae90b06c6773e9fecb2383f8195c50e6032742fb793423d75082db9a325b091d3e02351cd04157c68a64a5c130c0eaf7de1396d8993f0d649d1f3c1004119aa221daefca52215a235fb316af313ef64479957264012be20a1d54987386a3f29ae2fe80e147e7eeb770803045cab0d979aa6d5b88c39058f8fba7f6bf06bc436be59a19ccb72ac2813d809132203a64020bbe3c0c3df74befa8b18fb4782e34daff8f6e33e4b45cbe1b2db2be2c3e38a1c9e0e314178ed36a53960017fd9af5f27d99c5e5e0a8d384ac83156598788334248507ac1498fe44b1fb7e3b43e44a8bf3fc189076b16efef2c0f0a86d7faa053bbe24'}

获取加密后的字符串

>>> hex_data = _t.get('message')>>> print(hex_data)ae3e52eede23a7c9dd348244f0ae90b06c6773e9fecb2383f8195c50e6032742fb793423d75082db9a325b091d3e02351cd04157c68a64a5c130c0eaf7de1396d8993f0d649d1f3c1004119aa221daefca52215a235fb316af313ef64479957264012be20a1d54987386a3f29ae2fe80e147e7eeb770803045cab0d979aa6d5b88c39058f8fba7f6bf06bc436be59a19ccb72ac2813d809132203a64020bbe3c0c3df74befa8b18fb4782e34daff8f6e33e4b45cbe1b2db2be2c3e38a1c9e0e314178ed36a53960017fd9af5f27d99c5e5e0a8d384ac83156598788334248507ac1498fe44b1fb7e3b43e44a8bf3fc189076b16efef2c0f0a86d7faa053bbe24

对加密后的字符串进行解密

>>> _x = RsaCrypto().decrypt(hex_data)>>> print(_x){'state': 1, 'message': 'ops_coffee.cn'}

页面展示

列表页:列表页使用了datatables插件方便展示,且使用了Django的模板引擎直接渲染

添加:一个简单的功能,这里就在当前页面弹出model弹出框的方式来展现

编辑:添加、编辑、删除都采用前后端分离,ajax异步json数据交互

查看原始密码:实际上是有权限管理的,并非所有用户都能查看原始密码

源码地址

aHR0cHM6Ly9naXRodWIuY29tL29wcy1jb2ZmZWUvZGVtby90cmVlL21hc3Rlci9wYXNzd29yZA==

上边为“加密”后的源码地址,有没有想尝试破解一下的冲动?关注公众号【运维咖啡吧】回复"01"获取加密方式及源码地址,期待你的到来


扫码关注查看更多原创文章

如果你觉得文章对你有帮助,请转发分享给更多的人。如果你觉得读的不尽兴,推荐阅读以下文章:

转载于:https://my.oschina.net/37Y37/blog/2980735

你可能感兴趣的文章
【Dubbo实战】Dubbo+Zookeeper+Spring整合应用篇-Dubbo基于Zookeeper实现分布式服务(二)...
查看>>
使用 LeanCloud 服务做一站式 Chrome 插件开发 —— Favorite Image
查看>>
外包筛选心得
查看>>
markdown 列表下新段落
查看>>
浏览器拦截打开新窗口情况总结
查看>>
《Java工程师成神之路-基础篇》Java基础知识——序列化(已完结)
查看>>
iOS App间相互跳转漫谈 part2
查看>>
Android逆向之路---让我们试试另一种方法看漫画-(2)
查看>>
Java CAS 原理剖析
查看>>
iOS UIButton之UIEdgeInsets详解
查看>>
ISCC2014 writeup
查看>>
Java&Android 基础知识梳理(8) 容器类
查看>>
Kotlin 知识梳理(1) Kotlin 基础
查看>>
Redis内部数据结构详解(5)——quicklist
查看>>
OKio - 重新定义了“短小精悍”的IO框架
查看>>
注释那些事儿:前端代码质量系列文章(一)
查看>>
iOS-中集成百度echarts3-0
查看>>
js正则表达式
查看>>
iOS socket通信,编解码,浮点型数据解析
查看>>
四十四、【CardView】
查看>>