在测试过程中,我们经常会遇到接口数据加密、数据库密码加密怎么测试等问题,很多同学立马被吓退了。
实际上,只要耐心一点,测试过程的常用加密算法不是那么难,甚至有的根本就不是加密算法。
密码学是一门相对比较晦涩的科学,电影《模仿游戏》就是讲的包括图灵在内的几个顶级数学家破译德军的军事情报的故事。 但是在工作当中,我们不需要懂密码学的底层原理,你只需要知道他们如何使用的就可以了。
本文会列举在测试和开发过程中最常用的算法,解开所谓“加密”过程的神秘面纱。
算法1: base64
这不是加密算法,它叫做编码算法。和我们把文字编码成计算机当中的二进制数据一样。
说得更通俗一点。只要你观察到 I am a programer
这几个字是英语,你就能通过翻译软件知道他的原始意思是 “我是一个程序员”。
我们来看一段字符串:
SSBsaWtlIHlvdQ==
如果你是一个萌新,你肯定不懂这是什么意思。看文这篇文章以后,你就会知道他的意思是:
I like you
就和我们把中文翻译成英文一样, base64 这样的编码算法只是把你看得懂的字翻译成肉眼看不懂的字,但是一旦你知道这些看不懂的符号是哪一门语言,你就可以直接翻译回去。
比如上一段 SSBsaWtlIHlvdQ==
就是用 base64 编码 I like you
得到的字。
要“破解”也非常简单,你只要在网上搜索 base64 在线编码、解码就有工具。如果要使用代码,类似于这样:
import base64
# 开发人员编码
byte_str = "I like you".encode('utf-8')
encode_str = base64.b64encode(byte_str)
print(encode_str) # 得到 SSBsaWtlIHlvdQ==
# 解码
decode_str = base64.b64decode("SSBsaWtlIHlvdQ==")
print(decode_str.decode("utf-8")) # 得到 "I like you"
算法2:urlencode
URL 编码, 和 base64 一样,只是编码算法,不能称为加密。 记住,编码方式,只要你通过观察看到的字符串的特征,分析出编码方式,是可以很轻易的解码的。
肉眼看不见具体意思,所以这也是防君子,不妨小人的所谓 “加密方式”。
比如:base64的特征是尾部经常带有=
号, url 编码的特征是 %
很多。
我们经常在浏览器中看到这样的地址:
http://example.com/?q=%E8%8F%9C%E9%B8%9F
后半段带有很多百分号的就是 url 编码,你同样可以通过搜索对应的工具直接解码,得到原始数据:
http://example.com/?q=菜鸟
对应的 python 代码是这样的:
from urllib.parse import quote, unquote
q = '菜鸟'
# url 编码, 得到 http://example.com/?q=%E8%8F%9C%E9%B8%9F
url = 'http://www.baidu.com/?text={}'.format(quote(q))
# 解码
b = unquote('%E8%8F%9C%E9%B8%9F') # 得到: 菜鸟
算法3: md5
md5 不是编码,也不是加密,它叫做摘要算法,又称哈希算法和散列算法。 他的主要作用是:
- 防止篡改
- 校验数据
比如你下载了一个软件,会担心这个软件被人修改,植入了病毒。软件开发者为了防止自己的软件被别人修改,会在官网附带一个摘要信息。比如 https://dl.snipaste.com/sha-1.txt 这个网址就是该软件每个版本的摘要信息。
当你下载好软件以后,利用摘要算法检测工具检测改软件,算出他的摘要信息,如果和官方提供的一致,说明软件没有被修改;如果不一致,就说明这个软件被篡改了。
摘要算法的另一个应用场景是用来保存密码。我们日常注册账号输入的密码通常不会直接保存在数据库,而是经过摘要(或者是加密)处理以后保存在数据库当中。你可以通过在线工具对任意数据进行 md5 “加密”,这里提供 python 版代码:
import hashlib
hash = hashlib.md5()
# 明文密码是 hello yuz
hash.update(b"hello yuz")
hash_str = hash.hexdigest()
# 得到数据:bfb3f4712d0b04e8348a3fb5fa0b9bc2
# 保存到数据库
注意:摘要算法是不可逆的,通过 bfb3f4712d0b04e8348a3fb5fa0b9bc2 得不到原始数据 hello yuz 。所以通过存在数据库里面的密码无法获知你真正的密码。
为什么密码会被盗?
密码被盗通常是因为黑客利用了摘要算法的另一个特性攻击了数据库,这种方式叫撞库。
对于单一的摘要算法,有一个特征:只要你的原始数据是固定的,得到的 hash 值也会一样。比如 hello yuz 得到的就是 bfb3f4712d0b04e8348a3fb5fa0b9bc2 。黑客就是利用这种对应关系,将很多人常用的密码和对应的 hash 值做成一个关系表(彩虹表),然后一一去尝试。
比如很多人喜欢把密码生成 8888, abc123。 黑客只需要将这些密码提前算出对应的 hash 值保存起来,就可以尝试攻破你的账号。
什么是加盐?
上面的例子提到,黑客可以利用彩虹表套取你的密码,所以纯粹的摘要算法不是一种特别安全的方式去存储密码。但是我们可以采取“加盐” 的方式提高安全性。
网站开发者会提供一个类似于秘钥的东西,我们称为 salt, 其实就是一个随便起的字符串。然后将原始密码 + salt 得到一个新字符串,再对他进行 hash。
只要 salt 不被黑客知道,就没有办法利用彩虹表来攻击数据库。以下是加盐版的 python 代码:
salt = 'the salt'
pwd = '8888'
salt_pwd = pwd + salt
hash = hashlib.md5()
hash.update(salt_pwd.encode('utf-8'))
hash_str = hash.hexdigest()
在测试过程中,如果公司的密码是通过摘要算法生成的,可以找开发小哥哥要盐, 然后通过对应的摘要算法验证数据库密码。
算法 4:SHA1
SHA1 和 md5 一样,也是摘要算法,还有 SHA256, SHA512。 我们看到的区别就是长度不一样。长度越长,理论上更加安全,同时也意味着速度更慢。
以下是sha1 的代码,和 md5 几乎一样:
s = hashlib.sha1()
s.update(b"hello yuz")
sha_str = s.hexdigest()
总结
- 本文我们提到的“加密” 算法,都是伪加密,只有盐(salt)和密码类似;
- 真正的加密算法也有很多,下节再详细补充。
- base64 编码常用于在URL、Cookie、网页中传输少量二进制数据;
- 优点:速度快,肉眼不可理解
- 缺点:编码比较长,非常容易被破解,仅适用于加密非敏感信息
- url 编码常用于 URL 数据的编码和解析;
- md5 是最经典,使用最广泛的摘要算法。
- 部分公司会采用 md5 进行密码的保存
- 还有公司会采用其他更适合对密码进行摘要的算法,具体找开发
- sha1, sha256, sha512 比 md5 安全性更高,但是速度更慢,同时存储数据的时候耗费的资源会更多。