大家好,我是永强,就是老李之前经常给你们说的区块链大神、大学肄业却依然大公司 iOS 主程一波儿流、只生活在老李口中尚未真实露面的骗钱高手、老王的左膀右臂 ——— 赵永强。我和尼古拉斯赵四之间并没有什么强关联,我只是单方面认识他而已。
之前老李企图让我发表一些关于如何进行高端骗工资骗钱的教程,被我义正言辞地拒绝了:
毕竟是毕生绝学,不能就这么轻而易举地教给你们
不过后面有时间我可以给大家出一些关于“如何在公司混日子还能升职加薪”的入门级教程,传男不传女,独家绝技!敬请期待!
言归正传,那个一直以来我对加解密技术都是耿耿于怀的,因为很多年前有一次面试中被这东西给坑掉了,虽然我后来就自己对加解密中一些自己不懂的地方请教了对方而且他也没有给我讲清楚…
事情都过去好几年了,本人自我感觉已经一定程度掌握了一些关于加密的高端技术,因为决定出来装一波儿逼,时间比较紧张,我打算赶在 2020 年农历新年之前把逼装完,你们要注意配合。
我知道老李之前在社区发表了一些关于加密啊、解密啊之类的东西,甚至还扯上了什么 DH 什么 ECDH,又是质数又是椭圆曲线,不过这并不与本系列产生冲突,这并不重要,不要在意这些细节,他那个 too young too simple,sometimes naive…
这将是一个大概由四篇左右的文章组成的系列文章,所以在正式开始之前,我不得不强调一点 ——— 如下这几门学科的基础理论知识:
- 《离散数学》
- 《微分与积分》
- 《空间几何》
- 《概率论》
你并不需要具备。。。
不过你总得知道除了 html 和 css 之外的任意一门编程语言。尽管本人精通上到 CLanguage 下到 Perl 之类的各种语言,但是本文将采用世界上最好的语言进行一些程序演示,后面老李可能会使用 CLanguage 和 Golang 进行其他语言的演示补充。
简单说来呢,加解密技术就是分为两大类:
- 对称加解密
- 非对称加解密
其中,常见的对称加解密算法有 DES、3DES、AES;而非对称加解密技术比较典型的则是 RSA,就是什么公钥私钥证书什么乱七八糟的。
我们先从对称加解密开始,粗暴地说呢,对称加解密就是“加密和解密的时候用同一个密码”,听起来就非常对称,有没有?
用图表达一下就是:
最一开始的时候,我朝人民一般都是倾向于使用“天王盖地虎”,“宝塔镇河妖”这种加解密技术;然而,美帝用了一种叫做 DES 的技术进行对称加解密,这玩意一度成为业界通用的对称加解密技术,银行、五角大楼都爱用这玩意,可惜好景不长、世风日下、世态炎凉,这玩意的破解成本越来越低越来越低~~ 于是,为了续命,就又有一些白胡子老头给 DES 打补丁,缝缝补补搞出来一个玩意叫做 3DES,继续用,又不是不能用…这个顾名思义就行了,别打我,真的:3DES 就是用 DES 处理(注意是处理,我没说是加密)了三次的意思。就目前看来,3DES 实际上用的可能也并不是十分广泛了,所以如果大家在选择对称加解密技术的时候,尽量避开 DES 和 3DES 就可以了。
呵呵,喜新厌旧的沙雕人类…虽然 DES 已经没人用了,但毕竟也是辉煌过,我觉得还是得动手表演一波儿。我们知道,在 php7 里,原来的 mcrypt 系列加解密已经被放弃掉了,官方建议我们使用 openssl 系列来进行加解密,所以确保你的 PHP 环境里安装了 openssl 标准扩展。
<?php
// 这个函数打印出来 openssl 支持的所有加密方法以及模式的组合
$arr_ava_methods = openssl_get_cipher_methods();
print_r($arr_ava_methods);
文件保存成 test.php 后,执行一把:php test.php | grep des,结果你们感受一下:
其中带有 ede 的,比如 des-ede* 这样的就表示是 3DES。还有这么多奇奇怪怪的后缀是什么含义?回头再说…又不是不能用。
筛选一下,我们看 des(非 des3)有几种带着尾巴的具体方法:
- des-cbc
- des-cfb*(注意后面的通配符星号)
- des-ecb
- des-ofb
我们先用传统 des 方法继续进行装逼表演:
<?php
// 我们就选用 des-ecb 方法进行一次 des 加密
$ava_methods = openssl_get_cipher_methods();
$my_method = 'des-ecb';
if (!in_array( $my_method, $ava_methods) ) {exit( '错误的加密方法'.PHP_EOL);
}
$key = "123456";
$data = "helloMOTO";
echo "明文:".$data.PHP_EOL;
$enc_data = openssl_encrypt($data, $my_method, $key);
echo "密文:".$enc_data.PHP_EOL;
$dec_data = openssl_decrypt($enc_data, $my_method, $key);
echo "明文:".$dec_data.PHP_EOL;
保存为 test.php 执行一把:
完美!就像老王的 meshbox 一样,完美!
简单解析一下:
换个方法继续一下:我们使用 openssl_get_cipher_methods() 函数获取到可以使用的所有 des 加密方法,然后简单判断一下我们选用的方法是否在其中;紧接着我们用 123456 作为密码,helloMOTO 作为明文内容,openssl_encrypt() 就是加密函数,openssl_decrypt() 就是解密函数,具体的函数原型出门左拐查手册,总之一切都是这么的完美!
<?php
// 我们就选用 des-ecb 方法进行一次 des 加密
$ava_methods = openssl_get_cipher_methods();
$my_method = 'des-cbc';
if (!in_array( $my_method, $ava_methods) ) {exit( '错误的加密方法'.PHP_EOL);
}
$key = "123456";
$data = "helloMOTO";
echo "明文:".$data.PHP_EOL;
$enc_data = openssl_encrypt($data, $my_method, $key);
echo "密文:".$enc_data.PHP_EOL;
$dec_data = openssl_decrypt($enc_data, $my_method, $key);
echo "明文:".$dec_data.PHP_EOL;
执行一波儿,结果如下图:
并不完美,报错了,一个 warning 级的错误,虽然并不影响加密和解密,但是毕竟是报错了,错误原文我复制粘贴过来,你们感受下:
PHP Warning: openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended in /home/ubuntu/lab/test.php on line 10
大概意思就是:用了一个并不推荐而且不安全的空 iv 在 test.php 的第十行。我正在翻译的这句的时候,已经精通英语的老李在旁边跟我说“你这翻译也太硬了,要学会人性化,看好了,一看你这就是没上过全日制大学本科的恶果”:
PHP 警告:openssl_encrypt():iv 向量最好别是空的,不推荐这么用,而且这样并不安全~
什么是 iv 向量?先抛开这个问题,我先写一段代码,让他能跑起来:
<?php
$ava_methods = openssl_get_cipher_methods();
$my_method = 'des-cbc';
if (!in_array( $my_method, $ava_methods) ) {exit( '错误的加密方法'.PHP_EOL);
}
// 处理 iv 向量的两行代码
$iv_length = openssl_cipher_iv_length($my_method);
$iv = openssl_random_pseudo_bytes($iv_length);
$key = "123456";
$data = "helloMOTO";
echo "明文:".$data.PHP_EOL;
$enc_data = openssl_encrypt($data, $my_method, $key, 0, $iv);
echo "密文:".$enc_data.PHP_EOL;
$dec_data = openssl_decrypt($enc_data, $my_method, $key, 0, $iv);
echo "明文:".$dec_data.PHP_EOL;
注意到 8、9、10 和 15、17 两行,均为 iv 向量做了改动,然后这次代码保存了运行一波儿:
完美!就像老王的 meshbox 一样,完美!
那么,在 des 加解密中,我们遗留了两个问题:
- des-cbcdes-cfb 等这些后缀是什么意思?
- iv 向量是什么鬼东西?
长按或许有惊喜