前言


基于python3 flet库实现了证书信息的提取,留作自用,如有错误欢迎指正。

正文


程序架构:

主程序 main.py

证书解析程序 certHandle.py

运行 python main.py

main.py

# -*- coding:utf-8 -*-
import base64
import traceback
import json
import flet as ft
from certHandle import get_info_from_cert_pem def main(page: ft.Page):
page.title = "证书查看工具"
page.scroll = "auto" def btn_submit_clicked(e):
if not txt_cert_in.value:
txt_cert_in.error_text = "请粘贴证书字符串"
page.update()
return
else:
cert_in = txt_cert_in.value if not dropdown_timezone.value:
dlg = ft.AlertDialog(
title=ft.Text("Error"),
content=ft.Text("请选择时区")
)
page.dialog = dlg
dlg.open = True
page.update()
return timezone = dropdown_timezone.value
use_local_time = False
if timezone == "local":
use_local_time = True err_msg = None
cert_out = None
try:
cert_out = get_info_from_cert_pem(cert_in, use_local_time)
cert_out = json.loads(cert_out)
cert_out = json.dumps(cert_out, indent=4)
except Exception as e:
err_msg = traceback.format_exc() if cert_out is None or err_msg is not None:
txt_cert_out.error_text = "证书解析失败"
txt_cert_out.value = ""
page.update()
else:
txt_cert_out.value = cert_out
page.update() def btn_clean_clicked(e):
txt_cert_in.value = ""
txt_cert_out.value = ""
page.update() # 证书输入
txt_cert_in = ft.TextField(
label="请粘贴证书字符串"
) # 时间下拉框提示
txt_timezone = ft.Text("请选择时区")
# 时间下拉框
dropdown_timezone = ft.Dropdown(
width=130,
options=[
ft.dropdown.Option(key="org", text="原始时区"),
ft.dropdown.Option(key="local", text="本地时区"),
]
) # 确认按钮
btn_submit = ft.ElevatedButton(text="确认", on_click=btn_submit_clicked) # 清空按钮
btn_clean = ft.ElevatedButton(text="清空", on_click=btn_clean_clicked) # 证书输出
txt_cert_out = ft.TextField(
label="证书解析结果",
multiline=True,
height=400,
text_align=ft.TextAlign.LEFT
)
# txt_cert_out = ft.Text(selectable=True, text_align=ft.TextAlign.LEFT)
# txt_cert_out = ft.Markdown(
# selectable=True,
# extension_set=ft.MarkdownExtensionSet.GITHUB_WEB,
# on_tap_link=lambda e:page.launch_url(e.data)
# ) page.add(
# 输入证书内容
txt_cert_in,
# 时区选择
ft.Row(
[
txt_timezone,
dropdown_timezone
]
),
ft.Divider(),
# 解析结果
txt_cert_out,
# 按钮行
ft.Row(
[
btn_submit,
btn_clean
]
)
) if __name__ == "__main__":
ft.app(target=main)
# ft.app(target=main, view=ft.AppView.WEB_BROWSER)

certHandle.py

import base64
import hashlib
import traceback from OpenSSL.crypto import load_certificate, FILETYPE_PEM, dump_publickey, FILETYPE_ASN1
from cryptography import x509
from cryptography.hazmat.backends import default_backend from base64 import b64encode
from datetime import datetime
import pytz
import json from cryptography.hazmat.primitives import hashes def get_info_from_cert_pem(cert_str: str, use_local_time:bool = False) -> str | None:
"""
从证书获取详细信息
"""
cert_str = reformat_cert(cert_str)
info_dict = {}
try:
cert = load_certificate(FILETYPE_PEM, cert_str)
# 备用解析 - 另一种解析方式
cert_standby = x509.load_pem_x509_certificate(cert_str.encode(), default_backend()) # 签发者信息
issuer = cert.get_issuer()
issuer_info = analy_components(issuer.get_components())
issuer_hash = hex(issuer.hash()).replace("0x", "")
info_dict["issuer"] = {}
info_dict["issuer"]["info"] = issuer_info
info_dict["issuer"]["hash"] = issuer_hash # 主体信息
subject = cert.get_subject()
subject_info = analy_components(subject.get_components())
subject_hash = hex(subject.hash()).replace("0x", "") info_dict["subject"] = {}
info_dict["subject"]["info"] = subject_info
info_dict["subject"]["hash"] = subject_hash # 证书串号
serial_num = hex(cert.get_serial_number()).replace("0x", "")
info_dict["serial_num"] = serial_num # 有效期
valid_before = format_time(cert.get_notBefore(), to_local=use_local_time)
valid_after = format_time(cert.get_notAfter(), to_local=use_local_time)
info_dict["valid_before"] = valid_before
info_dict["valid_after"] = valid_after # 版本信息 -- 好像不准
# version = cert.get_version()
version = cert_standby.version info_dict["cert_version"] = version.name # 签名算法
algorithm = cert.get_signature_algorithm().decode() info_dict["cert_algorithm"] = algorithm # 证书指纹
cert_thumbprint_sha1 = cert.digest("SHA1").decode()
cert_thumbprint_sha256 = cert.digest("SHA256").decode()
cert_thumbprint_md5 = cert.digest("MD5").decode() info_dict["cert_thumbprint"] = {}
info_dict["cert_thumbprint"]["sha1"] = cert_thumbprint_sha1
info_dict["cert_thumbprint"]["sha256"] = cert_thumbprint_sha256
info_dict["cert_thumbprint"]["md5"] = cert_thumbprint_md5 # 证书主体指纹
cert_tbs_thumbprint_sha1 = hashlib.sha1(cert_standby.tbs_certificate_bytes).digest().hex()
cert_tbs_thumbprint_sha1_b64 = base64.b64encode(hashlib.sha1(cert_standby.tbs_certificate_bytes).digest()).decode() info_dict["cert_tbs_thumbprint"] = {}
info_dict["cert_tbs_thumbprint"]["sha1"] = cert_tbs_thumbprint_sha1
info_dict["cert_tbs_thumbprint"]["sha1_b64"] = cert_tbs_thumbprint_sha1_b64 # 公钥指纹
public_key = cert.get_pubkey()
public_key_pem = dump_publickey(FILETYPE_ASN1, public_key)
public_key_thumbprint_sha1 = hashlib.sha1(public_key_pem).digest().hex()
public_key_thumbprint_sha256 = hashlib.sha256(public_key_pem).digest().hex()
public_key_thumbprint_sha1_b64 = base64.b64encode(hashlib.sha1(public_key_pem).digest()).decode() info_dict["public_key_thumbprint"] = {}
info_dict["public_key_thumbprint"]["sha1"] = public_key_thumbprint_sha1
info_dict["public_key_thumbprint"]["sha256"] = public_key_thumbprint_sha256
info_dict["public_key_thumbprint"]["sha1_b64"] = public_key_thumbprint_sha1_b64 # 扩展信息 info_dict["extensions"] = {} extensions_cnt = cert.get_extension_count()
for i in range(extensions_cnt):
name = cert.get_extension(i).get_short_name().decode()
value = cert.get_extension(i) if name == "subjectKeyIdentifier":
thumbprint = cert_standby.extensions.get_extension_for_oid(x509.oid.ExtensionOID.SUBJECT_KEY_IDENTIFIER).value.digest
info_dict["extensions"][name] = {}
info_dict["extensions"][name]["value"] = "{0}".format(value)
info_dict["extensions"][name]["b64"] = base64.b64encode(thumbprint).decode()
else:
info_dict["extensions"][name] = "{0}".format(value) except Exception as e:
return traceback.format_exc()
info_str = json.dumps(info_dict)
return info_str def analy_components(components: list | None) -> str | None:
"""
解析 list[tuple(b'',b'')] 类型
:return:
"""
res = ""
try:
tmp_list = []
for i in components:
(k, v) = i
tmp_list.append("{0}={1}".format(k.decode(), v.decode()))
res = ",".join(tmp_list)
except Exception as e:
traceback.print_exc()
return res def format_time(time_org: bytes, to_local:bool = False)->str:
"""
将证书中得到的时间格式化
:param time_org: 原始时间字节串
:param to_local: 是否转换为本地时间
:return:
"""
time_str = time_org.decode("utf-8")
try: datetime_obj = datetime.strptime(time_str, "%Y%m%d%H%M%SZ")
# 上海时区
local_tz = pytz.timezone('Asia/Shanghai')
datetime_local = pytz.utc.localize(datetime_obj).astimezone(local_tz)
if to_local:
time_str = datetime_local.strftime("%Y-%m-%d %H:%M:%S")
else:
time_str = datetime_obj.strftime("%Y-%m-%d %H:%M:%S")
except Exception as e:
traceback.print_exc()
return time_str def reformat_cert(cert_in:str)->str|None:
"""
重新格式化证书
:param cert_in:证书字符串
:return:
"""
cert_out = None
cert_header = "-----BEGIN CERTIFICATE-----"
cert_tail = "-----END CERTIFICATE-----"
if cert_in:
if "\r" in cert_in:
cert_in = cert_in.replace("\r","")
if "\\n" in cert_in:
cert_in = cert_in.replace("\\n", "")
if "\n" in cert_in:
cert_in = cert_in.replace("\n", "")
cert_in = cert_in.replace(cert_header, "")
cert_in = cert_in.replace(cert_tail, "")
cert_body = base64.b64encode(base64.b64decode(cert_in.encode())).decode()
cert_out = "{0}\n{1}\n{2}".format(cert_header, cert_body, cert_tail)
return cert_out

基于python3 flet库的证书查看工具的更多相关文章

  1. 基于Python3的漏洞检测工具 ( Python3 插件式框架 )

    目录 Python3 漏洞检测工具 -- lance screenshot requirements 关键代码 usage documents Any advice or sugggestions P ...

  2. 7.Python3标准库--文件系统

    ''' Python的标准库中包含大量工具,可以处理文件系统中的文件,构造和解析文件名,还可以检查文件内容. 处理文件的第一步是要确定处理的文件的名字.Python将文件名表示为简单的字符串,另外还提 ...

  3. SSL证书在线工具

    证书在线工具 如果您是第一次申请SSL证书,如果您对您的服务器如何使用SSL证书还不熟悉的话,我们推荐您使用本套工具,本套工具支持所有SSL服务器证书格式和各种WEB服务器.帮助您在线生成CSR文件, ...

  4. lucene 索引查看工具

    luke 是 lucene 索引查看工具,基于 swing 开发的,是 lucene.solr.nutch 开发过程中不可或缺的工具.在测试搜索过程,进程出现搜不到东西或者搜到的东西不是想要的结果时, ...

  5. Python3 实现简易局域网视频聊天工具

    Python3 实现简易局域网视频聊天工具   1.环境 操作系统为 Ubuntu 16.04 python 3.5opencv-python 3.4.1.15numpy 1.14.5PyAudio ...

  6. 8.Python3标准库--数据持久存储与交换

    ''' 持久存储数据以便长期使用包括两个方面:在对象的内存中表示和存储格式之间来回转换数据,以及处理转换后数据的存储区. 标准库包含很多模块可以处理不同情况下的这两个方面 有两个模块可以将对象转换为一 ...

  7. Python3 标准库

    Python3标准库 更详尽:http://blog.csdn.net/jurbo/article/details/52334345 文本 string:通用字符串操作 re:正则表达式操作 diff ...

  8. Python 简易web日志查看工具&可改装为命令行工具

    Python 简易web日志查看工具&可改装为命令行工具 效果图 原理 利用python的paramiko库模拟ssh登录操作,并执行tail命令 所需库 flask.paramiko.gev ...

  9. 登峰造极,师出造化,Pytorch人工智能AI图像增强框架ControlNet绘画实践,基于Python3.10

    人工智能太疯狂,传统劳动力和内容创作平台被AI枪毙,弃尸尘埃.并非空穴来风,也不是危言耸听,人工智能AI图像增强框架ControlNet正在疯狂地改写绘画艺术的发展进程,你问我绘画行业未来的样子?我只 ...

  10. TinyWeb v1.0 正式完成第一个Release版本(功能基于 libuv 跨平台库)

    使用方法很简单,很容易融入现有项目,使现有项目拥有Web网站功能和WebSocket,以及Socket直连! 并且包含了一个跨平台(windows/linux)工具集合; 嗯,也挺棒的^,^ 在项目中 ...

随机推荐

  1. Gin框架

    目录 gin的参数获取 header参数 post Raw json 请求示例 gin的参数获取 package main import ( "fmt" "github. ...

  2. C语言:如何实现在txt文件中删除超链接、统计单词数量、生成单词列表 (文本流操作并解决乱码)

    1.首先读取原文件内容文本流(包含中英文) 2.删除超链接 3.统计单词数量 4.去除重复单词 读取文件需要自己在文本笔记中保存一个网页,保存为txt文件 注意的是,在这个代码实现过程中,我学到的是如 ...

  3. 【漏洞通报】WEB VIDEO PLATFORM疑似存在未授权访问漏洞

    漏洞描述 WEB VIDEO PLATFORM是一个基于GB28181-2016标准实现的开箱即用的网络视频平台,负责实现核心信令与设备管理后台部分,支持NAT穿透,支持海康.大华.宇视等品牌的IPC ...

  4. .NET集成DeveloperSharp实现http网络请求&与其它工具的比较

    爆了,爆了,DeveloperSharp系列近期又被制造业ERP.民航飞行App.建筑BIM.电力掌上营业厅.等多家大型采用,站在巨人的肩膀上你能走的更远. 支持.Net Core2.0及以上,支持. ...

  5. AI实战 | 手把手带你打造校园生活助手

    大家好,我是努力的小雨.最近,我开始将我的经验逐渐分享到B站,希望能够帮助大家通过扣子助手真正解决一些问题.最近有粉丝提出了一个需求,为了满足大家的期待,我已经制作了视频,详细介绍了这个助手的搭建思路 ...

  6. VMware Workstation解锁Mac系统

    VMware workstation在安装虚拟机的时候,如果是安装Windows.CentOS.Ubuntu等相关系统的话,仅仅需要一个系统镜像就可以顺利安装了. 但是如果想要安装苹果系统Mac的话, ...

  7. Windows中实现将bat或exe文件作为服务_且实现命令行安装、配置、启动、删除服务

    一.背景描述 在Windows环境下进行日常的项目开发过程中,有时候需要将bat文件或exe文件程序注册为Windows的服务实现开机自己运行(没有用户登陆,服务在开机后也可以照常运行).且对于那些没 ...

  8. kubernetes自动扩缩容[HPA控制器 horizontal pod autoscaler]

    kubernetes自动扩缩容[HPA控制器 horizontal pod autoscaler] #查看当前hpa控制器版本: [root@k8s-master01 ~]# kubectl get ...

  9. Python实现求多个集合之间的并集-方法2

    之前使用过一种方法实现求集合间的并集,参考文章:https://www.cnblogs.com/mrlayfolk/p/12373532.html,这次使用另外一种方法实现,这种方法效率更高. 目的: ...

  10. Unity3D 内存管理非代码技巧

    在场景管理器新建 gameobjct 使用代码在类初始化时 NEW 普肉fai包(包)然后将相同的类NEW够挂载到 gameobjct子节点上 在操控列表中类的时候用for循环遍历操作移动还是怎么样( ...