自制密码管理器 —— 使用python、RSA加密文件

本文介绍了一个使用Python编程自制的密码管理器,通过RSA加密确保密码安全。程序实现了根据账户名生成不同密码、修改密码、加密保存密码文件等功能。作者强调了密码管理的重要性,分享了学习心得,并探讨了加密过程的关键点,如规则制定、RSA加密的密钥管理和数据长度限制。
摘要由CSDN通过智能技术生成

  
  

视频演示链接:用python做的密码管理器
  
  

1.前言

  自从迷上各种网站以后,各种注册压根停不下来,密码老是记不住是接触互联网的人都会遇到的问题。
  有的人不管是什么密码,都统一用相同的密码,省去了不必要的麻烦,但是如果某天随意一个账号密码泄露,坏人来入侵你简直易如反掌。(只要知道你手机号和一个密码,就可以去尝试登陆不同的网站,并不是什么平台都会有短信验证码这种安全操作的)
  有的人会使用网上的密码管理器,看似安全,但是假如不法分子在软件上故意留了后门,那岂不是很危险。大数据时代,防人之心不可无啊!
  这几天在学习python语言,倒不如来练练手,自己写一个简易的密码管理器,密码的规则只有你知道,设置不同符号就可以挡住暴力破解,每一个账号的密码都不相同,都不简单。

2.需求

 ① 输入不同账户名,就可以生成不同的可设置长度的密码;
 ② 也能够自己修改密码,并且更新密码文件;
 ③ 不想记密码,要有保存密码的文件,以后可以查看;
 ④ 密码文件不轻易被别人看到,能够加密、自动备份、隐藏。
(大神请绕路,不要尝试找我的漏洞,因为你一定找得到~小小百姓能够使用就可以啦,本文旨在分享学习心得)

3.问题思路

  把账户名用哈希计算,得到固定长度的数据,比如SHA-512算法得到512位长度的数据,此过程不可逆。然后自行设置规则 —— 提取该数据的某一段、什么字符替换什么字符等,这个规则自行设定且要牢记。得到某一长度的密码后,连同账户名一起写入到文件中,这里可以使用python的字典来保存账号密码,对于后续多账号的管理操作会比较简单。然后使用RSA非对称加密来加密密码文件里的信息,在需要读取文件时,再用私钥去解密即可读取出文件内容。
关键点1:如果担心规则记不住,可以在提示信息里加以备注;
关键点2:RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题,对于1024长度的密钥,128字节(1024bits)-减去11字节正好是117字节,可以先对数据进行bas64加密, 再对加密后的内容使用rsa加密, 最后对rsa解密后的内容进行bas64解密。
关键点3:关于公钥密钥的保存,可以在代码里嵌入在线获取公钥密钥的方法(有点危险),也可以先把公钥密钥保存为pem文件放在本地,在代码里调用出公钥,只有在自己修改查看密码时将私钥文件放进特定路径再使用(安全系数更高)。
关键点4:每一次对密码文件的读写,都要经过加密、解密、备份的过程。加密过程是先读取文件里所有文本,经过加密再保存到文件里;解密过程是先读取文件的密文,经过解密后再将信息保存到文件里,对于文件的隐藏和备份,使用os.system()执行cmd命令。

4.开始办事

环境:WIN7 32位  python3.8.1
需要用到的包:hashlib,rsa,base64,os,re(注意有些自带了)
可以使用镜像源下载:pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com hashlib(需要下载哪个包,就把黄色名字改成包名)
查看是否有某个工具包的方法:进入cmd,先输入python,再输入import+包名,如果有这个工具包,则不会报错。

文件操作
1、open() 方法
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
参数 用途
file 必需,文件路径(相对或者绝对路径)
mode 可选,文件打开模式
模式 描述
r 以只读方式打开文件,这是默认模式
w 打开一个文件只用于写入,如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。

2、file.read()方法
read() 方法用于从文件读取指定的字节数,如果未给定或为负则读取所有

3、file.readlines()方法
readlines() 方法用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for… in … 结构进行处理。 如果碰到结束符 EOF 则返回空字符串。

4、file.write()方法
write() 方法用于向文件中写入指定字符串。如果文件打开模式带 b,那写入文件内容时,str (参数)要用 encode 方法转为 bytes 形式,否则报错:TypeError: a bytes-like object is required, not ‘str’。

示例:

在F:\MyPwd\b.txt下,输入如下内容:

123
456
789
{
   123}

新建一个.py文件,然后运行代码

file_path = "F:\\MyPwd\\b.txt" #使用绝对路径
f = open(file_path,'r')
read_data = f.read()
readlines_data = f.readlines()
f.close() #记得一定要关了文件
print('read_data:\n{}\ntype: {}\n\n'.format(read_data,type(read_data)))
print('readlines_data:\n{}\ntype: {}'.format(readlines_data,type(readlines_data)))
f = open(file_path,'w')
f.write('abcd')
f.close()

运行结果为:

readlines_data:  #使用readlines读取文件,返回列表
['123\n', '456\n', '789\n', '{123}']
type: <class 'list'>

read_data:  #使用read读取文件,返回字符串
123
456
789
{
   123}
type: <class 'str'>

abcd  #使用write写文件,将删除原有内容,再写入

鉴于此,先对密码文件的储存格式规划,在代码里,希望通过字典的方式来保存、调用信息,键值为账号名称,其值里再包含密码长度、密码内容,示例如下:

data = {
   
     '张三': {
   'len': '13', 'value': '1aswedwxdsaaa'},
     '李四': {
   'len': '12', 'value': '1aswedwxdsaa'},
     '小五': {
   'len': '11', 'value': '1aswedwxdsa'}
     }

使用write()函数时,传入参数不能直接将字典传进去,否则报错:TypeError: write() argument must be str, not dict,所以可以规定,将键值存放在单数行,值存放在双数行

f = open(file_path,'w') #file_path和data在前文已定义
for k,v in data.items():#data.items()返回字典的某一项内容
    #k为键值,写入在文件的单数行,如'张三'
    #v为value,如{'len': '13', 'value': '1aswedwxdsaaa'}
    f.write(str(k)+'\n') #主键值写完,回车
    #x为键值,如'len'  y为该键值对应的value,如'13'
    for x,y in v.items(): #同理操作
        f.write(str(x)+' ') #以空格隔开,方便后续分离
        f.write(str(y)+' ')
    f.write('\n') #次键值写完,回车
f.close()

运行结果如下,在txt文件可以看到:

张三  #主键值
len 13 value 1aswedwxdsaaa #以空格分开
李四
len 12 value 1aswedwxdsaa 
小五
len 11 value 1aswedwxdsa 
  #最后一行是回车

现在已经完成将字典内容写入txt文件,内容是以字符串形式储存的,接下来是如何读取出txt文件的字符串,再转成字典格式呢?回忆上文的readlines()函数,使用它读取文件返回的是list类型数据

f = open(file_path,'r')
data = f.readlines()
print(data)
f.close()

返回的结果如下

['张三\n', 'len 13 value 1aswedwxdsaaa \n', '李四\n', 'len 12 value 1aswedwxdsaa \n', '小五\n', 'len 11 value 1aswedwxdsa \n']

返回的是列表,列表的每一项内容是字符串,因此可以接着对这个返回结果操作,将有用信息提取出来

print('原字典信息:\n{}\n\n'.format(data))#file_path和data在前文已定义

f = open(file_path,'r')
information = f.readlines()
name,lenth,value = [],[],[] #分别存放姓名、密码长度、密码
data = {
   } #新建空白字典
for i in range(len(information)): #遍历所有信息条
    if i % 2 == 0:  # for循环从0开始,因此对应的是文件的第一行,即键值   
       s1 = information[i].replace('\n', '')#将字符串中的'\n'替换,即删除
       name.append(s1) #添加到name列表
    else: #对应的是主键值的value,如'len 13 value 1aswedwxdsaaa \n'
       s2 = information[i].split()  #将该字符串以空格分开组成新的列表,如['len', '13', 'value', '1aswedwxdsaaa']
       lenth.append(s2[1]) #index=1对应长度的数值
       value.append(s2[3]) #index=3对应密码的数值
for j in range(len(name)): #在所有账号中遍历
    #新建字典,格式如下:
    temp = {
   name[j]:{
   'len':lenth[j],'value':value[j]}}
    data.update(temp) #在data字典里增加新的内容
f.close()
print('读取出的信息:\n{}\n\n'.format(data))

运行结果如下:

原字典信息:
{
   '张三': {
   'len': 
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值