前言


基于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. minicube安装

    minicube安装 一.安装手册: https://minikube.sigs.k8s.io/docs/start/ 二.安装 打开官网,选择和自己对应的系统和要下载的版本.点击下面的release ...

  2. TeamViewer 9 和 10 即将停用 尝试切换到 Splashtop

    TeamViewer 9 和 TeamViewer 10 将于2021 年 6 月 1 日到期停用.当这两个版本的 TeamViewer 到期时,用户将无法再远程访问其计算机和设备. 这意味着要继续使 ...

  3. TCP协议分析工具TcpEngine V1.2.0使用教程

    概述 目前主流的网络数据分析工具主要有两类,一类是http协议分析工具,如fiddler,这类工具擅长对字符串类型协议分析:另一类是原始网络数据包的监听分析,如Wireshark,这类工具擅长分析网络 ...

  4. 用 C 语言开发一门编程语言 — 异常处理

    目录 文章目录 目录 前文列表 异常捕获 定义 Lisp Value 函数 前文列表 <用 C 语言开发一门编程语言 - 交互式解析器l> <用 C 语言开发一门编程语言 - 跨平台 ...

  5. Vue cli之创建组件

    一般在开发中,我们会人为把组件分2个目录存放,一个代表的页面组件,另一个代表页面一部分的子组件. src/ |- views/ |- Home.vue |- components/ |- App.vu ...

  6. 机器学习策略篇:详解超过人的表现(Surpassing human- level performance)

    超过人的表现 讨论过机器学习进展,会在接近或者超越人类水平的时候变得越来越慢.举例谈谈为什么会这样. 假设有一个问题,一组人类专家充分讨论辩论之后,达到0.5%的错误率,单个人类专家错误率是1%,然后 ...

  7. Python依据遥感影像的分幅筛选出对应的栅格文件

      本文介绍基于Python语言,结合已知研究区域中所覆盖的全部遥感影像的分幅条带号,从大量的遥感影像文件中筛选落在这一研究区域中的遥感影像文件的方法.   首先,先来明确一下本文所需实现的需求.现已 ...

  8. uniapp 判断当前是保存还是修改操作

    步骤分析: 首先得确定你进入表单后传入了id或者整个对象[这里使用id来进行讲解]其次就是两个请求:POST(保存的) 和 PUT(修改的)最后就是通过传入的id是否存在进行判断即可  POST 请求 ...

  9. Linux网络驱动

    1 简介 1.1 硬件说明 嵌入式网络硬件分为:MAC和PHY.MAC一般时SOC内置,PHY是外部器件. (1)SOC内部没有MAC 如果SOC内部没有网络MAC外设,可使用外置的MAC,一般外置的 ...

  10. .NET C# 程序自动更新组件

    引言 本来博主想偷懒使用AutoUpdater.NET组件,但由于博主项目有些特殊性和它的功能过于多,于是博主自己实现一个轻量级独立自动更新组件,可稍作修改集成到大家自己项目中,比如:WPF/Winf ...