最近有一个业务需求,需要前端传递一个密码到后端,期间要对传递的密码通过进行对称加密,我们约定使用成熟的AES加密方法。

前端使用php,后端用python,但是发现前端兄弟加密后的字符串,在python端解密后末尾总会有16字节长度的\x10字符内容,通过python的ord('\x10')输出可知,这就是数字16的Unicode code。

众所周知,在使用AES进行对称加密之前,需要将加密的内容长度补全至16的倍数。如果前端兄弟无法解决加密内容中总有额外的16字节\x10字符的问题,那么后端就要考虑多余的处理逻辑,看起来奇奇怪怪的。

于是我百度了下php的openssl_encrypt函数,发现其中option选项有4个:

- 0
- OPENSSL_RAW_DATA=1
- OPENSSL_ZERO_PADDING=2
- OPENSSL_NO_PADDING=3

其中赫然写着OPENSSL_NO_PADDING,字面意思很好理解了,应该就是就是不会自动追加(补全)的意思,再看前端兄弟用的是OPENSSL_RAW_DATA。于是替换为OPENSSL_NO_PADDING后,果然没有了\x10的内容,问题暂时解决了。

然后我又回头想了一想,为什么OPENSSL_RAW_DATA会自动追加一个16字节的\x10呢,这肯定是有原因的。

因为在之前的测试中,我们在调用php的openssl_encrypt函数之前,已经手动对加密的字符进行了补全,保证其长度是16的倍数。如果不补全会怎样?

我手动试了一下:

<?php
$str = '1234567890'
$add_data_zero_padding = openssl_encrypt($str, 'AES-128-CBC', $key, $options=OPENSSL_ZERO_PADDING, $iv);
$add_data_no_padding = openssl_encrypt($str, 'AES-128-CBC', $key, $options=OPENSSL_NO_PADDING, $iv);
$add_data_raw_data = openssl_encrypt($add_str, 'AES-128-CBC', 'eNg6geeCinee0kee', $options=OPENSSL_RAW_DATA, 'nesejeiP6du0quie'); var_dump($add_data_zero_padding);
var_dump($add_data_no_padding);
var_dump($add_data_raw_data); echo "base64 encode:\n";
var_dump(base64_encode($add_data_raw_data));
?>

然后输出结果就是:

bool(false)
bool(false)
string(32) "�q$B�7��*���vE0�+��J.8t�[Bt�"
base64 encode:
string(44) "jHEkQrs3hBG+DiqE/4B2RTCUK6wE5r1KLjh03VtCdPs="

果然,如果没有补全,那么OPENSSL_ZERO_PADDINGOPENSSL_NO_PADDING会加密失败。而OPENSSL_RAW_DATA加密的内容,解密后的字节内容是:

b'NulhIKidvmW6jaFK4T9uqJyuwrlEo\x03\x03\x03'

如此一来,其实不用去细看文档也能推理出OPENSSL_RAW_DATA自动补全的含义了,因为补全的内容最后还需要还原为原始字符串,怎么知道哪些字符是补全上去的,哪些字符是原始字符呢?

php逻辑是这样的,我补全的长度至少是1,最长是16,代表这个长度的数字,正好都可以用一个Unicode字符表示,比如1就是\x01,16就是\x10

如果加密的内容长度是15字节,那么就在最后补全一个\x01,还原的时候,只需要读取最后一个字节内容,转换为数字,得到1,就知道加密前只追加了1个字节,那么就把末尾的1个字节内容去掉即可。

如果加密的内容长度正好是16字节呢,为了还原,那么就必须要在末尾追加16\x10,还原的时候读取最后一个字节并转换为数字,就知道加密时候追加了16字节,那么把末尾的16个字节去掉即可。

其实用python代码表示这个补全和还原的逻辑如下:

BLOCK_SIZE = 16  # 16 Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE) # 至少会追加16字节的内容
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

chrord 含义如下:

chr(i, /)
Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. ord(c, /)
Return the Unicode code point for a one-character string.

使用php的openssl_encrypt和python的pycrypt进行跨语言的对称加密和解密问题的更多相关文章

  1. JAVA中AES对称加密和解密以及与Python兼容

    引言:本文主要解决Java中用AES加密及解密,同时可通过Python脚本对Java加密后的字符进行解密的操作. 由于近期工作中用到需要使用Java对一串密钥进行加密,并且后台通过Python语言读取 ...

  2. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现[转载]

    原文:http://outofmemory.cn/code-snippet/35524/AES-with-javascript-java-csharp-python-or-php c#里面的AES加密 ...

  3. C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  4. Python开发【模块】:M2Crypto RSA加密、解密

    M2Crypto 模块 快速安装: # 环境centos7.0,提前装好openssl(自行百度安装),windows装不上,暂不考虑了 [root@localhost ~]# pip install ...

  5. Golang、Php、Python、Java基于Thrift0.9.1实现跨语言调用

    目录: 一.什么是Thrift? 1) Thrift内部框架一瞥 2) 支持的数据传输格式.数据传输方式和服务模型 3) Thrift IDL 二.Thrift的官方网站在哪里? 三.在哪里下载?需要 ...

  6. (二)Python是一门什么样的语言?

    在学习python是一门什么样的语言之前首先需要知道什么是编译和解释? 编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快; 而 ...

  7. 跨语言学习的基本思路及python的基础学习

    笔者是C#出身,大学四年主修C#,工作三年也是C#语言开发.但在学校里其他的语言也有相应的课程,eg:Java,Php,C++都学过,当然只是学了皮毛(大学嘛,你懂得),严格来说未必入门,但这些语言的 ...

  8. Python pycrypto 加密与解密

    参考: python 使用 pycrypto‎ 实现 AES 加密解密 参考: 分组对称加密模式:ECB/CBC/CFB/OFB 代码示例 : import hashlib from Crypto.C ...

  9. Python面试题之python是一种什么语言及优缺点

    1.说说python是一种什么语言? 参考答案:python是一门动态解释性的强类型定义语言 编译型vs解释型 编译型优点:编译器一般会有预编译的过程对代码进行优化.因为编译只做一次,运行时不需要编译 ...

  10. 【Python】 基于秘钥的对称加密

    [Crypto] 关于用python进行信息的加密,类似的解决方案有很多比如用base64编码进行encode,再或者是hashlib来进行hash.但是还缺少一种明明场景很简单的解决方案,就是把利用 ...

随机推荐

  1. Arduino部分C语言含义之--“::”

    "::"在C++中表示作用域,和所属关系."::"是运算符中等级最高的.有三种作用. 1.作用域符号例如:A,B表示两个类,在A,B中都有成员member.那么 ...

  2. 淘宝H5 sign加密算法

    淘宝H5 sign加密算法   淘宝H5 sign加密算法 淘宝对于h5的访问采用了和客户端不同的方式,由于在h5的js代码中保存appsercret具有较高的风险,mtop采用了随机分配令牌的方式, ...

  3. OpenLayers 4326地图 根据距离设置地图分辨率

    问题:给一个距离,如何确定4326地图缩放等级或者分辨率使地图视口范围为这个距离 我本来打算计算从地图视口左上角到右下角的距离来计算地图缩放的,然后发现不好算,我也不会算,于是就计算水平方向距离的缩放 ...

  4. 幻兽帕鲁/Palworld/支持网络联机 v0.1.5.1

    游戏介绍 在广阔的世界中收集神奇的生物"帕鲁",派他们进行战斗.建造.做农活,工业生产等,这是一款支持多人游戏模式的全新开放世界生存制作游戏. 注意事项 先启动STEAM客户端,在 ...

  5. MySQL - [04] 分布式部署&主从复制&读写分离

    一.前言 Q1:为什么需要主从复制? 1.在业务复杂的系统中,有一条SQL语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务.使用主从复制,让主库负责写,从库负责读,这样即使主库出现了锁 ...

  6. 大数据之路Week08_day02 (Flume架构介绍和安装)

    Flume架构介绍和安装 写在前面在学习一门新的技术之前,我们得知道了解这个东西有什么用?我们可以使用它来做些什么呢?简单来说,flume是大数据日志分析中不能缺少的一个组件,既可以使用在流处理中,也 ...

  7. 玩转摄像头之MT9V034(最新打样,展示下,欢迎观摩,哈哈)低照度 红外透视应用

    分辨率:752*480  低照度 效果超好先上图 图像处理.物联网.fpga.stm32研究 我的店铺:ccjt.taobao.com 

  8. cypress route 拦截 zepto ajax 请求时候 response 返回 null 问题原因

    原文链接:https://blog.jijian.link/2020-08-03/cypress-zepto-ajax-response-null/ 如果你项目有如下几个巧合,大概率会发现一个 aja ...

  9. Windows编程----结束进程

    进程有启动就有终止,通过CreateProcess函数可以启动一个新的子进程,但是如何终结子进程呢?主要有四种方法: 通过主线程的入口函数(main函数.WinMain函数)的return关键字终止进 ...

  10. EmlBuilder:一款超轻量级的EML格式电子邮件阅读和编辑工具

    EmlBuilder 是一款超轻量级的电子邮件阅读和编辑工具,针对EML格式的文件具有非常强大的解析和容错能力,可实现超文本邮件的编写,并具备内嵌图片的编辑功能.该工具内部使用EmlParse对电子邮 ...