关于openssl:OpenSSL-300-设计五|遗留问题遗留-Provider-模块ENGINE-API

译|王祖熙(花名:金九 ) 蚂蚁团体开发工程师 负责国产化明码库 Tongsuo 的开发和保护 专一于密码学、高性能网络、网络安全等畛域 本文 2179 字 浏览 6 分钟 本文翻译 OpenSSL 官网文档:https://www.openssl.org/docs/OpenSSL300Design.html Tongsuo-8.4.0 是基于 OpenSSL-3.0.3 开发,所以本文对 Tongsuo 开发者同样实用,内容丰盛,值得一读! 明天带来的是 OpenSSL 3.0.0 设计最初一部分内容 《遗留问题、遗留 Provider 模块、ENGINE API》 ,已公布文章可查看文章列表。 遗留问题EVP 到低级 API 的桥接在某些中央,低级 API 构造被赋值给EVP_PKEY对象,对公共的EVP_PKEY的影响是它必须保留指向可能的低级构造的指针,并且在 libcrypto 外部必须晓得该低级构造的类型,每当具备这种指针的EVP_PKEY用于任何计算时,都必须查看低级构造是否产生了变动,并将其数据转换为能够与新的 Provider 一起应用的参数。 确定如何查看低级构造的内容是否产生了变动的具体机制有待确定,一种可能的办法是在低级构造中设置一个 dirty 计数器,并在EVP_PKEY构造中复制一个正本,每当低级构造发生变化时(例如,RSA_set0_key等函数必须执行递增操作),每当EVP_PKEY用于计算时,就会将其正本与低级脏计数器进行比拟,如果它们不同,则EVP_PKEY的 Provider 参数将应用低级构造的数据进行批改。 (另一个想法是通过遗留函数在EVP_PKEY中搁置一个回调函数,如果检测到低级别的更改,则更新参数) EVP办法创建者在 OpenSSL 1.1.x 中有能够轻松创立各EVP办法构造的性能,能够像这样找到: grep EVP_CIPHER_meth util/libcrypto.numgrep EVP_MD_meth util/libcrypto.numgrep EVP_PKEY_meth util/libcrypto.num相干类型低级 API 相当独立,因而除了在某些类型中增加了一个 dirty 标记外,所有低级 API 类型将放弃不变。关联的EVP_CIPHER、EVP_MD、EVP_PKEY_METHOD、EVP_MAC或EVP_KDF实例通过在遗留 Provider 模块中通过实现调度表来独自解决(见下文)。 遗留 Provider 模块一些被认为是“遗留”的算法(例如 IDEA)且具备以后的EVP_CIPHER、EVP_MD、EVP_PKEY_METHOD、EVP_MAC或EVP_KDF实现将移至一个名为 "Legacy" 的 Provider 模块,而不是咱们的默认 Provider 模块。 ...

September 6, 2023 · 1 min · jiezi

关于openssl:OpenSSL-300-设计四|代码维护FIPS-测试

译|王祖熙 (花名:金九 ) 蚂蚁团体开发工程师 负责国产化明码库 Tongsuo 的开发和保护专一于密码学、高性能网络、网络安全等畛域 本文 2862 字 浏览 8 分钟 本文翻译 OpenSSL 官网文档:https://www.openssl.org/docs/OpenSSL300Design.html Tongsuo-8.4.0 是基于 OpenSSL-3.0.3 开发,所以本文对 Tongsuo 开发者同样实用,内容丰盛,值得一读! 因为文章篇幅较长,明天带来的是 《代码保护、FIPS 测试》 局部内 后续内容将随每周推送残缺公布,请继续关注铜锁。 代码保护源代码构造/目录树的清理密码学实现(crypto/evp/e_*.c和大部分crypto/evp/m_*.c,以及任何定义EVP_CIPHER、EVP_MD、EVP_PKEY_METHOD、EVP_MAC或EVP_KDF的代码)必须移出 evp 目录,它们最终将成为一个或两个 Provider 的一部分,因而它们应该位于特定 Provider 的子目录中。 将创立一个新的目录providers/,用于寄存特定 Provider 的代码。providers/build.info定义了哪些源文件在哪些 Provider 模块中应用。 共享源代码FIPS Provider 模块和默认 Provider 将共享雷同的源代码,在不同的条件下,例如不同的#include门路或定义的宏不同(后者须要在构建零碎中增加反对)。上面是一个示例build.info文件,实现了这一点: PROVIDERS=p_fips p_defaultSOURCE[p_fips]=foo.cINCLUDE[p_fips]=include/fipsSOURCE[p_default]=foo.cINCLUDE[p_default]=include/default或者,应用宏: PROVIDERS=p_fips p_defaultSOURCE[p_fips]=foo.cDEFINE[p_fips]=FIPS_MODESOURCE[p_default]=foo.c留神:一些关键字还不是 build.info 语言的一部分。 条件代码咱们须要对编译时蕴含 FIPS 特定代码的办法进行统一解决,并在某些状况下排除 FIPS 不容许的代码。 编译时的管制将通过#ifdef FIPS_MODE来进行,这确保所有相干的文件都明确地为非 FIPS 或在 FIPS 模块外部进行编译,因为每个文件都将被编译两次(在默认 Provider 和 FIPS 模块中各一次),一次应用每个设置,因而应用具备恒定值的运行时if语句没有益处。(此外,运行时设置并不总是无效(例如在扩大诸如BLOCK_CIPHER_custom之类的宏时,会创立全局变量或函数指针。) 构建零碎将通过应用-DFIPS_MODE编译 FIPS Provider 对象文件,以及不带命令行定义的来自雷同源的默认 Provider 对象文件来反对此操作。 ...

August 30, 2023 · 1 min · jiezi

关于openssl:openssl的初步应用

牢骚距上一篇文章曾经时隔两年还要多了,我不禁感概时光如白驹过隙,而本人仍是少年,不论是身材心理上还是技术上。然而,人生不仅仅是工作一方面,我技术上仍比不上平均水平,不过几年来播种的也是不少。 引言我明确对称加密、非对称加密、公钥、私钥等各种概念。然而我该怎么操作呢?我接触了openssl。其实,我基本不懂openssl底层逻辑是啥,我只要求查阅材料后会用就行了。不要在我导入了ca证书后,浏览器还展现“不平安”这个页面。 应用本人表演CA机构自签名证书的问题在于服务器发给访问者的电脑或者浏览器的证书(公钥),访问者不意识,所以显示不平安界面。通常,服务器和访问者通过世界上权威的CA机构(第三方)来互相意识。而当初,服务器要本人做CA机构,而后通知访问者:“这是我。” 1. 生成ca.key(名字应该是没有关系的)。这个是私钥。openssl genrsa -out ca.key 4096解释: -out示意输入到这个文件4096示意加密位数/复杂度,1024的倍数2. 生成ca.csr(证书申请文件)。中间环节。openssl req -new -key ca.key -out ca.csr -subj "/C=CN/ST=SH/L=SH/O=MY/OU=FY/CN=www.batman.com/emailAddress=peace@love.com"解释: -new示意新生成-key示意基于哪个私钥生成.csr申请文件-out示意输入到哪个文件-subj用来指定各种信息。不加这个也没问题,他就会终端屏幕上一条一条的让你输出:然而指定了-subj,‘extra attributes’我就不会输出了你会发现每一条和用-subj参数是对应的内容就写你喜爱的,包含CN(Common Name),这个是CA的信息 3. 生成ca.crt证书。这个就是咱们要发给客户端的。openssl x509 -req -days 60 -in ca.csr -signkey ca.key -out ca.crt解释: -days示意证书有效期-in输出.csr申请文件-signkey基于哪个私钥-out示意输入到哪个文件4. 而后把ca.crt发给访问者,让他双击装置在零碎证书区域,或者在浏览器中导入。 生成服务器的证书1. 生成server.key(名字应该是没有关系的)。这个是私钥。放在nginx配置里。openssl genrsa -out server.key 2048解释: 和生成CA的.key文件一样嘛~抉择小一点的2048是因为这个证书是要用来和访问者交互的,略微小一点更快、申请包更小。CA反正生成了就放那了。2. 生成server.csr(证书申请文件)。中间环节。openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=SH/L=SH/O=MY/OU=FY/CN=www.batman.com/emailAddress=peace@love.com"解释: 和生成CA的.csr文件一样嘛~3. 生成server.crt(证书)。放在nginx配置里。openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile conf/serverCrt.conf解释: ...

July 3, 2023 · 2 min · jiezi

关于openssl:Azure-OpenAI-初体验-20230619

参考文档:Quickstart - Get started using ChatGPT and GPT-4 with Azure OpenAI Service - Azure OpenAI Service | Microsoft Learn 先决条件Azure 订阅在所需的 Azure 订阅中授予 Azure OpenAI 的拜访权限。具备 或gpt-35-turbo已部署的模型。 转到 Azure OpenAI Studio导航到 Azure OpenAI Studio https://oai.azure.com/,并应用有权拜访 OpenAI 资源的凭据登录。在登录工作流期间或之后,抉择相应的目录、Azure 订阅和 Azure OpenAI 资源。 曾经部署了一些模型 在“部署”中抉择模型: 启动聊天会话 抉择“从助理设置”下抉择“查看代码”,将重播到目前为止整个对话背地的代码: #Note: The openai-python library support for Azure OpenAI is in preview.import osimport openaiopenai.api_type = "azure"openai.api_base = "https://openainewone.openai.azure.com/"openai.api_version = "2023-03-15-preview"openai.api_key = os.getenv("OPENAI_API_KEY")//须要替换零碎参数或间接批改response = openai.ChatCompletion.create( engine="openaig35turbo", messages = [{"role":"system","content":"You are an AI assistant that helps people find information."},{"role":"user","content":"举荐端午节的华东好去处"},{"role":"assistant","content":"1. 苏州园林:苏州的园林建筑是中国传统文化的重要代表之一,端午节能够到苏州旅行古典园林,感触传统文化的魅力。\n\n2. 杭州西湖:西湖是杭州的标志性景点,端午节能够观赏西湖美景,品味当地的龙井茶。\n\n3. 上海迪士尼乐园:迪士尼乐园是全家人的好去处,端午节能够带着孩子一起来到这里,享受欢畅时光。\n\n4. 黄山:黄山是中国驰名的山水风景区,端午节能够在这里爬山、参观云海,感触大自然的魅力。\n\n5. 千岛湖:千岛湖是一个漂亮的水乡景区,端午节能够在这里游船、钓鱼、享受湖光山色。\n\n6. 乌镇:乌镇是一个古色古香的小镇,端午节能够在这里漫步、品味当地美食、感触古镇文化。\n\n7. 南京夫子庙:夫子庙是南京的驰名古迹,端午节能够在这里旅行、购物、品味当地小吃。\n\n8. 嘉兴南湖:南湖是嘉兴的标志性景点,端午节能够在这里游船、观赏风景、品味当地美食。"}], temperature=0.7, max_tokens=800, top_p=0.95, frequency_penalty=0, presence_penalty=0, stop=None)其中:openai.api_key = os.getenv("OPENAI_API_KEY")//须要替换零碎参数或间接批改 ...

June 21, 2023 · 3 min · jiezi

关于openssl:解决ChatGPT-too-many-requests-in-1-hourTry-again-later

ChatGPT 提醒: Too many requests in 1 hour. Try again later. 如下图,我屡次拜访也呈现同样的问题。中文意思是太多的申请数量在以后 1 个小时内,请稍后重试。那怎么办?怎么解决? 一、问题景象我根本试了半个小时,胜利次数就 1-2 次。那上面简略剖析这个起因,按起因出解决方案。起因如下 原文链接:https://bysocket.com/openai-c... "too many requests in 1 hour. try again later" 问题起因是什么?最大的起因是你的客户端拜访 IP 地址已被 ChatGPT 禁止,列入了黑名单。 但有可能 OpenAI 官网访问量太大,为了稳定性:做了削峰、降级和体验的衡量。如果问题频次不高,你须要重试即可解决。 点击支付海内原装 ChatGPT 正版账号:http://chatgpt.zzrpa.cn/ 官网的解释如图所示: 可能是为了保证系统的稳定性,Chatgpt 会定期检测申请的数量,并在达到肯定的阈值后限度申请的数量。可能是是因为你的应用程序 接了 OpenAI ChatGPT 存在某些问题导致发送了大量的反复申请。你能够尝试查看你的应用程序的代码,找出可能导致反复申请的起因并进行修改。上面是按多种办法解决步骤,心愿对你有帮忙! 二、多种办法解决步骤办法一:换好一点的代理因为可能你的代理对应的 IP,不是独享的。而且 IP 曾经被 OpenAI ChatGPT 列入了黑名单或将此 IP 速率限度,你再怎么搞,解决不了这个问题。所以按上面步骤形式解决: 找一个 Top 最好的代理(高级独享 IP)设置全局代理,国家切到可用国家(美国、英国、印度等等)删除浏览器 cookies 和站点数据强制刷新 ChatGPT 页面从新关上登录,即可胜利再次应用办法二:技术人员申请云主机代理解决其实实质还是 IP 在国内,那就用云主机,远程桌面解决。 申请美国(硅谷)的云主机:google cloud / AWS 都行(都能白嫖代金券)近程进入该主机,装置浏览器并关上 ChatGPT 页面从新关上登录,即可胜利体验丝滑办法三:创立一个 ChatGPT 新帐户可能账号被禁(比方 账号多用 等),官网把账号拉进了小黑屋。导致下面办法都不能解决,那能够这样 ...

February 10, 2023 · 1 min · jiezi

关于openssl:使用OpenSSL生成自签名证书

OpenSSL 用于传输层平安(TLS)协定的开源工具包,以前称为安全套接字层(Secure Sockets Layer)协定。自签名SSL证书的危险自签名SSL证书是不受浏览器信赖的,即便网站装置了自签名SSL证书,当用户拜访时浏览器还是会继续弹出正告。 为了网站的平安,请停止使用自签名SSL证书,举荐应用受信赖的CA机构提供的收费且平安的SSL证书。 生成步骤通过openssl生成私钥openssl genrsa -out server.key 1024依据私钥生成证书申请文件csropenssl req -new -key server.key -out server.csr这一步会提醒你补充一些信息,Common Name能够输出:*.yourdomain.com,这种形式生成通配符域名证书。 应用私钥对证书申请进行签名从而生成证书openssl x509 -req -in server.csr -out server.crt -signkey server.key -days 3650➜ ssl lsserver.crt server.csr server.key这样10年有效期的自签名证书就生成好了,能够把它装在服务上,如果你用的Nginx: server { listen 443 ssl http2; server_name youdomain.com; root /data/dist/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ssl_certificate "/etc/nginx/ssl/server.crt"; ssl_certificate_key "/etc/nginx/ssl/server.key"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on;}到浏览器查看,提醒: 所以,还是间接去CA机构签发证书吧。

September 15, 2022 · 1 min · jiezi

关于openssl:3-openssl-genrsa生成rsa私钥

genrsa用于生成RSA私钥,不会生成公钥,因为公钥提取自私钥,如果须要查看公钥或生成公钥,能够应用openssl rsa命令。 应用man genrsa查问其用法。 openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [numbits] 选项阐明: -out filename :将生成的私钥保留至filename文件,若未指定输入文件,则为规范输入。 -numbits :指定要生成的私钥的长度,默认为1024。必须为命令行的最初一项参数。 -des|-des3|-idea:指定加密私钥文件用的算法,这样每次应用私钥文件都将输出明码,太麻烦所以很少应用。 -passout args :加密私钥文件时,传递明码的格局,如果要加密私钥文件时未指定该项,则提醒输出明码。传递明码的args的格局见https://www.cnblogs.com/liliy... 例如: (1).生成512位的rsa私钥,输入到屏幕 [root@localhost tmp]# openssl genrsa 512 Generating RSA private key, 512 bit long modulus..........++++++++++++...++++++++++++e is 65537 (0x10001)-----BEGIN RSA PRIVATE KEY-----MIIBOgIBAAJBALuTz3ryd8qew0smTSuCKoA0G7/psj1HXLu5di8AZN+8wlJxSOYHR1S0EXqIlpOE4ajkGDVacsdV38aQyqxY5tUCAwEAAQJAXD9W3Bn+O5FUbdLKRMlg6We29eySEXzU6CVPL9I7yaOL0OFslvWbHXY9Zvn871lNkCpthwutJ6UsbCUKHo37SQIhAPZfFLSQfvmePHj59+dIMs/qeVIPZWCnq0yC3KaF4hZzAiEAwuiAdC2cHNLYKKP2sDR5kfJU/zru03m0XEHdfWp4c5cCIAb++jKKa+CguqzgxEZgCXlX+iv3XfSZrkaU7LkZ0iq7AiEAt9wXgICd6VrD6eJyDNoTbCeLIpD3RapjBzxisbJEGdUCIGlpWBcMHlRG5rqk+T+ONaA2wJY7lw0N8V/BuaDVtNor-----END RSA PRIVATE KEY----- (2).生成512位的rsa私钥,输入到指定的文件genrsa.txt [root@localhost tmp]# openssl genrsa -out genrsa.txt 512 [root@localhost tmp]# cat genrsa.txt -----BEGIN RSA PRIVATE KEY-----MIIBOwIBAAJBAM+hBmDPXongltEIy6Zkk+YhNNpGZKHzCLjWeQpd6qTSgVrST+kOCi1bNI/D6Lm5kYk6YNQfxzkb58JoaGhPF3MCAwEAAQJAYWnPMESaul2g5NoXki3GJkaWIYK9XC5GfVJC39ZIbKNtphy3Cqw5FfVn7YEg/Dl1Tn/ZyWoLCapyc1Z/TRqBoQIhAP46ZHnj3bvQJ8mK5NtyBPv1uVjicpva78ukjXtwOJ8FAiEA0RN84R2BiLncv3wFQ1HPJbY6ud8PvhHlaBlieuji9hcCIATGdgKwHAceFtE7UacpkhxldjDMOBjjWOO7WIj8B6Q9AiEAn+l15IC66KawDs1/AQR7me6NcEkKM2hgvIRd7IBfx7UCIQDRJ3sGcE0mIICOTtmW2FgdvOuf2UmVO9MDXfZv6chdww==-----END RSA PRIVATE KEY----- (3).加密私钥文件,加密的明码为123456 [root@xuexi tmp]# openssl genrsa -out genrsa.txt -des3 -passout pass:123456 512 #这里应用了-des3算法对私钥文件加密,如果不应用-passout选项指定明码, ...

August 18, 2022 · 1 min · jiezi

关于openssl:openssl-使用混合加密方法对大文件加解密

应用 openssl背景RSA 和 AES 别离是经典的非对称加密算法和对称加密算法。然而非对称加密算法并不适宜解决大文件,所以大家个别都会采纳混合加密的形式,即: 生成对称加密算法所须要的对称明码应用对称加密算法加密大文件应用非对称加密算法加密对称明码办法加密创立 AES 所需的 key 和 iv,用一个文本文件存储起来应用这个 key 和 iv 加密大文件创立 RSA 所需的公私钥对应用 RSA 公钥加密存储 key 和 iv 的文本文件将加密后的大文件和加密后的存储 key 和 iv 的文本文件放在一起,便于当前解密解密应用 RSA 私钥解密加密后的存储 key 和 iv 的文本文件读取 key 和 iv应用 AES 解密大文件命令请按理论须要,批改命令中的各个文件名 生成随机十六进制数字明码:长度 32openssl rand -hex 32 初始向量 iv:长度 16openssl rand -hex 16 生成后,写入到一个文本文件中,待之后被 RSA 加密 readonly key=$(openssl rand -hex 32)readonly iv=$(openssl rand -hex 16)readonly aes_key_and_iv_file="aes-key-and-iv.txt"{ echo "key=${key}" echo "iv=${iv}"} > "${aes_key_and_iv_file}"AES 加密记得应用生成的 key 和 iv,替换命令中的 32nums(hexdec) 和 16nums(hexdex)openssl enc -aes-256-cbc -in example.file -out example.file.enc -base64 -K 32nums(hexdec) -iv 16nums(hexdec) ...

May 30, 2022 · 1 min · jiezi

关于openssl:CentOS7升级openssl111

最近须要装置emq,发现openssl的版本低了,联合网上搜寻的材料。做了一个装置步骤,保障胜利。 查看版本openssl version # 返回后果OpenSSL 1.0.2k-fips 26 Jan 2017装置编译工具yum install -y wget gcc make unzip下载编译装置从https://github.com/openssl/op...下载最新版本,1.x.x。 # 下载wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1n.zip# 解压unzip OpenSSL_1_1_1n.zip# 切换目录cd openssl-OpenSSL_1_1_1n# 配置装置目录./config --prefix=/usr/local/openssl# 编译装置make && make install更换版本mv /usr/bin/openssl /usr/bin/openssl.oldmv /usr/lib64/openssl /usr/lib64/openssl.oldmv /usr/lib64/libssl.so /usr/lib64/libssl.so.oldln -s /usr/local/openssl/bin/openssl /usr/bin/opensslln -s /usr/local/openssl/include/openssl /usr/include/opensslln -s /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.soecho "/usr/local/openssl/lib" >> /etc/ld.so.confldconfig -v 国密算法检测# 查看 SM3 哈希校验和echo -n "abc" | openssl dgst -SM3# 查看椭圆曲线是否蕴含SM2openssl ecparam -list_curves | grep SM2# 查看对称算法openssl enc -ciphers |grep '\-sm'

April 21, 2022 · 1 min · jiezi

关于openssl:PC端openssl和libevent的编译流程

PC端openssl和libevent的编译流程筹备工作:1、Perl倡议应用5.30以上版本,自己在应用时发现28的版本如同在配置openssl的时候有问题。下载地址:http://strawberryperl.com/ps:ActivePerl 和 Strawberry Perl 都能够 2、nasm下载地址:https://www.nasm.us/pub/nasm/stable/nasm须要配置环境变量装置后关上vs编译环境(我编译的是vs2010)验证perl和nasm是否装置胜利 编译openssl进入openssl-1.0.2j目录执行: Perl Configure no-asm VC-WIN32 --prefix=D:\openssl_lib开始编译 ms\do_nasm(动态库)nmake -f ms\nt.maknmake -f ms\nt.mak testnmake -f ms\nt.mak install最初生成文件在openssl_lib目录下 Libevent编译进入libevent-2.0.22-stable目录替换Makefile.nmake内容如下: # WATCH OUT! This makefile is a work in progress. -*- makefile -*-## I'm not very knowledgeable about MSVC and nmake beyond their most basic# aspects. If anything here looks wrong to you, please let me know.# If OPENSSL_DIR is not set, builds without OpenSSL support. If you want# OpenSSL support, you can set the OPENSSL_DIR variable to where you# installed OpenSSL. This can be done in the environment:# set OPENSSL_DIR=c:\openssl# Or on the nmake command line:# nmake OPENSSL_DIR=C:\openssl -f Makefile.nmake# Or by uncommenting the following line here in the makefile...# OPENSSL_DIR=c:\openssl!IFDEF OPENSSL_DIRSSL_CFLAGS=/I$(OPENSSL_DIR)\include /DEVENT__HAVE_OPENSSL!ELSESSL_CFLAGS=!ENDIF# Needed for correctnessCFLAGS=/IWIN32-Code /IWIN32-Code/nmake /Iinclude /Icompat /DHAVE_CONFIG_H /DWIN32 /I. $(SSL_CFLAGS)# For optimization and warningsCFLAGS=$(CFLAGS) /Ox /W3 /wd4996 /MTd /nologo # XXXX have a debug modeLIBFLAGS=/nologoCORE_OBJS=event.obj buffer.obj bufferevent.obj bufferevent_sock.obj \bufferevent_pair.obj listener.obj evmap.obj log.obj evutil.obj \strlcpy.obj signal.obj bufferevent_filter.obj evthread.obj \bufferevent_ratelim.obj evutil_rand.obj WIN_OBJS=win32select.obj evthread_win32.obj buffer_iocp.obj \event_iocp.obj bufferevent_async.objEXTRA_OBJS=event_tagging.obj http.obj evdns.obj evrpc.obj!IFDEF OPENSSL_DIRSSL_OBJS=bufferevent_openssl.objSSL_LIBS=libevent_openssl.lib!ELSESSL_OBJS=SSL_LIBS=!ENDIFALL_OBJS=$(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS) $(SSL_OBJS)STATIC_LIBS=libevent_core.lib libevent_extras.lib libevent.lib $(SSL_LIBS)all: static_libs testsstatic_libs: $(STATIC_LIBS)libevent_core.lib: $(CORE_OBJS) $(WIN_OBJS)lib $(LIBFLAGS) $(CORE_OBJS) $(WIN_OBJS) /out:libevent_core.lib libevent_extras.lib: $(EXTRA_OBJS)lib $(LIBFLAGS) $(EXTRA_OBJS) /out:libevent_extras.liblibevent.lib: $(CORE_OBJS) $(WIN_OBJS) $(EXTRA_OBJS)lib $(LIBFLAGS) $(CORE_OBJS) $(EXTRA_OBJS) $(WIN_OBJS) /out:libevent.liblibevent_openssl.lib: $(SSL_OBJS)lib $(LIBFLAGS) $(SSL_OBJS) /out:libevent_openssl.libclean:del $(ALL_OBJS)del $(STATIC_LIBS)tests:!IFDEF OPENSSL_DIR !ELSE !ENDIF最初执行: ...

February 28, 2022 · 1 min · jiezi

关于openssl:交叉编译openssl-for-armlinuxandroideabigcc工具链

穿插编译openssl for arm-linux-androideabi-gcc工具链1、编译出错问题在Ubuntu 16.04 64bit上搭建的android编译环境穿插编译SDK的openssl-1.0.2j生成库,然而应用ndk-build时,却呈现了“Fatal error: Invalid -march= option: `armv5te'”谬误 2、解决办法用android-ndk-r10e的穿插编译链在Ubuntu 16.04 32bit零碎上没有问题,起初百度搜寻后尝试了各种办法还是找不到问题所在,最初在CSDN问答这边找到了相干形容,果不其然,降级了穿插编译链android-ndk-r12b后编译就通过了。

February 28, 2022 · 1 min · jiezi

关于openssl:openssh安装

下载间接下载编译过的exe文件,始终下一步即可。链接地址:http://slproweb.com/products/... 配置将bin门路增加到path下 验证查问版本 PS C:\Users\cui> openssl versionOpenSSL 3.0.0 7 sep 2021 (Library: OpenSSL 3.0.0 7 sep 2021)详细信息 PS C:\Users\cui> openssl version -aOpenSSL 3.0.0 7 sep 2021 (Library: OpenSSL 3.0.0 7 sep 2021)built on: Thu Sep 9 01:34:09 2021 UTCplatform: VC-WIN64Aoptions: bn(64,64)compiler: cl /Z7 /Fdossl_static.pdb /Gs0 /GF /Gy /MD /W3 /wd4090 /nologo /O2 -DL_ENDIAN -DOPENSSL_PIC -D_USING_V110_SDK71_ -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=0x0502OPENSSLDIR: "C:\Program Files\Common Files\SSL"ENGINESDIR: "C:\Program Files\OpenSSL\lib\engines-3"MODULESDIR: "C:\Program Files\OpenSSL\lib\ossl-modules"Seeding source: os-specificCPUINFO: OPENSSL_ia32cap=0x7ffaf3bfffebffff:0x29c67af生成证书私钥常见私后缀:pfx p12 pem key ...

November 30, 2021 · 1 min · jiezi

关于openssl:centos7-升级-opensslopenssh-解决漏洞扫描高危

一、linux中将openssl降级到1.1.1l下载版本:https://ftp.openssl.org/source/ ,下载最新的1.1.1k版本旧版本地址:https://www.openssl.org/sourc...将openssl-1.1.1l.tar.gz 上传到服务器 进入openssl-1.1.1.l目录下,编译装置 build [root@bogon ~]# yum -y install gcc pcre-devel zlib-devel openssl openssl-devel gcc make -y [root@bogon ~]# ./config --prefix=/usr/local/openssl #指定装置门路 [root@bogon ~]# make && make install #编译装置期待装置实现,执行上面的操作 #备份旧的openssl文件 [root@bogon ~]# mv /usr/bin/openssl /usr/bin/openssl.old [root@bogon ~]# mv /usr/lib64/openssl /usr/lib64/openssl.old [root@bogon ~]# mv /usr/lib64/libssl.so /usr/lib64/libssl.so.old #创立软链接 [root@bogon ~]# ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl [root@bogon ~]# ln -s /usr/local/openssl/include/openssl /usr/include/openssl [root@bogon ~]# ln -s /usr/local/openssl/lib/libssl.so /usr/lib64/libssl.so [root@bogon ~]# echo "/usr/local/openssl/lib" >> /etc/ld.so.conf [root@bogon ~]# ldconfig -v #显示正在扫描的目录及搜寻到的动态链接库[root@bogon ~]# openssl versionOpenSSL 1.1.1l 24 Aug 2021二、linux中将openssh降级到8.8https://openbsd.hk/pub/OpenBS... ...

November 18, 2021 · 1 min · jiezi

关于openssl:C语言openssl库的ECDSAwithsha256签名和验签

1.间接上源码:#include <stdio.h>#include <string.h>#include <openssl/ecdsa.h>#include <openssl/pem.h>#include <openssl/err.h>// base64 编码char *base64_encode(const char *buffer, int length) { BIO *bmem = NULL; BIO *b64 = NULL; BUF_MEM *bptr; char *buff = NULL; b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, buffer, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); BIO_set_close(b64, BIO_NOCLOSE); buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff;}// base64 解码char *base64_decode(char *input, int length) { BIO *b64 = NULL; BIO *bmem = NULL; char *buffer = NULL; buffer = (char *)malloc(length); memset(buffer, 0, length); b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new_mem_buf(input, length); bmem = BIO_push(b64, bmem); BIO_read(bmem, buffer, length); BIO_free_all(bmem); return buffer;}//公钥验证签名int my_verify(const char *input, int input_len, ECDSA_SIG *signret, const char *pub_key_fn){ EC_KEY *p_dsa = NULL; FILE *file = NULL; int ret = 0; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int digest_len = 0; EVP_MD_CTX md_ctx; if((file = fopen(pub_key_fn, "rb")) == NULL) { ret = -1; return ret; } if((p_dsa = PEM_read_EC_PUBKEY(file, NULL,NULL,NULL )) == NULL) { // 获取公钥的ec key ret = -2; fclose(file); return ret; } fclose(file); EVP_MD_CTX_init(&md_ctx); if (!EVP_DigestInit(&md_ctx, EVP_sha256())) { printf("EVP_digest fail \n"); return 0; } if (!EVP_DigestUpdate(&md_ctx, (const void *)input, input_len)) { printf("EVP_DigestUpdate fail \n"); return 0; } if (!EVP_DigestFinal(&md_ctx, digest, &digest_len)) { // 待签名音讯用sha256生成256比特的签名摘要 printf("EVP_DigestFinal fail \n"); return 0; } printf("verify digest: %s\n", digest); ret = ECDSA_do_verify(digest, digest_len, signret, p_dsa); // 对签名摘要进行验签失去后果 if (ret == -1) { ret = -3; printf("ECDSA_verify err!\n"); EC_KEY_free(p_dsa); return ret; } else if (ret == 0) { ret = -3; printf("ECDSA_verify err incorrect signature!\n"); EC_KEY_free(p_dsa); return ret; } else { printf("ECDSA_verify ok\n"); } printf("verify is ok!\n"); EC_KEY_free(p_dsa); return 0;}//私钥签名int my_sign(const char *input, int input_len, const char *pri_key_fn){ EC_KEY *p_dsa = NULL; ECDSA_SIG *s; FILE *file = NULL; unsigned char *data[2]; int nid; int signlen = 0; int i = 0; int ret = 0; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int digest_len = 0; EVP_MD_CTX md_ctx; memset(data, 0x00, sizeof(data)); nid = 0; file = fopen(pri_key_fn, "rb"); if(!file) { ret = -1; return ret; } if((p_dsa = PEM_read_ECPrivateKey(file, NULL, NULL, NULL)) == NULL) { // 获取私钥的ec key ret = -2; fclose(file); return ret; } fclose(file); EVP_MD_CTX_init(&md_ctx); if (!EVP_DigestInit(&md_ctx, EVP_sha256())) { printf("EVP_digest fail \n"); return 0; } if (!EVP_DigestUpdate(&md_ctx, (const void *)input, input_len)) { printf("EVP_DigestUpdate fail \n"); return 0; } if (!EVP_DigestFinal(&md_ctx, digest, &digest_len)) { // 待签名音讯用sha256生成256比特的签名摘要 printf("EVP_DigestFinal fail \n"); return 0; } printf("sign digest: %s\n", digest); s = ECDSA_do_sign(digest, digest_len, p_dsa); // 对签名摘要进行签名失去签名数据s if(s == NULL) { ret = -3; EC_KEY_free(p_dsa); return ret; } data[0] = BN_bn2hex(s->r); //二进制转十六进制 data[1] = BN_bn2hex(s->s); EC_KEY_free(p_dsa); ECDSA_SIG_free(s); printf("%s\n", data[0]); printf("%s\n", data[1]); free(data[0]); free(data[1]); return 0;}int main(int argc, char**argv){ char src[512+1]; char dst_str[2][512+1]; int src_len; int ret; FILE *f; memset(src, 0x00, sizeof(src)); memset(dst_str, 0x00, sizeof(dst_str)); if(argv[1][0] == 's') { strcpy(src, "hello world"); // 待签名音讯 src_len = strlen(src) ; ret = my_sign(src, src_len, argv[2]); if(ret) { fprintf(stderr, "Error\n"); } } else { ECDSA_SIG *s = (ECDSA_SIG *)malloc(sizeof(ECDSA_SIG)); strcpy(src, "hello world"); // 须要验证的签名音讯 strncpy(dst_str[0], argv[2], 512); strncpy(dst_str[1], argv[3], 512); src_len = strlen(src); s->r = BN_new(); s->s = BN_new(); BN_hex2bn(&(s->r), dst_str[0]); //十六进制转二进制 BN_hex2bn(&(s->s), dst_str[1]); ret = my_verify(src, src_len, s, argv[1]); if(ret) { fprintf(stderr, "Error\n"); } BN_free(s->r); BN_free(s->s); free(s); } return 0;}2.编译环境openssl版本为1.0.2g,openssl version查看openssl的版本,其余版本自行验证base的编解码代码也有,这里demo暂不应用 ...

October 18, 2021 · 3 min · jiezi

关于openssl:C版本ECDSAwithSHA256签名验证

因为我的项目须要验证签名,这里不做签名,只验签间接上代码: 应用办法:openssl版本:1.0.2g 其余的自行验证编译:g++ x509.cpp -o x509 -lssl -lcrypto执行:./x509 #include <openssl/pem.h>#include <openssl/x509.h>#include <openssl/x509v3.h>#include <cstring>#include <iostream>// base64 编码char *base64_encode(const char *buffer, int length) { BIO *bmem = NULL; BIO *b64 = NULL; BUF_MEM *bptr; char *buff = NULL; b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, buffer, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); BIO_set_close(b64, BIO_NOCLOSE); buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff;}// base64 解码char *base64_decode(char *input, int length) { BIO *b64 = NULL; BIO *bmem = NULL; char *buffer = NULL; buffer = (char *)malloc(length); memset(buffer, 0, length); b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new_mem_buf(input, length); bmem = BIO_push(b64, bmem); BIO_read(bmem, buffer, length); BIO_free_all(bmem); return buffer;}int get_str_len(const char *in) { int num = 0; if(in == NULL) { return 0; } while (!((*(in + num) == NULL) && (*(in + num + 1) == NULL) \ && (*(in + num + 2) == NULL) && (*(in + num + 3) == NULL) \ && (*(in + num + 4) == NULL)&& (*(in + num + 5) == NULL) \ && (*(in + num + 6) == NULL)&& (*(in + num + 7) == NULL))) { num++; } return num;}static const char hex_table[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};// 字节转十六进制字符串std::string BytesToHexStr(const char* aInStr, int len){ std::string hex_str; for (int i = 0; i < len; ++i) { hex_str.append(&hex_table[(aInStr[i] & 0xF0) >> 4], 1); hex_str.append(&hex_table[aInStr[i] & 0xF], 1); } std::cout << hex_str << std::endl; return hex_str;}// 字符串截取char* substring(char* ch,int pos,int length) { // 定义字符指针 指向传递进来的ch地址 char *pch = ch; // 通过calloc来调配一个length长度的字符数组,返回的是字符指针。 char *subch = (char*)calloc(sizeof(char),length+1); int i; // 只有在C99下for循环中才能够申明变量,这里写在里面,进步兼容性。 pch = pch + pos; // 是pch指针指向pos地位。 for(i = 0; i < length; i++) { subch[i] = *(pch++); // 循环遍历赋值数组。 } subch[length]='\0'; // 加上字符串结束符。 return subch; // 返回调配的字符数组地址。} int ECDSA_WithSHA256_do_verify(const char *strx509, char *message, unsigned int messageLen, char *signBuf, unsigned int signLen) { EC_KEY * ec_key; EVP_MD_CTX md_ctx; int ret = -1; char *Sigbuff = NULL, *Signature = NULL, *r = NULL, *s = NULL; char dst_str[2][512+1]; unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int digestLen = 0; BIO *bio_mem = BIO_new(BIO_s_mem()); BIO_puts(bio_mem, strx509); X509 * x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL); EVP_PKEY *pkey = X509_get_pubkey(x509); // 获取证书的公钥 if (pkey->type == EVP_PKEY_EC) { ec_key = EVP_PKEY_get1_EC_KEY(pkey); if (!ec_key) { printf("get EVP_PKEY_get1_EC_KEY fail \n"); } } EVP_PKEY_free(pkey); Sigbuff = base64_decode(message,messageLen); // base64解码后的验证数据 Signature = base64_decode(signBuf,signLen); // base64解码后的签名数据 printf("Sigbuff: %s\n", Sigbuff); printf("Signature: %s\n Signature len: %d\n EVP_MAX_MD_SIZE: %d\n", Signature,get_str_len(Signature), EVP_MAX_MD_SIZE); r = substring(Signature,0,get_str_len(Signature)/2); s = substring(Signature,get_str_len(Signature)/2,get_str_len(Signature)); std::string rSignatureInHex = BytesToHexStr(r,get_str_len(Signature)/2); std::string sSignatureInHex = BytesToHexStr(s,get_str_len(Signature)/2); free(r); free(s); EVP_MD_CTX_init(&md_ctx); if (!EVP_DigestInit(&md_ctx, EVP_sha256())) { printf("EVP_digest fail \n"); } if (!EVP_DigestUpdate(&md_ctx, (const void *)Sigbuff, get_str_len(Sigbuff))) { printf("EVP_DigestUpdate fail \n"); } if (!EVP_DigestFinal(&md_ctx, digest, &digestLen)) { printf("EVP_DigestFinal fail \n"); } free(Sigbuff); free(Signature); ECDSA_SIG *sig = (ECDSA_SIG *)malloc(sizeof(ECDSA_SIG)); strncpy(dst_str[0], rSignatureInHex.c_str(), 512); strncpy(dst_str[1], sSignatureInHex.c_str(), 512); printf("dst_str[0]: %s\n", &dst_str[0]); printf("dst_str[1]: %s\n", &dst_str[1]); sig->r = BN_new(); sig->s = BN_new(); BN_hex2bn(&(sig->r), dst_str[0]); //十六进制转二进制 BN_hex2bn(&(sig->s), dst_str[1]); /*do verify*/ ret = ECDSA_do_verify((const unsigned char*)digest, digestLen, sig, ec_key); if (ret == -1) { printf("ECDSA_verify failed\n"); } else if (ret == 0) { printf("ECDSA_verify incorrect signature\n"); } else { printf("ECDSA_verify ok\n"); } BN_free(sig->r); BN_free(sig->s); free(sig); if (ec_key) { EC_KEY_free(ec_key); ec_key = NULL; } BIO_free(bio_mem); X509_free(x509); return ret;}int main(int argc, char **argv){ OpenSSL_add_all_algorithms(); // 须要验证的数据的base64编码 char message[] = "hGpTaWduYXR1cmUxTaIESDSaQrDC0HKOASZAWQECpAQaZF2BgAYaYUOemQFiSVQ5AQOhAaRhdoGqYmRuAWJtYW1PUkctMTAwMDAxNjk5YnZwajExMTkzMDUwMDViZHRqMjAyMS0wNS0wNWJjb2JJVGJjaXgmMDFJVDVBMUM2NEYyREYwODQ3RjI5Rjc0MTA2MjA1OEFGQUUwIzFibXBsRVUvMS8yMS8xNTI5Ymlzdk1pbmlzdGVybyBkZWxsYSBTYWx1dGVic2QBYnRnaTg0MDUzOTAwNmNuYW2kY2ZudGdQQU5ESU5JYmZuZ1BBTkRJTkljZ250ZkFORFJFQWJnbmZBTkRSRUFjdmVyZTEuMC4wY2RvYmoxOTUyLTA5LTI4"; // 摘要签名数据的base64编码 char signBuf[] = "a0KNpWa23iFQue19IioU/jrUPd/Utoo9A4prMG9LvS3FCsNEHHAwoAUpO4/KIfLB6R1MiIakaIJo4lIBawvUOA=="; // 证书 std::string str = "MIIEDzCCAfegAwIBAgIURldu5rsfrDeZtDBxrJ+SujMr2IswDQYJKoZIhvcNAQELBQAwSTELMAkGA1UEBhMCSVQxHzAdBgNVBAoMFk1pbmlzdGVybyBkZWxsYSBTYWx1dGUxGTAXBgNVBAMMEEl0YWx5IERHQyBDU0NBIDEwHhcNMjEwNTEyMDgxODE3WhcNMjMwNTEyMDgxMTU5WjBIMQswCQYDVQQGEwJJVDEfMB0GA1UECgwWTWluaXN0ZXJvIGRlbGxhIFNhbHV0ZTEYMBYGA1UEAwwPSXRhbHkgREdDIERTQyAxMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnL9+WnIp9fvbcocZSGUFlSw9ffW/jbMONzcvm1X4c+pXOPEs7C4/83+PxS8Swea2hgm/tKt4PI0z8wgnIehoj6OBujCBtzAfBgNVHSMEGDAWgBS+VOVpXmeSQImXYEEAB/pLRVCw/zBlBgNVHR8EXjBcMFqgWKBWhlRsZGFwOi8vY2Fkcy5kZ2MuZ292Lml0L0NOPUl0YWx5JTIwREdDJTIwQ1NDQSUyMHhcMSxPPU1pbmlzdGVybyUyMGRlbGxhJTIwU2FsdXRlLEM9SVQwHQYDVR0OBBYEFC4bAbCvpArrgZ0E+RrqS8V7TNNIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAjxTeF7yhKz/3PKZ9+WfgZPaIzZvnO/nmuUartgVd3xuTPNtd5tuYRNS/1B78HNNk7fXiq5hH2q8xHF9yxYxExov2qFrfUMD5HOZzYKHZcjcWFNHvH6jx7qDCtb5PrOgSK5QUQzycR7MgWIFinoWwsWIrA1AJOwfUoi7v1aoWNMK1eHZmR3Y9LQ84qeE2yDk3jqEGjlJVCbgBp7O8emzy2KhWv3JyRZgTmFz7p6eRXDzUYHtJaufveIhkNM/U8p3S7egQegliIFMmufvEyZemD2BMvb97H9PQpuzeMwB8zcFbuZmNl42AFMQ2PhQe27pU0wFsDEqLe0ETb5eR3T9L6zdSrWldw6UuXoYV0/5fvjA55qCjAaLJ0qi16Ca/jt6iKuws/KKh9yr+FqZMnZUH2D2j2i8LBA67Ie0JoZPSojr8cwSTxQBdJFI722uczCj/Rt69Y4sLdV3hNQ2A9hHrXesyQslr0ez3UHHzDRFMVlOXWCayj3LIgvtfTjKrT1J+/3Vu9fvs1+CCJELuC9gtVLxMsdRc/A6/bvW4mAsyY78ROX27Bi8CxPN5IZbtiyjpmdfr2bufDcwhwzdwsdQQDoSiIF1LZqCn7sHBmUhzoPcBJdXFET58EKow0BWcerZzpvsVHcMTE2uuAUr/JUh1SBpoJCiMIRSl+XPoEA2qqYU="; str.insert(0,"-----BEGIN CERTIFICATE-----" "\n"); str.append( "\n" "-----END CERTIFICATE-----" "\n"); int ret = ECDSA_WithSHA256_do_verify(str.c_str(), message, sizeof(message), signBuf, sizeof(signBuf)); printf("ECDSA_WithSHA256 ret = %d\n", ret);}/*应用办法:openssl版本:1.0.2g 其余的自行验证编译:g++ x509.cpp -o x509 -lssl -lcrypto执行:./x509*/

October 18, 2021 · 3 min · jiezi

关于openssl:C11-ECDSAwithSHA256验签

这里不做签名,只验签 应用办法:openssl版本:1.0.2g 其余的自行验证编译:g++ test.cpp -o test -lssl -lcrypto -std=c++11执行:./test签名过程:随机数进行SHA256哈希后再应用私钥对其签名验签过程:用随机数的SHA256和公钥来验证签名以下代码是验证签名 #include <iostream>#include <memory>#include <string>#include <sstream>#include <stdio.h>#include <string.h>#include <openssl/ecdsa.h>#include <openssl/pem.h>#include <openssl/err.h>#include <openssl/conf.h>#include <openssl/evp.h>#include <openssl/err.h>#include <openssl/ec.h>#include <openssl/bn.h>bool verify_signature(const unsigned char* hash, const ECDSA_SIG* signature, EC_KEY* eckey){ int verify_status = ECDSA_do_verify(hash, SHA256_DIGEST_LENGTH, signature, eckey); if (1 != verify_status) { printf("Failed to verify EC Signature\n"); return false; } printf("Verifed EC Signature\n"); return true;}void SetOpensslSignature(const std::string& sSignatureInHex, ECDSA_SIG* pSign){ // std::unique_ptr< BIGNUM, std::function<void(BIGNUM*)>> rr(NULL, [](BIGNUM* b) { BN_free(b); }); // BIGNUM* r_ptr = rr.get(); // std::unique_ptr< BIGNUM, std::function<void(BIGNUM*)>> ss(NULL, [](BIGNUM* b) { BN_free(b); }); // BIGNUM* s_ptr = ss.get(); std::string sSignatureR = sSignatureInHex.substr(0, sSignatureInHex.size() / 2); std::string sSignatureS = sSignatureInHex.substr(sSignatureInHex.size() / 2); pSign->r = BN_new(); pSign->s = BN_new(); BN_hex2bn(&pSign->r, sSignatureR.c_str()); BN_hex2bn(&pSign->s, sSignatureS.c_str()); return;}bool SetOpensslPublicKey(const std::string& sPublicKeyInHex, EC_KEY* pKey){ const char* sPubKeyString = sPublicKeyInHex.c_str(); char cx[65]; std::unique_ptr< BIGNUM, std::function<void(BIGNUM*)>> gx(NULL, [](BIGNUM* b) { BN_free(b); }); std::unique_ptr< BIGNUM, std::function<void(BIGNUM*)>> gy(NULL, [](BIGNUM* b) { BN_free(b); }); BIGNUM* gx_ptr = gx.get(); BIGNUM* gy_ptr = gy.get(); EC_KEY_set_asn1_flag(pKey, OPENSSL_EC_NAMED_CURVE); memcpy(cx, sPubKeyString, 64); cx[64] = 0; if (!BN_hex2bn(&gx_ptr, cx)) { std::cout << "Error getting to binary format" << std::endl; } if (!BN_hex2bn(&gy_ptr, &sPubKeyString[64])) { std::cout << "Error getting to binary format" << std::endl; } if (!EC_KEY_set_public_key_affine_coordinates(pKey, gx_ptr, gy_ptr)) { std::cout << "setting public key attributes" << std::endl; } if (EC_KEY_check_key(pKey) == 1) { printf("EC Key valid.\n"); return true; } else { printf("EC Key Invalid!\n"); return false; }}std::string sha256(const std::string str){ unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, str.c_str(), str.size()); SHA256_Final(hash, &sha256); std::stringstream ss; for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { ss << hash[i]; } return ss.str();}bool Verify(const std::string& sRandomNumber, const std::string& sSignature, const std::string& sDevicePubKeyInHex){ std::unique_ptr< ECDSA_SIG, std::function<void(ECDSA_SIG*)>> zSignature(ECDSA_SIG_new(), [](ECDSA_SIG* b) { ECDSA_SIG_free(b); }); // Set up the signature... SetOpensslSignature(sSignature, zSignature.get()); std::unique_ptr< EC_KEY, std::function<void(EC_KEY*)>> zPublicKey(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1), [](EC_KEY* b) { EC_KEY_free(b); }); if (!SetOpensslPublicKey(sDevicePubKeyInHex, zPublicKey.get())) std::cout << "Failed to get the public key from the hex input" << std::endl; std::string sHash = sha256(sRandomNumber); return verify_signature((const unsigned char*)sHash.c_str(), zSignature.get(), zPublicKey.get());}int main(int argc, char* argv[]){ std::string sSignatureInHex = "D506D976EC17DD3717C40329E28FD8DB4F32D6A3773454A6427FD12E69728157508086B661D91E07ADF5B57E787EA1EEA526A84500436E430E89B1C1F8532A41"; std::string sPublicKeyInHex = "94E62E0C77A2955B1FB3EE98AEAA99AACAD742F20E45B727EACDD10487C2F7D0D8257C6102921880ABE953245D573D7E33EC88A67E2BA930980CB9C3D6722F8A"; std::string sRandomNumber = "65560886818773090201885807838738706912015073749623293202319529"; if (!Verify(sRandomNumber, sSignatureInHex, sPublicKeyInHex)) std::cout << "Verification failed." << std::endl; else std::cout << "Verification succeeded" << std::endl;}

October 18, 2021 · 2 min · jiezi

关于openssl:C语言openssl-aes128ecb加解密

openssl aes-128-ecb形式对明码进行md5后的加解密openssl版本:1.0.2g 其余的自行验证编译:gcc aes_128_ecb.c -o aes_128_ecb -lssl -lcrypto 执行后果:./aes_128_ecbpasswd: 12345strMd516: A46B755EA8F1B4DDstrBase64Encrypt: cFeeVowosk4cR5gIg7i6ZQ==aes_128_ecb_decrypt OKstrAESDecrypt passwd is: 12345/*********************************************** aes_128_ecb.c** encrypte decrypt the password*********************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>#include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/buffer.h>#include <openssl/md5.h>int aes_128_ecb_encrypt(char *in, char *key, char *out) { int ret = 0, len = 0, len1 = 0, len2 = 0; unsigned char *result = NULL; EVP_CIPHER_CTX *ctx; ctx = EVP_CIPHER_CTX_new(); ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, (const unsigned char*)key, NULL); if (ret != 1) { printf("EVP_EncryptInit_ex error\n"); EVP_CIPHER_CTX_free(ctx); return 0; } result = (unsigned char *)malloc(AES_BLOCK_SIZE*64); ret = EVP_EncryptUpdate(ctx, result, &len1, (const unsigned char*)in, strlen(in)); if (ret != 1) { printf("EVP_EncryptUpdate error\n"); EVP_CIPHER_CTX_free(ctx); free(result); return 0; } ret = EVP_EncryptFinal_ex(ctx, result + len1, &len2); if (ret != 1) { printf("EVP_EncryptFinal_ex error\n"); EVP_CIPHER_CTX_free(ctx); free(result); return 0; } while (len < (len1+len2)) { out[len] = result[len]; len++; } EVP_CIPHER_CTX_free(ctx); free(result); return (len1+len2);}int aes_128_ecb_decrypt(char *in, char *key, char *out) { int ret = 0, len = 0, len1 = 0, len2 = 0; unsigned char *result = NULL; EVP_CIPHER_CTX *ctx; ctx = EVP_CIPHER_CTX_new(); ret = EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, (const unsigned char*)key, NULL); if (ret != 1) { printf("EVP_DecryptInit_ex error\n"); EVP_CIPHER_CTX_free(ctx); return 0; } result = (unsigned char *)malloc(AES_BLOCK_SIZE*64); ret = EVP_DecryptUpdate(ctx, result, &len1, (const unsigned char*)in,get_str_len(in));//不可应用strlen求取,字符串中可能含有结束符等 if (ret != 1) { printf("EVP_DecryptUpdate error\n"); EVP_CIPHER_CTX_free(ctx); free(result); return 0; } ret = EVP_DecryptFinal_ex(ctx, result + len1, &len2); if (ret != 1) { printf("EVP_DecryptFinal_ex error\n"); EVP_CIPHER_CTX_free(ctx); free(result); return 0; } while (len < (len1+len2)) { out[len] = result[len]; len++; } EVP_CIPHER_CTX_free(ctx); free(result); return 1;} // base64 编码char *base64_encode(const char *buffer, int length) { BIO *bmem = NULL; BIO *b64 = NULL; BUF_MEM *bptr; char *buff = NULL; b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, buffer, length); BIO_flush(b64); BIO_get_mem_ptr(b64, &bptr); BIO_set_close(b64, BIO_NOCLOSE); buff = (char *)malloc(bptr->length + 1); memcpy(buff, bptr->data, bptr->length); buff[bptr->length] = 0; BIO_free_all(b64); return buff;}// base64 解码char *base64_decode(char *input, int length) { BIO *b64 = NULL; BIO *bmem = NULL; char *buffer = NULL; buffer = (char *)malloc(length); memset(buffer, 0, length); b64 = BIO_new(BIO_f_base64()); BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new_mem_buf(input, length); bmem = BIO_push(b64, bmem); BIO_read(bmem, buffer, length); BIO_free_all(bmem); return buffer;}int md5_16(const char *src, char *out) { unsigned char c[MD5_DIGEST_LENGTH]; int i = 0; MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, src, strlen(src)); MD5_Final(c, &ctx); for (i = 0; i < MD5_DIGEST_LENGTH / 2; i++) { sprintf(out+i*2, "%02X", c[i+4]); } return 1;}int get_str_len(const char *in) { int num = 0; if(in == NULL) { return 0; } while (!((*(in + num) == NULL) && (*(in + num + 1) == NULL) \ && (*(in + num + 2) == NULL) && (*(in + num + 3) == NULL) \ && (*(in + num + 4) == NULL)&& (*(in + num + 5) == NULL) \ && (*(in + num + 6) == NULL)&& (*(in + num + 7) == NULL))) { num++; } return num;}int main(int argc, char const *argv[]){ char strAESEncrypt[1024] = {0}, strAESDecrypt[1024] = {0}, *strBase64Encrypt = NULL, *pStrBase64Decrypt = NULL, strMd516[17] = {0}; int nAESEncryptLen = 0; char strKey[128] = "0123456789ABCDEF"; char *passwd = "12345"; md5_16(strKey, strMd516); printf("passwd: %s\n", passwd); printf("strMd516: %s\n", strMd516); // 加密局部 nAESEncryptLen = aes_128_ecb_encrypt(passwd, strMd516, strAESEncrypt); strBase64Encrypt = base64_encode(strAESEncrypt, nAESEncryptLen); printf("strBase64Encrypt: %s\n", strBase64Encrypt); // 解密局部 pStrBase64Decrypt = base64_decode(strBase64Encrypt, strlen(strBase64Encrypt)); if (aes_128_ecb_decrypt(pStrBase64Decrypt, strMd516, strAESDecrypt) == 1) { printf("aes_128_ecb_decrypt OK\n"); printf("strAESDecrypt passwd is: %s\n", strAESDecrypt); } return 0;}

October 18, 2021 · 3 min · jiezi

关于openssl:假黄仁勋刷屏之后英伟达官方辟谣只有14秒是虚拟的OpenAI-开启-Codex-测试-思否周刊

40s 新闻速递报道称苹果新 iPhone 将着重降级影像零碎,推出摄影版“人像模式”音讯称 SpaceX 摸索太空广告业务,将来将用以太币等加密货币购买卫星广告牌苹果回应隐衷争议:检测儿童不良图片不会留下后门,且只在美国提供拆解发现华为 P50 Pro 采纳三层 CPU:或因买不到麒麟 9000 专用内存Facebook收买Giphy或涉嫌垄断,英国监管机构正在考察中Redis Labs 更名为 Redis:纯正而简略英特尔为其 C/C++ 编译器全面采纳 LLVM“假黄仁勋”刷屏之后,英伟达官网造谣:只有14秒是虚构的Firefox 跟上 Chrome 步调,将默认阻止不平安的下载OpenAI开启 Codex测试,一个将自然语言翻译成代码的 AI 零碎程序员笔记 CherryTree 0.99.40 公布elementary OS 6“Odin”公布,迄今为止最大的更新JetBrains Academy 推出收费 Kotlin Basics 课程Android 12 Beta 4 公布,已达到平台稳定性Firefox 91 正式公布,引入增强型 Cookie 革除行业资讯报道称苹果新 iPhone 将着重降级影像零碎,推出摄影版“人像模式”依据媒体周二征引知情人士报道,除了一系列惯例降级外,往年苹果将着重降级影像零碎,带来至多三项拍照和摄像方面的重大降级。 报道称,新款机型的摄像性能将引入此前只有拍照性能能力应用的“人像模式”,即对人物身后的背景进行虚化。与拍照模式一样,这一成果将通过深度传感器实现,用户能够在实现摄像后对含糊水平进行调整。 此外,新 iPhone 还会引入高质量视频存储格局 ProRes,给前期编辑更大的操作空间。与去年引入的 ProRAW 照片格局一样,这一性能可能将持续由 Pro 版本机型独占。此外爆料人示意苹果的照片编辑性能也将产生扭转,与目前将滤镜利用在整张照片不同,新款机型将借助 AI 技术容许用户在白平衡不变的状况下调整色彩和高光。此外往年新机型的拍照将出现一种更为均衡的格调,以更亮堂的体现显示暗影和贴近事实的色调。 思考到苹果通常会隔年推出大型的性能变动,在去年引入 5G、调整外观和产品线后,往年的降级会绝对温和。除了影像零碎外,新手机还将按例降级 A15 芯片,缩小屏幕“刘海”的面积,并应用新的屏幕技术提供高刷性能。 尽管目前苹果公司尚未确认公布新手机的工夫和模式,思考苹果曾经发表延后员工返回办公室的日程表,往年的秋季新品发布会有很大概率仍将以视频会议模式举办。 除了新手机外,知情人士示意公司在将来几个月里还有多条产品线将进行降级。其中包含应用自研芯片降级 MacBook Pro、从新设计的 iPad mini、针对校园用户的入门级 iPad、新款 Apple Watch 和入门款 AirPods。 ...

August 15, 2021 · 4 min · jiezi

关于openssl:Qt开发笔记OpenSSL库介绍windows上mingw32版本的OpenSSL编译模块化

若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/117503951 红瘦子(红模拟)的博文大全:开发技术汇合(蕴含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬联合等等)继续更新中…(点击传送门) Qt开发专栏:三方库开发技术 前言 Windows上mingw32版本的openssl的编译是属于比拟辣手的,OpenSSL自身不提供反对.。 OpenSSL介绍 OpenSSL是一个凋谢源代码的软件库包,应用程序能够应用这个包来进行平安通信,防止窃听,同时确认另一端连贯者的身份。这个包宽泛被利用在互联网的网页服务器上。 SSL是Secure Sockets Layer(安全套接层协定)的缩写,能够在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协定规范。其指标是保障两个利用间通信的保密性和可靠性,可在服务器端和用户端同时实现反对。曾经成为Internet上窃密通信的工业规范。 SSL能使用户/服务器利用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可抉择对用户进行认证。SSL协定要求建设在牢靠的传输层协定(TCP)之上。SSL协定的劣势在于它是与应用层协定独立无关的,高层的应用层协定(例如:HTTP,FTP,TELNET等)能通明地建设于SSL协定之上。SSL协定在应用层协定通信之前就曾经实现加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协定所传送的数据都会被加密,从而保障通信的私密性。 特点平安信道个性数据保密性 信息加密就是把明码的输出文件用加密算法转换成加密的文件以实现数据的窃密。加密的过程须要用到密钥来加密数据而后再解密。没有了密钥,就无奈解开加密的数据。数据加密之后,只有密钥要用一个平安的办法传送。加密过的数据能够公开地传送。 数据完整性 加密也能保证数据的一致性。例如:音讯验证码(MAC),可能校验用户提供的加密信息,接收者能够用MAC来校验加密数据,保证数据在传输过程中没有被篡改过。 平安验证 加密的另外一个用处是用来作为集体的标识,用户的密钥能够作为他的平安验证的标识。SSL是利用公开密钥的加密技术(RSA)来作为用户端与服务器端在传送秘密材料时的加密通信协定。 OpenSSL蕴含一个命令行工具用来实现OpenSSL库中的所有性能,更好的是,它可能曾经装置到你的零碎中了。 OpenSSL是一个弱小的安全套接字层明码库,Apache应用它加密HTTPS,OpenSSH应用它加密SSH,然而,你不应该只将其作为一个库来应用,它还是一个多用途的、跨平台的明码工具。 开源特点 Eric A. Young和Tim J. Hudson自1995年开始编写起初具备微小影响的OpenSSL软件包,这是一个没有太多限度的凋谢源代码的软件包。Eric A. Young 和Tim J. Hudson是加拿大人,起初因为写OpenSSL功成名就之后就到大公司里赚大钱去了。1998年,OpenSSL项目组接管了OpenSSL的开发工作,并推出了OpenSSL的0.9.1版,到目前为止,OpenSSL的算法曾经十分欠缺,对SSL2.0、SSL3.0以及TLS1.0都反对。 OpenSSL采纳C语言作为开发语言,这使得OpenSSL具备优良的跨平台性能,这对于宽广技术人员来说是一件十分美好的事件,能够在不同的平台应用同样相熟的货色。OpenSSL反对Linux、Windows、BSD、Mac、VMS等平台,这使得OpenSSL具备宽泛的适用性。但习惯C语言总比应用C++从新写一个跟OpenSSL雷同性能的软件包轻松不少。 性能基本功能 OpenSSL整个软件包大略能够分成三个次要的性能局部:SSL协定库、应用程序以及明码算法库。OpenSSL的目录构造天然也是围绕这三个性能局部进行布局的。 作为一个基于密码学的平安开发包,OpenSSL提供的性能相当弱小和全面,囊括了次要的明码算法、罕用的密钥和证书封装治理性能以及SSL协定,并提供了丰盛的应用程序供测试或其它目标应用。 辅助性能 BIO机制是OpenSSL提供的一种高层IO接口,该接口封装了简直所有类型的IO接口,如内存拜访、文件拜访以及Socket等。这使得代码的重用性大幅度提高,OpenSSL提供API的复杂性也升高了很多。 OpenSSL对于随机数的生成和治理也提供了一整套的解决办法和反对API函数。随机数的好坏是决定一个密钥是否平安的重要前提。 OpenSSL还提供了其它的一些辅助性能,如从口令生成密钥的API,证书签发和治理中的配置文件机制等等。如果你有足够的急躁,将会在深刻应用OpenSSL的过程缓缓发现很多这样的小性能,让你一直有新的惊喜。 算法密钥证书治理 密钥和证书治理是PKI的一个重要组成部分,OpenSSL为之提供了丰盛的性能,反对多种规范。 首先,OpenSSL实现了ASN.1的证书和密钥相干规范,提供了对证书、公钥、私钥、证书申请以及CRL等数据对象的DER、PEM和BASE64的编解码性能。OpenSSL提供了产生各种公开密钥对和对称密钥的办法、函数和应用程序,同时提供了对公钥和私钥的DER编解码性能。并实现了私钥的PKCS#12和PKCS#8的编解码性能。OpenSSL在规范中提供了对私钥的加密爱护性能,使得密钥能够平安地进行存储和散发。 在此基础上,OpenSSL实现了对证书的X.509规范编解码、PKCS#12格局的编解码以及PKCS#7的编解码性能。并提供了一种文本数据库,反对证书的治理性能,包含证书密钥产生、申请产生、证书签发、撤消和验证等性能。 事实上,OpenSSL提供的CA应用程序就是一个小型的证书管理中心(CA),实现了证书签发的整个流程和证书治理的大部分机制。 OpenSSL实现了SSL协定的SSLv2和SSLv3,反对了其中绝大部分算法协定。 OpenSSL也实现了TLSv1.0,TLS是SSLv3的标准化版,尽管区别不大,但毕竟有很多细节不尽相同。 尽管曾经有泛滥的软件实现了OpenSSL的性能,然而OpenSSL外面实现的SSL协定可能让咱们对SSL协定有一个更加分明的意识,因为至多存在两点:一是OpenSSL实现的SSL协定是凋谢源代码的,咱们能够查究SSL协定实现的每一个细节;二是OpenSSL实现的SSL协定是纯正的SSL协定,没有跟其它协定(如HTTP)协定联合在一起,廓清了SSL协定的本来面目。 对称加密 OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法别离是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都反对电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输入反馈模式(OFB)四种罕用的分组明码加密模式。其中,AES应用的加密反馈模式(CFB)和输入反馈模式(OFB)分组长度是128位,其它算法应用的则是64位。事实上,DES算法外面不仅仅是罕用的DES算法,还反对三个密钥和两个密钥3DES算法。 非对称加密 OpenSSL一共实现了4种非对称加密算法,包含DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法个别用于密钥替换。RSA算法既能够用于密钥替换,也能够用于数字签名,当然,如果你可能忍耐其迟缓的速度,那么也能够用于数据加密。DSA算法则个别只用于数字签名。信息摘要 OpenSSL实现了5种信息摘要算法,别离是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包含了SHA和SHA1两种信息摘要算法。此外,OpenSSL还实现了DSS规范中规定的两种信息摘要算法DSS和DSS1。 下载OpenSSL 官网:http://distfiles.macports.org/openssl/ CSDN:https://download.csdn.net/download/qq21497936/11537079 QQ群:1047134658(点击“文件”搜寻“openssl”,群内与博文同步更新) 编译OpenSSL装置windows下linux编译环境msys 将qt的mingw和本机的perl拷贝到msys文件夹下,而后增加门路 配置OpenSSL 配置装置门路 此处卡了一个多小时,各种找起因,原来是须要应用msys而不是msys2 批改Makefile 在最上层Makefile找到变量PERL 间接批改如下图: 持续mingw32-make.exe 漫长的期待后,持续报错 认真看是利用的问题,链接库失败可能是,然而咱们须要的 查看编译出的库 ...

June 3, 2021 · 1 min · jiezi

关于openssl:gRPC来聊一聊gRPC认证

[TOC] gRPC认证咱们再来回顾一下gRPC的根本构造 gRPC 是一个典型的C/S模型,须要开发客户端 和 服务端,客户端与服务端须要达成协议,应用某一个确认的传输协定来传输数据,gRPC通常默认是应用protobuf来作为传输协定,当然也是能够应用其余自定义的。 那么,客户端与服务端要通信之前,客户端如何晓得本人的数据是发给哪一个明确的服务端呢?反过来,服务端是不是也须要有一种形式来弄个分明本人的数据要返回给谁呢? 那么就不得不提gRPC的认证 认证形式此处说到的认证,不是用户的身份认证,而是指多个server 和 多个client之间,如何辨认对方是谁,并且能够平安的进行数据传输 SSL/TLS认证形式(采纳http2协定)基于Token的认证形式(基于平安连贯)不采纳任何措施的连贯,这是不平安的连贯(默认采纳http1)自定义的身份认证,gRPC提供了接口用于扩大自定义认证形式明天就和大家分享一下 SSL/TLS认证形式 和 基于Token的认证形式 ,这里再来回顾一下上一篇讲到的 gRPC音讯传输的四种类型申请-响应式服务端流式音讯,客户端申请一次,服务端会一一系列的数据,即数据流客户端流式音讯,客户端用数据流申请,服务端做响应双向流的形式,即单方都是流式数据简略的例子: service Example{ rpc ReqAndRsp(Req) returns (Response) rpc ReqAndStream(Req) returns (Stream Response) rpc StreamAndRsp(Stream Request) returns (Response) rpc BidStream(Stream Request) returns (Stream response)}SSL/TLS认证形式那么什么是SSL/TLS?TLS(Transport Layer Security) 是 SSL(Secure Socket Layer) 的后续版本,它们是用于在互联网两台计算机之间用于身份验证和加密的一种协定。 基于SSL/TLS的通道加密是gRPC罕用的伎俩,那么个别咱们都是如何使用他的,他的架构个别会是啥样的? GRPC 默认是基于HTTP/2的TLS 对客户端和服务端替换的所有数据进行加密传输的 那么HTTP 2 默认就有加密吗?HTTP 2 协定默认是没有加密的,它只是事后定义好了TLS的轮廓,是TLS保障安全性,TLS做的加密 HTTP 2 有啥个性?这里简略说一下,HTTP 2 较之前的版本有如下4个重要的变动: 二进制分帧将所有传输的信息宰割为更小的音讯和帧,并对它们采纳二进制格局的编码 多路io复用在共享TCP链接的根底上同时发送申请和响应,http音讯被合成为独立的帧,乱序发送,服务端依据标识符和首部将音讯从新组装起来 头部压缩服务器推送 server push服务器能够额定的向客户端推送资源,而无需客户端明确的申请 SSL/TLS加密的根本做法是啥?SSL/TLS 通过将称为X.509 证书的数字文档将网站和公司的实体信息绑定到加密密钥来进行工作。 ...

May 27, 2021 · 4 min · jiezi

关于openssl:openssl-证书生成笔记go-115版本以上

[TOC] openssl证书生成问题golang 1.15+版本上,用 gRPC通过TLS实现数据传输加密时,会报错证书的问题 rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate is valid for www.eline.com, not xxx"panic: rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate is valid for www.eline.com, not xxx" 造成的起因是因为咱们用的证书,并没有开启SAN扩大(默认是没有开启SAN扩大)所生成的, 导致客户端和服务端无奈建设连贯 开始解决问题 应用开启扩大SAN的证书什么是 SANSAN(Subject Alternative Name) 是 SSL 规范 x509 中定义的一个扩大。应用了 SAN 字段的 SSL 证书,能够扩大此证书反对的域名,使得一个证书能够反对多个不同域名的解析。 生成CA根证书新建 ca.conf vim ca.conf ...

May 27, 2021 · 2 min · jiezi

关于openssl:怎样用openssl制作自签名证书

How to use OpenSSL to create self signed certificateMethod 1Procedure: Create a no-password private key,Create the certificate.openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -out unencrypted-private.keygenpkeygenerate a private key.-algorithm rsa use RSA algorithm.-pkeyopt rsa_keygen_bits:2048the key's length is 2048.-outoutput filename.openssl req -x509 -key unencrypted-private.key -out new.crtreqopenssl's subcommand, used to create and process CSR(certificate signing request).-509do not create a CSR, but create a certificate.-keythe private key used to sign the certificate-outthe output certificate.Method 2Procedure: ...

February 28, 2021 · 2 min · jiezi

关于openssl:mac-os-silicon-m1-编译openssl

Andrew MadsenFOLLOW @ARMADSEN ON MICRO.BLOG.ABOUT ARCHIVE PHOTOS Building OpenSSL for ARM/Apple silicon MacsJUNE 22, 2020[](https://blog.andrewmadsen.com/) I tend to shy away from dependencies when possible. But my app, Aether, has an unavoidable dependency on tqsllib, which in turn depends on OpenSSL. Originally, OpenSSL shipped with macOS, so using it was no big deal. Apple deprecated it years ago (for very good reasons) and recommends building it yourself from up-to-date source if you need it. So, I do just that. ...

February 25, 2021 · 3 min · jiezi

关于openssl:从零搭建php环境openresty

参考起源:http://openresty.org/en/insta... 一、配置编译参数,应用默认 > cd /usr/local/src/> tar -xvf openresty-1.19.3.1.tar.gz> cd openresty-1.19.3.1> ./configure -j21、Can't locate File/Temp.pm in @INC (you may need to install the File::Temp module) (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at ./configure line 9. yum install perl2、./configure: error: the HTTP rewrite module requires the PCRE library.You can either disable the module by using --without-http_rewrite_moduleoption, or install the PCRE library into the system, or build the PCRE librarystatically from the source with nginx by using --with-pcre=<path> option. ...

December 14, 2020 · 2 min · jiezi

关于openssl:Openssl-EVP-to-implement-RSA-and-SM2-endec-signverify

Using the EVP interface in openssl to implement RSA and SM2 encrypt decrypt sign and verify (C lauguage)0. AbstractOpenssl provides a series of interfaces that name is EVP structure. Using the interfaces, it is pretty convenient to implement these algorithm of asymmetric RSA or SM2 encryption decryption signature and verification. This paper sorted out the usage of OPENSSL EVP C-lauguage interface, and implement the SM2 and RSA encrypt decrypt signature and verify. Combining with the code, this paper introduced the related functions of RSA and SM2 algorithm. Finally, ran the program to test module functions. ...

September 2, 2020 · 1 min · jiezi

最常见的OpenSSL命令

https://www.sslshopper.com/ar... 最通用的SSL工具之一是OpenSSL,它是SSL协议的开源实现。几乎每个平台都有OpenSSL版本,包括Windows,Linux和Mac OS X.OpenSSL通常用于为许多不同平台(包括Apache)创建CSR和私钥。但是,它还有数百种不同的功能,允许您查看CSR或证书的详细信息,比较证书的MD5哈希和私钥(以确保它们匹配),验证证书是否在任何网站上正确安装,并将证书转换为其他格式。可以在此处找到OpenSSL for Windows的编译版本。 如果您不想打扰OpenSSL,可以使用我们的SSL证书工具执行许多相同的操作。下面,我们列出了最常见的OpenSSL命令及其用法: 常规OpenSSL命令这些命令允许您生成CSR,证书,私钥以及执行其他其他任务。 Base64编解码编码: echo "我是一片云 天空是我家\n朝迎旭日升 暮送夕阳下" | openssl enc -base64输出: 5oiR5piv5LiA54mH5LqRIOWkqeepuuaYr+aIkeWutlxu5pyd6L+O5pet5pel5Y2H44CA5pqu6YCB5aSV6Ziz5LiLCg== 对上面的字符串解码 echo '5oiR5piv5LiA54mH5LqRIOWkqeepuuaYr+aIkeWutlxu5pyd6L+O5pet5pel5Y2H44CA5pqu6YCB5aSV6Ziz5LiLCg==' |openssl enc -base64 -d输出: 我是一片云 天空是我家\n朝迎旭日升 暮送夕阳下注意:这里编码和解码都是用的 enc 命令,只是解码加了-d参数。md5摘要形成摘要: echo "我是一片云 天空是我家 朝迎旭日升 暮送夕阳下" | openssl md5输出 (stdin)= 2418617a0586d93db1db5e43260a43bb校验摘要:再生成一次,对比生成的字符串。 生成服务器端 web 服务器密码用于基本验证访问的服务器密码, 密码只能是8位, 多了会有警告。 openssl passwd -crypt yourpass会生成 U0tfb.p0Pit5I重复执行上面的指令时密码会有变化。所以密码是有随机变量在里面。 保存到 ·/etc/nginx/conf.d/pass`文件中 $ cat /etc/nginx/conf.d/passyouradmin:U0tfb.p0Pit5I密码文件是 用户名:加密密码 的格式存储的。 Nginx服务器的配置 server { server_name yourserver.cn; root /var/www/webapps/; index index.html index.htm; location / { auth_basic "server login auth"; auth_basic_user_file conf.d/pass;...这样就能通过基本验证, 保护服务器的内容只能在输入密码的情况下进行访问。 ...

October 18, 2019 · 2 min · jiezi

使用openssl-生成证书

关于最近在用egg写一个简单的CURD项目,使用的是jwt并打算使用RS256加密方式进行加密,这里记录一下如何生成RS256证书步骤检查是否安装opensslopenssl version -a 发现已经安装了openssl,这里我们将版本更新至最新版 如果没有安装的话可以直接使用yum安装yum install openssl更新opensslyum update openssl 生成公钥openssl genrsa -out rsa_private_key.pem 1024生成私钥openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成成功,复制并且使用~~总结文章首发于https://www.ahwgs.cn/openssl-key.html

June 30, 2019 · 1 min · jiezi

Create-a-selfsigned-SSL-Certificate-using-OpenSSL-in-Windows

PreparationUnfortunately, there is no official OpenSSL client for Windows. However, you could download it from WinOpenSSL. Then you can use the OpenSSL utility to generate a Private Key, Certificate Signing Request (CSR) and Self-Signed Certificate. Run the openssl.exe in Command Prompt or PowerShell, the executable will be located in folder C:\Program Files\OpenSSL-Win64\bin\ if you install the 64bit version. First Step - Generate a Private KeyEnter the following command to create your RSA Private Key: ...

June 13, 2019 · 3 min · jiezi

使用-OpenSSL-命令行管理证书md

OpenSSL 概述OpenSSL 的结构 OpenSSL 目录功能对照表目录名功能描述Crypto存放 OpenSSL 所有加密算法源码文件和相关标注如 X.509 源码文件,是 OpenSSL 中最重要的目录,包含了 OpenSSL 密码算法库的所有内容SSL存放 OpenSSL 中 SSL 协议各个版本和 TLS 1.0 协议源码文件,包含了 OpenSSL 协议库的所有内容Apps存放 OpenSSL 中所有应用程序源码文件,如 CA、X509 等应用程序的源文件就存放在这里Doc存放了 OpenSSL 中所有的使用说明文档,包含三个部分:应用程序说明文档、加密算法库 API 说明文档及 SSL 协议API说明文档Demos存放了一些基于 OpenSSL 的应用程序例子,这些例子一般都很简单,演示怎么使用 OpenSSL 中的一个功能Include存放了使用 OpenSSL 的库时需要的头文件Test存放了 OpenSSL 自身功能测试程序的源码文件查看 OpenSSL 版本# 查看当前系统使用的 OpenSSL 版本$ openssl versionOpenSSL 1.0.2g 1 Mar 2016# 获取完整的版本信息$ openssl version -a ...OPENSSLDIR: "/usr/lib/ssl" # OpenSSL 默认查找和配置证书目录构建特定版本的 OpenSSLOpenSSL 官网:https://www.openssl.org/ # 下载 OpenSSL 二进制包$ wget https://www.openssl.org/source/openssl-1.1.1.tar.gz# 解压缩,先调用 gzip 解压缩,再解开文件。$ tar -xzvf openssl-1.0.2o.tar.gz # 安装配置$ cd openssl-1.0.2o/$ ./config \--prefix=/opt/openssl \--openssldir=/opt/openssl \ # 设置安装目录enable-ec_nistp_64_gcc_128 # 使用优化后的常用椭圆曲线算法$ make depend # 生成可执行文件$ make # 编译$ sudo make install # 安装# OpenSSL 安装在 /opt/openssl/ 目录下$ cd /opt/openssl/$ ls -ltotal 40drwxr-xr-x 2 root root 4096 Jun 15 08:08 bindrwxr-xr-x 2 root root 4096 Jun 15 08:08 certs # 根证书目录、可信证书库drwxr-xr-x 3 root root 4096 Jun 15 08:08 includedrwxr-xr-x 4 root root 4096 Jun 15 08:08 libdrwxr-xr-x 6 root root 4096 Jun 15 08:08 mandrwxr-xr-x 2 root root 4096 Jun 15 08:08 misc # 补充脚本-rw-r--r-- 1 root root 10835 Jun 15 08:08 openssl.cnfdrwxr-xr-x 2 root root 4096 Jun 15 08:08 private # 私钥目录查看可用命令:openssl help# ------ 所有可用工具 ------Standard commands asn1parse ca ciphers cmscrl crl2pkcs7 dgst dhdhparam dsa dsaparam ececparam enc engine errstrgendh gendsa genpkey genrsanseq ocsp passwd pkcs12pkcs7 pkcs8 pkey pkeyparampkeyutl prime rand reqrsa rsautl s_client s_servers_time sess_id smime speedspkac srp ts verifyversion x509# man + 工具名称,显示某一命令的详细信息# man ciphers,显示如何配置密码套件# ------ 消息摘要命令 ------Message Digest commands (see the `dgst' command for more details)md4 md5 rmd160 shasha1# ------ 加密命令 ------Cipher commands (see the `enc' command for more details)aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecbaes-256-cbc aes-256-ecb base64 bfbf-cbc bf-cfb bf-ecb bf-ofbcamellia-128-cbc camellia-128-ecb camellia-192-cbc camellia-192-ecbcamellia-256-cbc camellia-256-ecb cast cast-cbccast5-cbc cast5-cfb cast5-ecb cast5-ofbdes des-cbc des-cfb des-ecbdes-ede des-ede-cbc des-ede-cfb des-ede-ofbdes-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofbdes-ofb des3 desx rc2rc2-40-cbc rc2-64-cbc rc2-cbc rc2-cfbrc2-ecb rc2-ofb rc4 rc4-40seed seed-cbc seed-cfb seed-ecbseed-ofb获取算法的帮助信息# 示例:获取 RSA 算法的帮助信息$ openssl rsa --help证书格式及转换证书格式X.509 标准X.509 标准来自国际电信联盟电信标准(ITU-T)的 X.500 标准。 ...

May 22, 2019 · 22 min · jiezi

X509PKCS文件格式介绍

ASN.1 - 数据结构描述语言引用自Wiki: ASN.1 is a standard interface description language for defining data structures that can be serialized and deserialized in a cross-platform way.也就是说ASN.1是一种用来定义数据结构的接口描述语言,它不是二进制,也不是文件格式,看下面的例子你就会明白了: FooQuestion ::= SEQUENCE { trackingNumber INTEGER, question IA5String}这段代码定义了FooQuestion的数据结构,下面是FooQuestion这个数据接口的某个具体的数据: myQuestion FooQuestion ::= SEQUENCE { trackingNumber 5, question "Anybody there?"}ASN.1用在很多地方比如下面要讲的X.509和PKCS group of cryptography standards。 文件编码格式DER编码格式引用自Wiki: ASN.1 is closely associated with a set of encoding rules that specify how to represent a data structure as a series of bytes意思是ASN.1有一套关联的编码规则,这些编码规则用来规定如何用二进制来表示数据结构,DER是其中一种。 ...

April 27, 2019 · 3 min · jiezi

在 OpenSSL 1.1.1 下支持 OpenResty 的非阻塞 SSL session fetch

起如果你用 OpenResty 做过 SSL session reuse,你可能会用到其中的异步获取 SSL session 的特性,比如在 ssl_session_fetch_by_lua* 里面发起非阻塞的网络请求,从 memcache 或别的什么存储服务器上读取 SSL session。ssl_session_fetch_by_lua* 的实现原理,就是在 OpenSSL 的 session get callback 里执行 Lua 代码。然而 OpenSSL 的 session get callback 并不支持 yield,所以只靠原生 OpenSSL 是没办法支持在该阶段发起非阻塞的网络请求的。因此,Cloudflare 的工程师贡献了一个 OpenSSL 的补丁给 OpenResty,让 OpenSSL 的 session get callback 支持 yield。要想解释这个补丁的实现原理,我们得先说明下什么是“支持 yield”。在 OpenResty 的语境里,支持 yield 就是指某个函数(或者阶段)可以被中断,然后在合适的时间继续执行。这样的函数需要至少有三种返回结果:OK,ERROR 和 AGAIN。如果函数返回 AGAIN,表示它的工作被中断了,比如发起了一个网络请求,需要等待对端的响应。同时该函数还会把自己的状态保存到一个 ctx 里。当合适的机会来临时,它会被重新调用,读取 ctx 里面的状态继续执行下去,直到返回 OK 或 ERROR 为止。让 session get callback 支持 yield 的补丁最早是针对 OpenSSL 1.0 开发的。后来 OpenSSL 1.1.0 版本大改了握手流程,于是 Cloudflare 的工程师写了第二版补丁。之后 OpenSSL 1.1.0 的小版本又有些许小变化,我便帮着润色了下。针对 OpenSSL 1.1.0 版本的补丁,主要做了两个改动:在调用获取 session 的 callback 的时候,如果 callback 返回一个 magic 值,那么就保存当前的上下文,返回一个表示重试的错误码。在 server 处理 client 请求的状态机中,引入一个新的状态 READ_STATE_PROCESS 。这个状态里,OpenSSL 会尝试 session resumption。该过程有可能会返回一个表示重试的错误码,在这种情况下,如果重新调用 SSL_handshake, OpenSSL 会重新进入这一状态。补丁的代码可以在这里看到:https://github.com/openresty/…除了要给 OpenSSL 打补丁外,该功能还依赖于一个 Nginx 补丁。Nginx 的 ngx_ssl_handshake 只有在 SSL_ERROR_WANT_READ 和 SSL_ERROR_WANT_WRITE 下才会重试 SSL_handshake。 所以 OpenResty 给 Nginx 打了补丁,让它在 SSL_ERROR_PENDING_SESSION 下也能重试。SSL_ERROR_PENDING_SESSION 这个名字来源于 BoringSSL。BoringSSL 是 Google 和 Cloudflare 一起开发的,在这个 SSL 库里面,session fetch 是可以 yield 的。该特性的名字就叫做 PENDING SESSION。ssl_session_fetch_by_lua* 就是先在 Cloudflare 内部使用一段时间,然后再开源出来。自然,这个 Nginx 补丁也是针对 BoringSSL 设计的。为此,OpenSSL 补丁也给自己的错误类型起了个 SSL_ERROR_PENDING_SESSION 的别名。补丁的代码可以在这里看到:https://github.com/openresty/…OpenSSL 1.1.1 版本对握手流程又做了新的变化,变化之大,以致于现有的补丁没法再缝缝补补凑合用下去了。由于这次没有天降 Cloudflare 工程师来帮忙,我就接下了这一任务,开始针对新的握手流程修改当前的补丁。承看了下 OpenSSL 1.1.1 涉及的函数,最大的变化是它把 session resumption 从原来的 READ_STATE_BODY 向后挪到了 READ_STATE_POST_PROCESS。补丁里之所以要引入 READ_STATE_PROCESS 把 READ_STATE_BODY 劈成两半,是因为 READ_STATE_BODY 里包含了读取 TLS 数据块的这一不可重试的操作。但是 READ_STATE_POST_PROCESS 里就没这样的顾忌了。所以我们可以把 READ_STATE_PROCESS 这个阶段去掉。一番调整后,我发现 ssl_session_fetch_by_lua* 现在只要一 yield,就会报 Fatal 错误。一路追查下来发现,OpenSSL 有些函数的返回码改变了。如果照原来的错误码,会走到一个被 SSLfatal 挡路的地方。于是调整了下返回码。现在 ssl_session_fetch_by_lua* 已经能 yield 了,只是 resume 的时候会报 no cipher 的错误。可是我再三确认,握手时是有 cipher 传递的。我拿着 OpenSSL 1.1.0 和 OpenSSL 1.1.1 的源码,就 server 处理 ClientHello 的 post process 部分的流程对比了下,发现还有一处不同。OpenSSL 1.1.0 里面,关于 cipher 处理部分是在 session resumption 之后进行的。而 OpenSSL 1.1.1 为了遵循 TLS 1.3,把 cipher 的处理挪到 session resumption 之前完成。cipher 处理过程中会把 cipher 给消耗掉,导致重入 session resumption 逻辑的时候,报 no cipher 错误。解决方法也很简单,就是在处理 cipher 前把它保存起来,如果要 yield,就恢复它。这么改之后,OpenResty 所有关于 SSL session fetch 的测试在 OpenSSL 1.1.1 下终于能跑通了。补丁的代码可以在这里看到:https://github.com/spacewande…转看上去本文到这里应该完了,但是,还没有呢! 在开发 patch 的过程中,我发现有一个 CLIENT_HELLO_CB,好像在我每次改动的地方都能看到它。这种感觉,就像一路上发现有人一直跟你同路。这种情况下,我不由得对这个 CB 感兴趣起来。查了下发现,OpenSSL 1.1.1 起引入了一个 SSL_CTX_set_client_hello_cb 的函数。这个 callback 在 server 处理 ClientHello 时调用,而且支持 yield。这不就是打完 patch 之后的 session get callback 么! 当然,我们仍然需要通过 session get callback 来设置 session,但已经不需要要求 session get callback 支持 yield 了。我们可以在支持 yield 的 ClientHello callback 中发起非阻塞的网络请求,然后待到 session get callback 再把准备好的 session 丢出去。这么一来,就不需要给 OpenSSL 打 patch 了。合于是我着手修改 OpenResty 的代码,如果当前 OpenSSL 支持 ClientHello callback,就改由 ClientHello callback 执行 ssl_session_fetch_by_lua* 里的 Lua 代码。我们依然需要注册 session get callback,但如果 ClientHello callback 已经执行了 ssl_session_fetch_by_lua*,那么就该 callback 就只需要返回准备好的 session 了。ClientHello callback 还有一个作用,就是你可以在这里面修改 preferred cipher。在没有 ClientHello callback 的时代,你得自己造一个。其余的 callback 还是有覆盖不到的路径。当然,由于只在有 session id 的情况下才会执行 ssl_session_fetch_by_lua* 的逻辑,直接在该阶段里修改 preferred cipher 是行不通的。最后,还需要修改下 Nginx 的那个补丁,让它在 SSL_ERROR_WANT_CLIENT_HELLO_CB 下也重试。你可能会奇怪,为什么我会在开发完对 OpenSSL 1.1.1 的 patch 之后,还要另起炉灶开发 ClientHello callback?因为一直对 OpenSSL 修修补补也不是什么好办法。毕竟我不是专业的 OpenSSL 开发者,改 OpenSSL 可能会改出 bug。虽然目前还需要在 Nginx 端维护一个补丁,但是维护 Nginx 的补丁相对来说简单一些,毕竟 OpenResty 都维护了那么多 Nginx 的补丁,也不缺能改 Nginx 的人。 ...

April 13, 2019 · 2 min · jiezi

【随笔】工程师都是性情中人

it行业工程师往往给人很木的感觉,实际上个个都是性情中人,心里藏着一团火。从代码或工程命名可以看出很多工程师都是性情中人。比如有拿地名做名字的,有拿吃的做名字的,有的给项目起的名字像外号等等。拿android来说。1.android的版本,cupcake, donut, froyo,以及让android名声大噪的2.3 Gingerbread, 里程碑4.0 Ice Cream Sandwich,kitkat,5.0是lollipop,以及后边的棉花糖,牛轧糖,oreo等,9.0是pie。明显都是吃货。可能就是因为这一天的免费零食是pie,而这一天正好项目立项,pie很好吃,代号就是pie了。normandie播放框架的命名也是由于立项正好赶上二战胜利周年纪念,normandie登陆使二战欧洲战场态势发生了转变。2.android里的播放器命名为awesome(牛b)player, nu(乐队走电子迷幻路线)player,基于alooper,ahanlder,amessage实现的线程,异步等机制很大程度上解决了框架api实现里的耗时操作比较容易引起的应用anr等问题比如访问网络或弱网络下请求播放数据等情况。normandie播放框架参考了这套机制基于looper,handler,thread,event实现了自己的线程模型,异步机制,为网络请求耗时比较容易引起anr做了大量优化,比如nuplayer没有的abort机制,可以随时中断请求线程避免在快速退出切换等场景下网络请求线程阻塞等等。3.android里引入的开源openssl改名boring(无聊烦人)ssl。normandie播放框架支持https的时候折腾过一段时间openssl内嵌到ffmpeg,版本兼容问题很麻烦,版本稍有变化就不兼容了,确实够boring的。还有哪些欢迎跟帖。

February 15, 2019 · 1 min · jiezi

OpenSSL常用命令快速上手

OpenSSL常用命令快速上手RSA篇我们的操作流程为:生成RSA密钥key.pem(也称私钥,密钥对)。从key.pem中导出公钥pubkey.pem。使用公钥pubkey.pem对文件test.txt进行加密,得到密文test.enc。使用私钥key.pem对test.enc进行解密,得到译文test.dec。对比test.txt和test.dec,应该是一样的。使用key.pem对test.txt进行签名,得到test.sig。使用pubkey.pem对test.txt的签名test.sig进行验签。key.pem ====导出=====> pubkey.pempubkey.pem + text.txt ===公钥加密===> test.enckey.pem + test.enc ===私钥解密===> test.deckey.pem + test.txt ===私钥签名===> test.sigpubkey.pem + test.txt + test.sig ==> 验证签名命令如下:1. 生成密钥对并导出公钥# 生成密钥对openssl genrsa -out key.pem# 导出公钥openssl rsa -in key.pem -pubout -out pubkey.pem参数说明:-out: 指定输出的文件-in: 指定输入的文件-pubout: 指定输出公钥。如果不加该参数,默认输出的为私钥2. 加解密操作# 生成一个待加密的测试文件echo “hello, world” > test.txt# 公钥加密openssl rsautl -encrypt -pubin -inkey pubkey.pem -in test.txt -out test.encopenssl rsautl -decrypt -inkey key.pem -in test.enc -out test.dec参数说明:-encrypt: 加密操作-decrypt: 解密操作-pubin: 指定输入公钥。如果不加该参数,则认为输入的为私钥-inkey: 密钥文件核对文件# 如果没有任何输出,则文件相同cmp test.txt test.dec3. 签名、验签# 签名openssl dgst -sign key.pem -sha256 -out test.sig test.txt# 验签openssl dgst -verify pubkey.pem -sha256 -signature test.sig test.txt参数说明:-sign: 使用私钥签名-verify: 使用公钥验签-sha256: 摘要算法,也可以为md5/sha1/sha384/sha512等,签名验签使用的摘要算法应相同-signature: 待验证的签名文件4. 查看密钥信息# 查看私钥信息openssl rsa -in key.pem -noout -text# 查看公钥信息openssl rsa -pubin -in pubkey.pem -noout -text参数说明:-noout: 不打印密钥数据-text: 以文本方式打印密钥信息 ...

February 1, 2019 · 1 min · jiezi

PHP 将 mcrypt_encrypt 迁移至 openssl_encrypt 的方法

注:php 的 mcrypt_ 函数簇在 7.1.0 版本中开始 deprecated,并在 7.2.0 版本中彻底废弃。其实在 2015 就已经开始建议大家使用 openssl_encrypt/openssl_decrypt 来代替 mcrypt_encrypt/mcrypt_decrypt,缓冲了 N 久,这一天终于在 7.2.0 版本上到来了。为什么要提及迁移,比如 A & B 两套系统使用 AES 加密做数据传输,且 A 作为客户端,B 则是第三方的服务,且 A 已经在使用 7.2.0+ 版本,而 B 作为长期运行的服务仍在使用 7.1.0-,那我们能做的就是在 A 上使用 openssl_簇 原样的实现 mcrypt_簇 的加解密功能,以便兼容 B 服务,且 mcrypt_簇 是有一些需要多加注意的地方,否则迁移之路略微坎坷。mcrypt_簇 虽说被遗弃了,但 文档页 上依然有很多值得注意的文档贡献,有助于我们将 mcrypt_簇 迁移至 openssl_簇,大家应该仔细看一下。1.If you’re writing code to encrypt/encrypt data in 2015, you should use openssl_encrypt() and openssl_decrypt(). The underlying library (libmcrypt) has been abandoned since 2007, and performs far worse than OpenSSL (which leverages AES-NI on modern processors and is cache-timing safe).2.Also, MCRYPT_RIJNDAEL_256 is not AES-256, it’s a different variant of the Rijndael block cipher. If you want AES-256 in mcrypt, you have to use MCRYPT_RIJNDAEL_128 with a 32-byte key. OpenSSL makes it more obvious which mode you are using (i.e. ‘aes-128-cbc’ vs ‘aes-256-ctr’).3.OpenSSL also uses PKCS7 padding with CBC mode rather than mcrypt’s NULL byte padding. Thus, mcrypt is more likely to make your code vulnerable to padding oracle attacks than OpenSSL.1、即刻起,应尽可能的使用 openssl_簇 代替 mcrypt_簇 来实现数据的加密功能。2、MCRYPT_RIJNDAEL_256 并不是 AES-256,如果想使用 mcrypt_簇 实现 AES-256,则你应该使用 MCRYPT_RIJNDAEL_128 算法 + 32位的 key,openssl_簇 则更为清晰的明确了各种模式。这里我整理了一下对应关系供大家参考:MCRYPT_RIJNDAEL_128 & CBC + 16位Key = openssl_encrypt(AES-128-CBC, 16位Key) = AES-128MCRYPT_RIJNDAEL_128 & CBC + 24位Key = openssl_encrypt(AES-192-CBC, 24位Key) = AES-192MCRYPT_RIJNDAEL_128 & CBC + 32位Key = openssl_encrypt(AES-256-CBC, 32位Key) = AES-256(注:AES-128, 192 and 256 的加密 key 的长度分别为 16, 24 and 32 位)openssl_簇 的确更为清晰明了,而且 mcrypt_get_key_size 得到的 key 长度都是 32 位,所以不太靠谱。iv 到是会根据 cipher 方法变更 16 、24、32,但 openssl_簇的 AES cipher 的 iv 长度适中要求为 16 位。所以,我们为了最大的适配,即便现在不会再用,也要知道 mcrypt_簇 实现 AES-128/192/256 的标准方式为:cipher 选 MCRYPT_RIJNDAEL_128根据 cipher 和 mode 获取 iv 长度并生成 iv根据实际业务来确定 key 长度: AES-128 16位 / AES-192 24位 / AES-256 32位,而不是使用 mcrypt_get_key_size3、这一点其实蛮重要的,涉及 加密算法数据块 & 填充算法PKCS7 的概念。我在支付宝 alipay SDK 中有看到此算法的实现,虽然 sdk 中仍然使用的 mcrypt_簇,但已结合了 PKCS7 填充算法,为什么要这样做呢?其一是为了安全&兼容,php mcrypt 会使用 null(‘0’) 对数据块进行填充,java/.net 则是使用 PKCS7。其二则是为后期迁移至 openssl_簇 的准备,openssl 的填充模式默认是使用 PKCS7 填充的(当然也可以指定使用 null(‘0’) 填充模式,但极力不推荐的)。mcrypt_encrypt/mcrypt_decrypt相关的支持函数// 支持的算法 rijndael-128|rijndael-192|rijndael-256(此算法并非AES-256,需使用rijndael-128 + key32byte实现)mcrypt_list_algorithms()// 支持的模式 cbc ecb 等mcrypt_list_modes()// 算法所对应的 key 长度:AES-128, 192 and 256 的加密 key 的长度分别为 16, 24 and 32 位mcrypt_get_key_size(string $cipher , string $mode)// 算法所对应的加密向量 iv 的长度mcrypt_get_iv_size(string $cipher , string $mode)// 生成 ivmcrypt_create_iv(mcrypt_get_iv_size(string $cipher , string $mode))// 加密算法数据块的大小 主要用于填充算法mcrypt_get_block_size(string $cipher , string $mode)PKCS7 填充算法的实现/** * 填充算法 * @param string $source * @return string /function addPKCS7Padding($source, $cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC){ $source = trim($source); // 获取加密算法数据块大小 用于计算需要填充多少位 $block_size = mcrypt_get_block_size($cipher, $mode); $pad = $block_size - (strlen($source) % $block_size); if ($pad <= $block_size) { $char = chr($pad); $source .= str_repeat($char, $pad); } return $source;}/* * 移去填充算法 * @param string $source * @return string /function stripPKCS7Padding($source){ $source = trim($source); $char = substr($source, -1); $num = ord($char); if ($num == 62) { return $source; } $source = substr($source, 0, -$num); return $source;}openssl_encrypt/openssl_decrypt简单讲解一下日常开发中用到的参数/* * $data 待加密内容 * $method 加密算法 * $key 加密key * $options 数据块填充模式 * $iv 加密向量**/openssl_encrypt(string $data, string $method, string $key[, int $options = 0[, string $iv = “”[, string &$tag = NULL[, string $aad = “”[, int $tag_length = 16 ]]]]]): stringopenssl_decrypt(string $data, string $method, string $key[, int $options = 0[, string $iv = “”[, string $tag = "" [, string $aad = "" ]]]] ) : string这里需要特别注意的就是 options 选项,很多人 mcrypt_簇 迁移至 openssl_簇 时二者加密结果内容不一致,大都是此处没有搞清楚的原因。options 共 3 个值可选0 默认值 使用 PKCS7 填充算法,不对加密结果进行 base64encode1 OPENSSL_RAW_DATA 使用 PKCS7 填充算法,且对加密结果进行 base64encode2 OPENSSL_ZERO_PADDING 使用 null(‘0’) 进行填充,且对加密结果进行 base64encode所以要注意填充算法及对结果是否进行了 base64encode 编码。mcrypt_簇 迁移至 openssl_簇mcrypt_簇/** * 加密算法 * @param string $content 待加密数据 * @param string $key 加密key * @param string $iv 加密向量 * @param string $cipher 加密算法 * @param string $mode 加密模式 * @return string 加密后的内容且base64encode /function encrypt($content, $key, $iv, $cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC){ //AES, 128 模式加密数据 CBC $content = addPKCS7Padding($content); $content_encrypted = mcrypt_encrypt($cipher, $key, $content, $mode, $iv); return base64_encode($content_encrypted);}/* * 解密算法 * @param [type] $content [description] * @param [type] $key [description] * @param [type] $iv [description] * @param [type] $cipher [description] * @param [type] $mode [description] * @return [type] [description] /function decrypt($content_encrypted, $key, $iv, $cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC){ //AES, 128 模式加密数据 CBC $content_encrypted = base64_decode($content_encrypted); $content = mcrypt_decrypt($cipher, $key, $content_encrypted, $mode, $iv); $content = stripPKSC7Padding($content); return $content;}/* * PKCS7填充算法 * @param string $source * @return string /function addPKCS7Padding($source, $cipher = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_CBC){ $source = trim($source); $block = mcrypt_get_block_size($cipher, $mode); $pad = $block - (strlen($source) % $block); if ($pad <= $block) { $char = chr($pad); $source .= str_repeat($char, $pad); } return $source;}/* * 移去PKCS7填充算法 * @param string $source * @return string */function stripPKSC7Padding($source){ $source = trim($source); $char = substr($source, -1); $num = ord($char); if ($num == 62) { return $source; } $source = substr($source, 0, -$num); return $source;}openssl_簇转换实例以 AES-128 为例// 固定使用此算法 然后通过 key 的长度来决定具体使用的是何种 AES$cipher = MCRYPT_RIJNDAEL_128;$mode = MCRYPT_MODE_CBC;// openssl_簇 iv 固定为 16 位,mcrypt_簇 MCRYPT_RIJNDAEL_128 是 16位// 但改为 MCRYPT_RIJNDAEL_192/256 就是 24/32 位了,会不兼容 openssl_簇// 所以务必注意向量长度统一固定 16 位方便两套算法对齐// $iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher, $mode), MCRYPT_RAND);// 根据需要自行定义相应的 key 长度 aes-128=16 aes-192=24 aes-256=32$key = ‘0123456789012345’;// 固定为 16 位$iv = ‘0123456789012345’;$content = “hello world”;// mcrypt 加解密$mcrypt_data = encrypt($content, $key, $iv, $cipher, $mode);var_dump($mcrypt_data);$content = decrypt($mcrypt_data, $key, $iv, $cipher, $mode);var_dump($content);// mcrypt 时使用了 PKCS7 填充 并对结果 base64encode// 如果 +PKCS7 +base64encode 则 option = 0// 如果 +PKCS7 -base64encode 则 option = 1// 如果 -PKCS7 +base64encode 则 option = 2$openssl_data = openssl_encrypt($content, “AES-128-CBC”, $key, 0, $iv)var_dump($openssl_data);$content = openssl_decrypt($openssl_data, “AES-128-CBC”, $key, 0, $iv)var_dump($content);// 相互转换$content = openssl_decrypt($mcrypt_data, “AES-128-CBC”, $key, 0, $iv)var_dump($content);$content = decrypt($openssl_data, $key, $iv, $cipher, $mode);var_dump($content);总结1、PKCS7 填充算法。2、openssl_encrypt / openssl_decrypt 三种模式所表示的 PKCS7/base64encode。3、mcrypt_簇 的 cipher/mode 同 openssl_簇 的转换。 ...

January 29, 2019 · 4 min · jiezi