基于 OpenSSL 实现国密 SM4 加解密

转载请注明来源地址:http://her-cat.com/posts/2021/08/23/php-openssl-sm4/

if (!in_array('sm4-cbc', openssl_get_cipher_methods())) {
    printf("不支持 sm4\n");
}

$key = 'her-cat.com';
$iv = random_bytes(openssl_cipher_iv_length('sm4-cbc'));

$plaintext = '她和她的猫';

$ciphertext = openssl_encrypt($plaintext, 'sm4-cbc', $key, OPENSSL_RAW_DATA , $iv);

printf("加密结果: %s\n", bin2hex($ciphertext));

$original_plaintext = openssl_decrypt($ciphertext, 'sm4-cbc', $key, OPENSSL_RAW_DATA , $iv);

printf("解密结果: %s\n", $original_plaintext);

运行结果:

加密结果: 45cd787b0a84603ae8fd443b81af4d17
解密结果: 她和她的猫
博客地址:她和她的猫,欢迎关注。
本文转载于网络 如有侵权请联系删除

相关文章

  • php图形图像处理之生成验证码

    \(^o^)/~现在网上越来越离不开验证码了,不知道小伙伴们知不知利用php的GD库就可以生成验证码,Σ(⊙▽⊙"a......首先介绍几个需要用的函数。1.imagesetpixel()这个函数可以进行像素点的绘制,在验证码中,我们称之为“噪点”,简直是一个神器。不知道小伙伴有没有想起来验证码上的点点呢,就是用这个函数生成的。2.str_shuffle()利用这个打乱字符串,然后利用substr()截取给定的位数,就可以生成一个随机字符串啦。实例:1<?php 2 3$img=imagecreatetruecolor(100,50); 4$black=imagecolorallocate($img,0x00,0x00,0x00); 5$green=imagecolorallocate($img,0x00,0xFF,0x00); 6$white=imagecolorallocate($img,0xFF,0xFF,0xFF); 7imagefill($img,0,0,$white); 8//生成随机的验证码 9$code=make(5); 10imagestring($i

  • 误操作YUM导致error,rpmdb解决方法

    1、由于搭建Kubernetes集群,误操作导致执行yum出现Error:rpmdbopenfailed错误,如下图 根据提示我们可以知道rpm数据库在yum安装过程中使用导致RPM数据库损坏了,需要我们重新构建,下面是重新构建的方法及步骤,操作如下 [root@JDCloud_Server_v1yum.repos.d]#cd/var/lib/rpm 1)删除RPM库 [root@JDCloud_Server_v1rpm]#rm-rf__db.00* 2)重新构建rpm数据库 [root@JDCloud_Server_v1rpm]#rpm--rebuilddb 3)用yumcleanall重新测试 [root@JDCloud_Server_v1rpm]#yumcleanall OK,成功了,问题解决了。 [root@JDCloud_Server_v1~]#yum-yinstallvim

  • ArrayDeque 源码解读

    Java里有一个叫做Stack的类,却没有叫做Queue的类(它是个接口名字)。当需要使用栈时,Java已不推荐使用Stack,而是推荐使用更高效的ArrayDeque;既然Queue只是一个接口,当需要使用队列时也就首选ArrayDeque了(次选是LinkedList)。 总体介绍要讲栈和队列,首先要讲Deque接口。Deque的含义是“doubleendedqueue”,即双端队列,它既可以当作栈使用,也可以当作队列使用。下表列出了Deque与Queue相对应的接口:下表列出了Deque与Stack对应的接口:上面两个表共定义了Deque的12个接口。添加,删除,取值都有两套接口,它们功能相同,区别是对失败情况的处理不同。一套接口遇到失败就会抛出异常,另一套遇到失败会返回特殊值(false或null)。除非某种实现对容量有限制,大多数情况下,添加操作是不会失败的。虽然Deque的接口有12个之多,但无非就是对容器的两端进行操作,或添加,或删除,或查看。明白了这一点讲解起来就会非常简单。ArrayDeque和LinkedList是Deque的两个通用实现,由于官方更推荐使用Aarr

  • GLSL ES 语言—变量数值类型

    数值类型 GLSL支持两种数据值类型:数据类型:整数(比如:0、1、2)和浮点数(比如:3.14、29.98)。没有小数点(.)的值被认为是整数,而有小数点的值则被认为是浮点数。布尔值类型:true和false两个布尔常量。注意:GLSLES不支持字符串类型。变量变量名需要符合下面规则:只包括a~z,A~Z,0~9和下划线(_)。变量名的首字母不能是数字。不能以gl、webgl或webgl开头,这些已经被OpenGLES保留了。不能是GLSLES中的关键字和保留字,但你的变量的一份可以是它们。GLSLES是强类型语言GLSLES要求你具体指明变量的数据类型:<类型><变量名>如vec4a_position。在进行赋值操作(=)时,等号左右两侧的数据类型必须一样,否则会出错。基本类型类型描述float单精度浮点数类型int整型数bool布尔值下面是声明基本类型变量的例子:floatklimt;//变量为一个浮点数 intutrillo;//变量为一个整型数 booldoga;//变量为一个布尔值复制赋值和类型转换使用等号(=)可以将值赋给变量,GLSLES是强类型

  • 七大工业机器人离线编程软件大PK

    通常来讲,机器人编程可分为示教在线编程和离线编程。我们今天讲解的重点是离线编程,通过示教在线编程在实际应用中主要存在的问题,来说说机器人离线编程软件的优势和主流编程软件的功能、优缺点进行深度解析。示教在线编程在实际应用中主要存在以下问题:-示教在线编程过程繁琐、效率低。-精度完全是靠示教者的目测决定,而且对于复杂的路径示教在线编程难以取得令人满意的效果。示教在线编程相比,离线编程又有什么优势呢?-减少机器人的停机时间,当对下一个任务进行编程时,机器人仍可在生产线上进行工作。-使编程者远离了危险的工作环境。-适用范围广,可对各种机器人进行编程,并能方便的实现优化编程。-可对复杂任务进行编程。-便于修改机器人程序。看到离线编程的这些优点后,是不是迫不及待的想看看离线编程软件长什么样子?那么往下看吧~下面详细介绍一下主流的离线编程软件。__1、RobotMaster__Robotmaster来自加拿大,由上海傲卡自动化公司代理,是目前全球离线编程软件中顶尖的软件,几乎支持市场上绝大多数机器人品牌(KUKA,ABB,Fanuc,Motoman,史陶比尔、珂玛、三菱、DENSO、松下……),Ro

  • 学会自定义主题,让你的仪表盘瞬间高逼格~

    今天这一篇跟大家介绍如何在PowerBI和Tableau中自定义主题来更换默认主题,让你的仪表盘随心所欲的变换主题。关于Excel的主题配色相关内容已经推送过很多篇了,这里只涉及PowerBI和Tableau的主题自定义。可视化基础——色彩篇office颜色配置技巧与自定义颜色主题妈妈再也不用担心我不会配色了一个神奇的配色网站~因为PowerBI和Tableau这种以快捷BI著称商务智能工具,颜色搭配上都已经提供了大量的预设色板供使用者切换使用。但是考虑到很多企业或者公司比较注重报告或者仪表盘的整体风格,并通常会要求与自身的VI系统一致,所以自定义配色主题就很有必要。PowerBI自定义配色主题Tableau自定义配色主题首先我使用上次Excel演示爬取数据的案例所抓取的大学排行榜数据做了一个简单仪表盘。默认的配色风格如下:这就是默认的PowerBI配色主题,整体来讲,虽然也算不上丑,但是这套配色的颜色过于高亮,其中的红绿色组尤为如此,给人的感觉偏浮躁、略微刺眼。PowerBI的菜单里设置有主题颜色切换入口,但是却并没有提供可用的多套配色方案。如下所示的入口中,如果你没有提前准备主题的

  • 与Ajax同样重要的jQuery(1)

    jQuery框架jQuery1.4是企业主流版本,从jQuery1.6开始引入大量新特性。最新版本2.1.1,这里讲解以1.8.3为主(新版本主要是浏览器兼容问题以及新特性)jQuery提供jquery-1.8.3.js和jquery-1.8.3.min.jsjquery-1.8.3.jsjQuery框架源码,没有被精简,体积较大(主要用来研究jQuery源码),企业开发时,需要导入jquery-1.8.3.min.js(精简过)1.jQuery程序快速入门window.onload=function(){...}等价于$(document).ready(function(){...});①:jQuery基本使用传统Js写法:<scripttype="text/javascript"> window.onload=function(){ alert("传统JS,Ok"); } </script> jQuery写法: <scripttype="text/javascript"src="..

  • 数据恢复:ORA-600 2662 错误的SCN增进应对

    正文:在损失了日志,进行基于损坏的恢复时,可能会因为_allow_resetlogs_corruption参数的使用而收到ORA-6002662的错误报告。2662错误是指:AdatablockSCNisaheadofthecurrentSCN,也就是说数据块的SCN大于了系统的最大SCN,这意味着数据库出现了异常。介绍一下SCN的基本知识:SCN可以说是Oracle中的很基础,但同时也是很重要的东西,它是一个单向增长的“时钟”,广泛应用于数据库的恢复、事务ACID、一致性读还有分布式事务中。那么除了这些,SCN还有以下一些知识点: SCN的内部存储方式:在Oracle内部,SCN分为两部分存储,分别称之为scnwrap和scnbase。实际上SCN长度为48位,即它其实就是一个48位的整数。只不过可能是由于在早些年通常只能处理32位甚至是16位的数据,所以人为地分成了低32位(scnbase)和高16位(scnwrap)。为什么不设计成64位,这个或许是觉得48位已经足够长了并且为了节省两个字节的空间:)。那么SCN这个48位长的整数,最大就是2^48(2的48次方,281万亿

  • MongoDB 安装配置

    官方网站:https://www.mongodb.com/MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。配置文件systemLog: destination:file path:/var/log/mongodb/mongo.log logAppend:true storage: dbPath:/var/lib/mongodb processManagement: fork:true net: bindIp:127.0.0.1 port:27017复制启动$mongod--config/usr/local/etc/mongod.conf #客户端连接 $mongo127.0.0.1:端口/数据库复制关闭useadmin db.shutdownServer()复制

  • 架构遗留应用程序和现代化方案

    架构遗留应用程序和现代化方案     毫无疑问,我们所有从事软件工程师或架构师工作的人都曾在任何时候接触过遗留应用程序。在这篇文章中,我们的目标是了解遗留系统和重构它的方法,同时探索各种迁移到云的方案。我们还将研究遗留应用可以被现代化的其他方面,包括软件开发方法,以及构建和部署程序。 遗留应用     我们中的许多人喜欢在全新的软件系统中工作,因为它们涉及到从头开始设计的现代技术栈。这样的系统对之前的工作没有什么限制,也不需要和现有的系统进行整合。然而,无论我们今天拥有什么样的新系统,明天都会成为一种遗产。我们经常发现自己在现有的软件系统上工作,能够这样做是一种宝贵的技能。遗留应用是一个现有的软件系统,它仍然在使用,但也难以维护。使用一个遗留的应用程序会产生一些挑战。 问题和挑战      使用一个遗留的应用程序通常会带来各种需要克服的问题。其中最重要的是难以维护和扩展。它可能包括旧的、过时的技术,此外,往往没有遵循开发的最佳实

  • mongodb 聚合查询

    mongoshell操作 aggregate 使用mongodb的aggregate进行聚合操作,改操作传入的参数是一个数组 aggregate操作的参数 match相当于mysql的where,传入的是筛选条件 示例: {$match:{ 'os':'win' } } 复制 group相当于mysql的groupby,传入的是要分组聚合的字段 示例: {$group:{ _id:"$name", count:{ $sum:1 } } } 复制 与mysql对比示例 分组查询count #mysql selectname,count(*)fromtablegroupbyname; #mongoshell db.collection.aggregate([{$group:{_id:'name',count:{$sum:1}}}]) 复制 先筛选后分组查询 #mysql selectname,count(*)fromtablewhereos='win';groupbyname; #mongoshell db.collection.aggregate([{$match:{

  • 牛客OI周赛7-普及组

    牛客OI周赛7-普及组 比赛链接 A救救喵咪 这题非常简单,纯模拟就可以过,不用解释 代码如下 #include<bits/stdc++.h> usingnamespacestd; structgg { intx,y; }a[10005]; intmain() { intn; cin>>n; for(inti=1;i<=n;i++) cin>>a[i].x>>a[i].y; for(inti=1;i<=n;i++) { intans=0; for(intj=1;j<=n;j++) if(i!=j&&a[j].x>a[i].x&&a[j].y>a[i].y) ans++; cout<<ans<<endl; } } 复制 B救救兔子 很明显是二分,但我为装逼用了set。 set自带去重和排序,还有lower_bound(x)函数可以返回大于或等于x的第一个数 lower_bound(x)返回的就是大于或等于x的第一个数,有因为排好了序,所以lowe

  • 深入理解进程和线程

    在之前的博客里面(进程通信),我简单的区分了一下进程和线程,然后过了一个月我发现之前的理解远远不够。 先把之前的简单理解贴一下, 进程是装入内存运行的程序段,是许多的系统对象拥有权的集合,换句大家经常引用的话说进程是资源分配的基本单位。 线程是CPU运行调度的基本单位,线程必须被包含在进程中,一个进程可以有很多线程(至少有一个),这些线程有自己的资源(如栈,寄存器)也共享进程的许多资源。   我把我的理解过程一步步的给大家贴出来,希望这样能让各位更好的理解进程与线程。 在理解下面的内容之前,需要先理解虚拟地址空间与虚拟内存的概念。 (简单来说,我们代码中的指针地址都是cpu的逻辑地址,而不是实际上的物理地址(内存地址),这就是虚拟地址,虚拟地址很好的解决了地址空间隔离问题。 我们很多时候不需要将整个程序都放入内存中(内存的大小是有限的),部分程序可以先放在磁盘上等需要时再调入内存(可能几乎不调用),这样就利用有限的内存放入更多的进程。所以这个磁盘上的伪内存就是虚拟内存。)   其实我的理解过程来源于一个很常见又比较难理解的问题:我们知道main函数可以理解为一个主线

  • ThinkPHP3.1快速入门教程

    ThinkPHP3.1快速入门教程 http://www.thinkphp.cn/info/155.html   --------------------------------------------------------------------- ThinkPHP 3.1 完全开发手册   http://doc.thinkphp.cn/manual/

  • oracle11g重新安装oem

    1.重新设置syssysmanDBSNMP密码alteruserdbsnmpidentifiedby**; 2.select'droppublicsynonym'||synonym_name||';'fromall_synonymswheresynonym_namelike'MGMT_%';select'droppublicsynonym'||synonym_name||';'fromall_synonymswheresynonym_namelike'SMP_%';select'droppublicsynonym'||synonym_name||';'fromall_synonymswheresynonym_namelike'EMD_%';select'droppublicsynonym'||synonym_name||';'fromall_synonymswheresynonym_namelike'ECM_%';全部删除同义词 3.dropusersysmancascade;droproleMGMT_USER;dropuserMGMT_VIEWcascade;dropuserMGMT

  • 面试八股文

    leetcode https://github.com/labuladong/fucking-algorithm C++面试问题 https://github.com/huihut/interview https://www.cnblogs.com/LUO77/p/5771237.html

  • 过去的2017和已经到来的2018

    忙碌且充实的2017年   一、写个前言   看看博客园,好多园友都在写年终总结和下年计划,无法抚平心中的冲动,不写写总结,不写写规划,总感觉还不如一条咸鱼。 二、关于工作   目前任职于山西某大型超市信息中心,懂点业务,会点技术,算是尽心尽职且忙忙碌碌的一年,除了日常工作外,重点参与了两个项目:     1、数据报表项目,通过项目学会了Kettle、SSIS工具传输数据;     2、新零售转型项目,项目依然在进行中,项目中主要和第三方软件公司(厦门公司)的开发工程师对接接口,了解零售行业的园友们应该知道,无非就是些商品信息、库存、价格等基础资料;对接过程中,对厦门工程师的印象极好,敬业、专注;当然在对接过程自身水平还是有明显进步的,对平时接触不到的业务有所了解,当然T-SQL写的更溜了,哈哈。 三、关于生活   生活方面喜讯更多一点:     1、新房在年初装修好了,国庆的时候搬了进去。     2、小棉袄在11月初出生了,家里突然多了个小娃,手忙脚乱的。 四、关于读书   虽然干着IT边缘的工作,感觉在周围同事里水平算好的,但比起纯粹的开发或者专业人士,总是感觉差了点

  • 调研一类软件的发展演变( 1000-2000 words, in Chinese)

    WARING:大量个人观点,可靠性突出一个没有。      随着时代的发展,科技的用途也在发生着改变。最初,计算机是高端科学家用来计算导弹路线、模拟核弹爆炸用的,而现在计算机更多是平凡百姓家的一台娱乐设备。当今的互联网的根须遍及世界,而最初的阿帕网仅仅是想确保在遭受打击后有至少一条通畅的线路。至于浏览器,最初是一个“翻译软件”。 一、Lynx:“曾是最好的浏览器.”   由于机器语言基本没法看,所以基本所有的软件都是在进行翻译工作。而这些来自网络、这些来自主机之外的信息,由于远距离传输的限制以及被转换了格式,那么作为接收方自然需要一个“浏览器”来对这些外来的信息进行还原。在研究早期浏览器的过程中,我认为Lynx是比较有代表性的。自1995年,Lynx在GPL下发布以来,Lynx直到现在依旧时不时会有更新(即使更新的象征意义大于实际意义)。它是目前仍在更新与使用的浏览器中历史最悠久的,并且一直到现在,Lynx仍然是一款纯文字浏览器,就像一块完美的活化石一样。在Lynx下有两种浏览方式:1.以方向键选择超链结,而Lynx

  • js的浏览器判断方法

    使用navigator.userAgent来判断浏览器类型。 1、浏览器版本号函数: varbr=navigator.userAgent.toLowerCase();  varbrowserVer=(br.match(/.+(?:rv|it|ra|ie)[\/:]([\d.]+)/)||[0,'0'])[1];    2、js浏览器判断函数 functionuserBrowser(){    varbrowserName=navigator.userAgent.toLowerCase();    if(/msie/i.test(browserName)&&!/opera/.test(browserName)){      alert("IE");      return;    }elseif(/firefox/i.test(browserName)){

  • Spring Boot2 系列教程(二十三)| Shiro 与 Redis 多级缓存问题

    微信公众号:一个优秀的废人。如有问题,请后台留言,反正我也不会听。 前言 来自不愿意透露姓名的小师弟的投稿。这篇主要讲了,项目中配置了多缓存遇到的坑,以及解决办法。 发现问题 在一次项目实践中有实现多级缓存其中有已经包括了Shiro的Cache,本以为开启redis的缓存是一件很简单的事情只需要在启动类上加上@EnableCaching注解就会启动缓存管理了,但是问题出现了。 重要错误日志截图 java.lang.IllegalStateException:@BeanmethodShiroConfig.cacheManagercalledasabeanreferencefortype[org.apache.shiro.cache.ehcache.EhCacheManager]butoverriddenbynon-compatiblebeaninstanceoftype[org.springframework.data.redis.cache.RedisCacheManager].Overridingbeanofsamenamedeclaredin:classpathresourc

  • Canvas:飞机大战

    Canvas:飞机大战 最开始我们要初始化信息,我们有五个状态:游戏封面,加载状态,运行状态,游戏暂停,游戏结束。 我们还需要 得分--score,生命--life。 varSTART=1;//初始状态 varLOADING=2;//加载状态 varRUNNING=3;//游戏运行状态 varWAIT=4;//游戏暂停状态 varGAMEOVER=5;//游戏结束状态 varstate=START;//初始状态 varscore=0;//游戏得分 varlife=5;//我方飞机的生命值复制 1.游戏开始界面 我们创建一个背景的构造函数,为了制造背景的动态效果,我们创建两张背景 第一张图片的位置为(0,0) 第二张图片我们放在第一张图片的上面, 当第一张图片运动到最底下时,然后把第一张图片放在第二张图片的上面 当第二张图片运动到最底下时,然后把第二张图片放在第一张图片的上面 varbg=newImage();//创建一个图片对象 bg.src="img/background.png"; varBG={ imgs:bg, width:480, height:850

相关推荐

推荐阅读