前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安全的数据库图形管理工具(1):准备密钥

安全的数据库图形管理工具(1):准备密钥

作者头像
不可言诉的深渊
发布2019-07-26 17:18:04
1.2K0
发布2019-07-26 17:18:04
举报

年底了,该干大事了,就问你怕不怕?!

为什么要做一个安全的数据库图形管理工具?

我们都知道,在正式的生产环境下,数据库并不在你工作的电脑上,而是位于机房的实体服务器,或者是位于传说中的云服务器。因此,远程连接数据库是很有必要的。但是,数据库一般安装配置好后是不允许远程连接的,要想允许远程连接,就需要去修改它的连接权限(以MySQL为例)。

当我们通过远程连接工具XShell或者SecureCRT连接到远程服务器之后,输入命令mysql -uroot -p回车输入MySQL的root密码就进入了MySQL交互界面。然后就可以输入SQL语句进行操作了,每输入完SQL语句之后,必须要给一个结束符(英文分号或者\g)。然后我们就可以修改它的权限了,首先执行SQL语句:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'password' WITH GRANT OPTION;然后执行SQL语句:FLUSH PRIVILEGES;使修改生效。

我们来看一下第一个SQL语句,‘root’@‘%’表示任何机器都可以以root用户名登录数据库,其中%表示任何机器,‘password’是root账户的密码。像这样任何人都有访问服务器数据库的权限太不安全了,这种方式简直就是瞎胡闹!有些人会想,既然%表示所有机器,那么我把%改成我工作的电脑的IP就行了吧,如果服务器在公司那没啥问题,因为毕竟只会从公司内网连过去,公司外的不法分子很难抓到数据(如果这都被抓到了,只能说明公司的安全系统出问题了)。

但是如果你人不在公司,又或者服务器不是公司内的实体服务器,而是传说中的云服务器,这样连接的到服务器数据库会通过好多个路由器,在通过路由器期间一旦被中间人将密码窃取并破解后果不堪设想。有些人可能会想,在把密码发过去之前已经加密了,难道这还会被破解?依旧是有可能会,因为MySQL数据库密码使用的是SHA1加密算法,这个算法现在已经非常不安全了,所以被破解很有可能。

难道真的没有办法远程连接数据库了吗?办法还是有的,在给出解决方案之前,我们来想一下这样两个问题:为什么我可以通过远程连接工具实现连接?远程连接工具真的安全吗?说实话,这还真的是安全的,因为这些工具使用了更强的加密算法——非对称加密

非对称加密

在网络通信中,主机A发送一个消息到达主机B,大部分情况下,这个消息并不是直接到达的,而是中间经过了好多的分组转发,在分组转发期间,如果消息被中间人窃取后果不堪设想!因此,加密传输的技术诞生了。加密算法目前分为两种——对称加密和非对称加密。对称加密是发送方用某种加密算法加密,接收方接收到密文之后再使用对应的解密算法解密,也就是加密和解密使用同一个密钥,如果中间人窃取了密文并破解那后果不堪设想。因此,更安全的非对称加密诞生了。非对称加密与对称加密不同的是它有两个密钥——公钥和私钥。公钥是公开的,可以给任何人;私钥只能你自己保管。

同样的还是A和B两个主机发送数据,当A要给B发送数据,A必须要有B的公钥才行,A将发送的数据使用B的公钥加密后发送,然后B接收到之后使用自己的私钥解密就行了。这样的话中间人即使窃取到了也还是无能为力,因为中间人没有B的私钥!

难道只能通过终端操作远程数据库?

通过远程连接工具数据传输确实得到了安全的保证,但是有些人会觉得不爽,因为没有图形化管理工具(实际上有图形化管理工具,但现有的MySQL图形化管理工具都是使用的对称加密)。既然没有可靠的图形化管理工具,那我们就自己做一个!

准备密钥

既然知道了为什么要自己做一个数据库图形管理工具,就可以开始做前期的准备工作了!我们首先来想这样一个问题,我们能不能从远程连接工具里面获取密钥呢?当然可以!但这太繁琐了,所以我们通过编写程序来获取。

公钥给对方,私钥自己留!

在编写程序之前,我们先想一下非对称加密的过程——发送方要有接收方的公钥才能够正确的加密!因此客户端服务器交换公钥成了准备密钥的核心操作!

用程序生成公钥私钥我们需要使用模块rsa,如果没有该模块,请使用pip安装。

客户端程序

客户端需要生成自己的公钥私钥,并把公钥交给服务器保管,私钥自己留着。具体实现的细节我就不讲了,代码中有注释!下面我直接给出客户端代码:

代码语言:javascript
复制
  import rsa
  import socket
  host = ""  # 服务器的IP地址
  port = 1234  # 服务器程序的端口号
  public_key, private_key = rsa.newkeys(256)  # 生成公钥和私钥
  private_key = private_key.save_pkcs1()  # 获取私钥使用对应存储格式的字符串
  public_key = public_key.save_pkcs1()  # 获取公钥使用对应存储格式的字符串
  open("self_private_key.pem", "wb").write(private_key)  # 将自己的私钥保存起来
  s = socket.socket()  # 创建套接字对象
  s.connect((host, port))  # 与服务器建立连接
  s.send(public_key)  # 将公钥发送给服务器
  server_public_key = s.recv(512)  # 将服务器的公钥接收回来
  open("server_public_key.pem", "wb").write(server_public_key)  # 保存服务器的公钥

通过注释,我相信大家很容易理解这段代码,我就不做解释了。下面我开始讲解服务器代码!

服务器程序

和客户端程序一样,服务器程序依旧需要生成自己的公钥私钥,公钥给客户端,私钥自己留着。具体实现的细节我页不讲了,代码中有注释!下面我直接给出服务器代码:

代码语言:javascript
复制
  import rsa
  import socket
  host = ""  # 服务器IP地址,什么都不写表示本地
  port = 1234  # 服务器程序端口号
  public_key, private_key = rsa.newkeys(256)  # 生成公钥和私钥
  private_key = private_key.save_pkcs1()  # 获取私钥使用对应存储格式的字符串
  public_key = public_key.save_pkcs1()  # 获取公钥使用对应存储格式的字符串
  open("self_private_key.pem", "wb").write(private_key)  # 将自己的私钥保存起来
  s = socket.socket()  # 创建套接字对象
  s.bind((host, port))  # 捆绑IP地址和端口号,让客户端程序可以找到
  s.listen(1)  # 最大连接数
  c, addr = s.accept()  # 接受客户端连接
  c.send(public_key)  # 将公钥发送给客户端
  client_public_key = c.recv(512)  # 接受客户端发来的公钥
  open("client_public_key.pem", "wb").write(client_public_key)  # 保存客户端的公钥
  c.close()  # 关闭客户端
  s.close()  # 关闭服务器

运行程序

运行程序的过程很简单,先运行服务器程序,然后再运行客户端程序。等运行完之后查看客户端程序对应的目录下会有两个文件——self_private_key.pem(自己的私钥)和server_public_key.pem(服务器的公钥)。如图所示。

同样的,服务器程序所在的目录下也会有两个文件——self_private_key.pem(自己的私钥)和client_public_key.pem(客户端的公钥)。

测试密钥

密钥虽然生成了,但到底能不能用呢?写一个程序验证一下就行了。为什么要验证?因为客户端服务器交换公钥的途中有可能公钥被截获并篡改!验证的过程非常简单,客户端和服务器建立连接之后,客户端用服务器的公钥加密要发送的数据并发送给服务器,在此期间,服务器用客户端公钥加密发送的数据并发送客户端。然后就是双方都接收对方发来的加密数据,最后用自己的私钥解密并输出。

客户端测试程序

客户端测试程序需要加载自己的私钥和对方的公钥,然后把发送的数据用对方的公钥加密并发送给对方,接着接收对方发来的加密的数据。最后解密接收的数据并输出。具体实现的细节我就不讲了,代码中有注释!下面我直接给出客户端测试程序代码:

代码语言:javascript
复制
  import rsa
  import socket
  public_key = open("server_public_key.pem", "rb").read()  # 打开公钥文件并读取
  public_key = rsa.PublicKey.load_pkcs1(public_key)  # 加载公钥
  private_key = open("self_private_key.pem", "rb").read()  # 打开私钥文件并读取
  private_key = rsa.PrivateKey.load_pkcs1(private_key)  # 加载私钥
  send_encode_data = rsa.encrypt(b"client", public_key)  # 用公钥加密要发送的数据
  s = socket.socket()  # 创建套接字对象
  host = "111.230.108.44"  # 服务器的IP地址
  port = 1234  # 服务器程序的端口号
  s.connect((host, port))  # 连接服务器
  s.send(send_encode_data)  # 发送已经加密的数据
  receive_encode_data = s.recv(128)  # 接受已经加密的数据
  print(rsa.decrypt(receive_encode_data, private_key).decode())  # 解密接收到的加密数据并输出

服务器测试程序

与客户端测试程序一样,服务器测试程序依旧需要加载对方的的公钥和自己的私钥,然后把发送的数据用对方的公钥加密并发送给对方,接着接收对方发来的加密的数据。最后解密接收的数据并输出。具体实现的细节我就不讲了,代码中有注释!下面我直接给出服务器测试程序代码:

代码语言:javascript
复制
  import rsa
  import socket
  public_key = open("client_public_key.pem", "rb").read()  # 打开公钥文件并读取
  public_key = rsa.PublicKey.load_pkcs1(public_key)  # 加载公钥
  private_key = open("self_private_key.pem", "rb").read()  # 打开私钥文件并读取
  private_key = rsa.PrivateKey.load_pkcs1(private_key)  # 加载私钥
  send_encode_data = rsa.encrypt(b"server", public_key)  # 用公钥加密要发送的数据
  s = socket.socket()  # 创建套接字对象
  host = ""  # 服务器IP地址
  port = 1234  # 服务器程序端口号
  s.bind((host, port))  # 捆绑IP地址和端口号,让客户端程序可以找到
  s.listen(1)  # 最大连接数
  c, addr = s.accept()  # 接受客户端的连接
  c.send(send_encode_data)  # 发送已经加密的数据
  receive_encode_data = c.recv(128)  # 接收已经加密的数据
  print(rsa.decrypt(receive_encode_data, private_key).decode())  # 解密接收到的加密数据并输出
  c.close()
  s.close()

运行测试程序

运行程序的过程很简单,先运行服务器程序,然后再运行客户端程序。等程序运行完之后,发现客户端程序执行结果如图所示。

同样的,服务器程序执行结果如图所示。

通过结果我们可以看出,客户端测试程序可以解密服务器用客户端公钥加密的数据,服务器测试程序也可以解密客户端用服务器公钥加密的数据。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python机器学习算法说书人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么要做一个安全的数据库图形管理工具?
    • 非对称加密
      • 难道只能通过终端操作远程数据库?
      • 准备密钥
        • 公钥给对方,私钥自己留!
          • 客户端程序
            • 服务器程序
              • 运行程序
              • 测试密钥
                • 客户端测试程序
                  • 服务器测试程序
                    • 运行测试程序
                    相关产品与服务
                    云服务器
                    云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档