我们使用Python / Tkinter拆卸和查看合格证书

合格的证书很快成为日常生活中不可或缺的一部分。 越来越多的人希望从内部看到这种“野兽”。 这是一方面。 另一方面,正在开发越来越多的应用程序,其中使用了来自这些证书的信息。 这些不仅是证书所有者或发布者的TIN或BIN属性。 这可以是有关证书持有人使用哪个加密提供程序(subjectSignTool属性)来生成私钥的信息,也可以是关于基于哪种认证手段而创建的颁发证书的认证中心(CA)的信息。 并且,如果您编写了一个用于分析已颁发证书的程序,则可以收集有关证书持有人使用哪些加密信息保护工具的有趣统计信息,并可以根据部署了哪些(尽管不那么有趣)认证(或非认证)基金CA(issuerSignTools属性):



在Habr的开放空间上,已经成功地尝试对合格证书进行分类。 不幸的是,该分析仅涉及作为专有名称DN一部分的TIN,PSRN和SNILS属性的接收。 虽然,为什么不幸呢? 作者有一个特定的问题,已经解决。 我们希望通过Python访问合格证书的属性,并提供用于查看它们的图形实用程序。

要访问证书的属性,我们将使用fsb795软件包。 该软件包可用于Linux和Windows的Pytho2和Python3。 要安装它,只需运行传统命令:

# python -m pip install fsb795 Collecting fsb795 Requirement already satisfied: pyasn1-modules>=0.2.2 in /usr/lib/python2.7/site-packages (from fsb795) (0.2.2) Collecting pyasn1>=0.4.4 (from fsb795) Using cached https://files.pythonhosted.org/packages/d1/a1/7790cc85db38daa874f6a2e6308131b9953feb1367f2ae2d1123bb93a9f5/pyasn1-0.4.4-py2.py3-none-any.whl Requirement already satisfied: six in /usr/lib/python2.7/site-packages (from fsb795) (1.11.0) Installing collected packages: pyasn1, fsb795 Successfully installed fsb795-1.5.2 pyasn1-0.4.4 [root@localhost GCryptGOST]# 

fsb795软件包需要pyasn1和pyasn1-modules软件包。 因此,如果未安装它们,将尝试安装它们。

对于python3,此命令如下所示:

 # python -m pip install fsb795 ... # 

您还可以下载python3python2安装软件包并在本地安装它们。
软件包名称类似于pyasn1-modules软件包中的模块,例如rfc2459等,表示该软件包旨在与满足2011年12月27日俄罗斯联邦联邦安全局命令795号要求的证书一起使用。合格证书形式的要求...”。

通过Certificate类可访问fsb795软件包中的证书:

 # -*- coding: utf-8 -*- import os, sys import pyasn1 import binascii import six from pyasn1_modules import rfc2459, pem from pyasn1.codec.der import decoder from datetime import datetime, timedelta class Certificate: #  cert_full = '' cert = '' pyver = '' formatCert = '' def __init__ (self,fileorstr): #     if not os.path.exists(fileorstr): #  ,  ,     #    PEM- strcert = fileorstr.strip('\n') if (strcert[0:27] != '-----BEGIN CERTIFICATE-----'): return idx, substrate = pem.readPemBlocksFromFile(six.StringIO( strcert), ('-----BEGIN CERTIFICATE-----', '-----END CERTIFICATE-----') ) self.pyver = sys.version[0] try: self.cert_full, rest = decoder.decode(substrate, asn1Spec=rfc2459.Certificate()) self.cert = self.cert_full["tbsCertificate"] self.formatCert = 'PEM' except: self.pyver = '' self.formatCert = '' return #   #  self.pyver   python self.pyver = sys.version[0] filename = fileorstr if (self.pyver == '2'): if sys.platform != "win32": filename = filename.encode("UTF-8") else: filename = filename.encode("CP1251") #  DER file1 = open(filename, "rb") substrate = file1.read() if (self.pyver == '2'): b0 = ord(substrate[0]) b1 = ord(substrate[1]) else: b0 = substrate[0] b1 = substrate[1] #  PEM/DER,   0x30,       127  if (b0 == 48 and b1 > 128) : self.formatCert = 'DER' else: self.formatCert = 'PEM' file1 = open(filename, "r") idx, substrate = pem.readPemBlocksFromFile( file1, ('-----BEGIN CERTIFICATE-----', '-----END CERTIFICATE-----') ) file1.close() try: self.cert_full, rest = decoder.decode(substrate, asn1Spec=rfc2459.Certificate()) self.cert = self.cert_full["tbsCertificate"] except: self.pyver = '' self.formatCert = '' #       def subjectSignTool(self): . . . #,     if __name__ == "__main__": . . . 

要为特定证书创建对象的实例,只需执行以下语句即可:

 $ python Python 2.7.15 (default, May 23 2018, 14:20:56) [GCC 5.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>import fsb795 >>tek_cert = fsb795.Certificate(</  >) >> 

作为参数,在创建类的实例时,将指定证书,证书可以在PEM或DER文件中,也可以是PEM格式的字符串。

创建后,每个实例具有四个属性:pyver,formatCert,cert_full和cert。
使用pyver属性,您可以检查证书的解析过程。 如果pyver等于空字符串,则文件或字符串不包含证书。 否则,pyver属性包含python语言版本:

 >>> c1=fsb795.Certificate('     ') >>> if (c1.pyver == ''): ... print ('   ') ...     >>> c2 = fsb795.Certificate('/home/a513/cert_nss.der') >>> if (c2.pyver != ""): ... print(c2.pyver) ... 2 >>> print(c2.formatCert) DER >>> 

成功创建Certificate类的实例时,formatCert属性包含证书的文件/字符串格式类型。 它可以是PEM或DER。 为什么需要此属性的原因将在下面阐明。

fsb795软件包是使用pyasn1软件包创建的。 因此,两个属性仍待检查。 cert属性存储可与pyasn1软件包一起使用的tbs证书。 另一个cert_full属性存储有关rfc2459的整个解码证书。 我们展示了如何使用cert属性和连接的pyasn1包获取公钥算法:

 >>> pubkey = c2.cert['subjectPublicKeyInfo'] >>> ff = pubkey['algorithm'] >>> ff1 = ff['algorithm'] >>> print (ff1) 1.2.643.2.2.19 >>> 

最后,可以评估fsb795软件包的功能,以获取有关合格证书的公钥的信息。

成功创建Certificate类的实例后,我们可以使用一些方法,使从证书中轻松获取必要的数据变得容易。 可以通过以下方式获取有关公钥的所有信息:

 >>> c3 = fsb795.Certificate('cert.der') >>> key_info=c3.publicKey() >>> for opt in key_info.keys(): ... val = str(key_info[opt]) ... print (opt + '=' + val) ... curve=1.2.643.2.2.36.0 hash=1.2.643.2.2.30.1 valuepk=5b785f86f0dd5316ba37c8440e398e83f2ec0c34478f90da9c0c8046d341ff66f9044cd00a0e25530 acefd51e6be852dbecacbaabc55e807be8e1f861658bd58 algo=1.2.643.2.2.19 >>> 

当前,证书类包含以下方法:

  • subjectSignTool()-返回带有密码信息保护证书持有者名称的字符串;
  • issuerSignTool()-返回四个元素的列表,其中包含证书颁发者的信息加密工具;
  • classUser()-返回一个字符串,其中包含证书持有者的密码信息保护证书的安全类的oid,以字符“ ;;”分隔;
  • issuerCert()-返回一个字典,其中包含证书颁发者的区别名DN的字段和值以及标识证书的数字(2-法人实体);
  • subjectCert()-返回字典,其中包含证书持有者的专有名称DN的字段和值以及标识证书的数字(2-法人实体);
  • publicKey()-返回一个包含键值('valuepk')和键参数('curve'和'hash')的字典;
  • signatureCert-返回两个值:签名算法和签名值;
  • validityCert-返回带有两个键“ not_after”和“ not_before”的字典;
  • keyUsage()-返回键范围的列表;
  • serialNumber()-以十进制形式返回证书的序列号;
  • prettyPrint()-根据pyasn1(self.cert_full.prettyPrint())返回带有证书“打印输出”的字符串。

扰流板包含一个测试示例,清楚地演示了这些方法的工作。

测试test795.py以测试fsb795软件包
 import fsb795 certpem = """ -----BEGIN CERTIFICATE----- MIIG3DCCBougAwIBAgIKE8/KkAAAAAAC4zAIBgYqhQMCAgMwggFKMR4wHAYJKoZI hvcNAQkBFg9kaXRAbWluc3Z5YXoucnUxCzAJBgNVBAYTAlJVMRwwGgYDVQQIDBM3 NyDQsy4g0JzQvtGB0LrQstCwMRUwEwYDVQQHDAzQnNC+0YHQutCy0LAxPzA9BgNV BAkMNjEyNTM3NSDQsy4g0JzQvtGB0LrQstCwLCDRg9C7LiDQotCy0LXRgNGB0LrQ sNGPLCDQtC4gNzEsMCoGA1UECgwj0JzQuNC90LrQvtC80YHQstGP0LfRjCDQoNC+ 0YHRgdC40LgxGDAWBgUqhQNkARINMTA0NzcwMjAyNjcwMTEaMBgGCCqFAwOBAwEB EgwwMDc3MTA0NzQzNzUxQTA/BgNVBAMMONCT0L7Qu9C+0LLQvdC+0Lkg0YPQtNC+ 0YHRgtC+0LLQtdGA0Y/RjtGJ0LjQuSDRhtC10L3RgtGAMB4XDTE4MDcwOTE1MjYy NFoXDTI3MDcwOTE1MjYyNFowggFVMR4wHAYJKoZIhvcNAQkBFg9jb250YWN0QGVr ZXkucnUxITAfBgNVBAMMGNCe0J7QniDCq9CV0LrQtdC5INCj0KbCuzEwMC4GA1UE Cwwn0KPQtNC+0YHRgtC+0LLQtdGA0Y/RjtGJ0LjQuSDRhtC10L3RgtGAMSEwHwYD VQQKDBjQntCe0J4gwqvQldC60LXQuSDQo9CmwrsxCzAJBgNVBAYTAlJVMRgwFgYD VQQIDA83NyDQnNC+0YHQutCy0LAxRDBCBgNVBAkMO9Cj0JvQmNCm0JAg0JjQm9Cs 0JjQndCa0JAsINCULjQsINCQ0J3QotCgIDMg0K3Qojsg0J/QntCcLjk0MRgwFgYD VQQHDA/Qsy7QnNC+0YHQutCy0LAxGDAWBgUqhQNkARINMTE0Nzc0NjcxNDYzMTEa MBgGCCqFAwOBAwEBEgwwMDc3MTA5NjQzNDgwYzAcBgYqhQMCAhMwEgYHKoUDAgIk AAYHKoUDAgIeAQNDAARAW3hfhvDdUxa6N8hEDjmOg/LsDDRHj5DanAyARtNB/2b5 BEzQCg4lUwrO/VHmvoUtvsrLqrxV6Ae+jh+GFli9WKOCA0AwggM8MBIGA1UdEwEB /wQIMAYBAf8CAQAwHQYDVR0OBBYEFMQYnG5GfYRnj2ehEQ5tv8Fso/qBMAsGA1Ud DwQEAwIBRjAdBgNVHSAEFjAUMAgGBiqFA2RxATAIBgYqhQNkcQIwKAYFKoUDZG8E Hwwd0KHQmtCX0JggwqvQm9CY0KDQodCh0JstQ1NQwrswggGLBgNVHSMEggGCMIIB foAUi5g7iRhR6O+cAni46sjUILJVyV2hggFSpIIBTjCCAUoxHjAcBgkqhkiG9w0B CQEWD2RpdEBtaW5zdnlhei5ydTELMAkGA1UEBhMCUlUxHDAaBgNVBAgMEzc3INCz LiDQnNC+0YHQutCy0LAxFTATBgNVBAcMDNCc0L7RgdC60LLQsDE/MD0GA1UECQw2 MTI1Mzc1INCzLiDQnNC+0YHQutCy0LAsINGD0LsuINCi0LLQtdGA0YHQutCw0Y8s INC0LiA3MSwwKgYDVQQKDCPQnNC40L3QutC+0LzRgdCy0Y/Qt9GMINCg0L7RgdGB 0LjQuDEYMBYGBSqFA2QBEg0xMDQ3NzAyMDI2NzAxMRowGAYIKoUDA4EDAQESDDAw NzcxMDQ3NDM3NTFBMD8GA1UEAww40JPQvtC70L7QstC90L7QuSDRg9C00L7RgdGC 0L7QstC10YDRj9GO0YnQuNC5INGG0LXQvdGC0YCCEDRoHkDLQe8zqaC3yHaSmikw WQYDVR0fBFIwUDAmoCSgIoYgaHR0cDovL3Jvc3RlbGVjb20ucnUvY2RwL2d1Yy5j cmwwJqAkoCKGIGh0dHA6Ly9yZWVzdHItcGtpLnJ1L2NkcC9ndWMuY3JsMIHGBgUq hQNkcASBvDCBuQwj0J/QkNCa0JwgwqvQmtGA0LjQv9GC0L7Qn9GA0L4gSFNNwrsM INCf0JDQmiDCq9CT0L7Qu9C+0LLQvdC+0Lkg0KPQpsK7DDbQl9Cw0LrQu9GO0YfQ tdC90LjQtSDihJYgMTQ5LzMvMi8yLTk5OSDQvtGCIDA1LjA3LjIwMTIMONCX0LDQ utC70Y7Rh9C10L3QuNC1IOKEliAxNDkvNy8xLzQvMi02MDMg0L7RgiAwNi4wNy4y MDEyMAgGBiqFAwICAwNBALvjFGhdFE9llvlvKeQmZmkI5J+yO2jFWTh8nXPjIpiL OutUew2hIZv15pJ1QM/VgRO3BTBGDOoIrq8LvgC+3kA= -----END CERTIFICATE----- """ #c1 = fsb795.Certificate('OOO_VOLGA.der') #c1 = fsb795.Certificate('cert.der') c1 = fsb795.Certificate(certpem) if (c1.pyver == ''): print('Context for certificate not create') exit(-1) print('=================formatCert================================') print(c1.formatCert) res = c1.subjectSignTool() print('=================subjectSignTool================================') print (res) print('=================issuerSignTool================================') res1 = c1.issuerSignTool() print (res1[0]) print (res1[1]) print (res1[2]) print (res1[3]) print('=================prettyPrint================================') res2 = c1.prettyPrint() #print(res2) print('=================classUser================================') res3 = c1.classUser() print (res3) print('=================issuerCert================================') iss, vlad_is = c1.issuerCert() print ('vlad_is=' + str(vlad_is)) for key in iss.keys(): print (key + '=' + iss[key]) print('=================subjectCert================================') sub, vlad_sub = c1.subjectCert() print ('vlad_sub=' + str(vlad_sub)) for key in sub.keys(): print (key + '=' + sub[key]) print('================publicKey=================================') key_info = c1.publicKey() print(key_info['curve']) print(key_info['hash']) print(key_info['valuepk']) print('================serialNumber=================================') print(c1.serialNumber()) print('================validityCert=================================') valid = c1.validityCert() print(valid['not_after']) print(valid['not_before']) print('================signatureCert=================================') algosign, value = c1.signatureCert() print(algosign) print(value) print('================KeyUsage=================================') ku = c1.KeyUsage() for key in ku: print (key) # print(ku) print('================END=================================') 


要运行测试示例,只需运行以下命令:

 $python test795.py 

使用fsb795软件包时,很自然地用python编写了一个独立的,平台无关的图形实用程序,用于查看合格的证书。 Tkinter软件包用作图形支持:



viewCertFL63实用程序具有三个选项卡。 关于证书选项卡,除其他外,显示当前时间。 我们将在下面返回它。 要选择证书,只需单击“选择”按钮:



注意按钮(在Windows上工作的人不会看到此按钮),它使您可以隐藏所谓的不可见文件/目录(隐藏)。 为了显示此按钮,只需执行以下命令:

 if sys.platform != "win32": root.tk.call('set', '::tk::dialog::file::showHiddenBtn', '1') root.tk.call('set', '::tk::dialog::file::showHiddenVar', '0') 

一个非常有用的按钮。 因此,选择证书后,“关于证书”标签将采用以下形式:



此处值得注意的是,如果证书在查看证书时过期,则左上角图标上的打印将分为两半。 每个人都可以相信这一点,可以提前一年在计算机上重新安排时钟。
在“详细信息”选项卡上,您可以详细查看合格证书的所选属性的特征:



最后,第三个选项卡是“文本”。 此选项卡显示整个证书的内容:



要查看证书,不仅可以使用Python(“ Python”按钮),还可以使用网络安全服务(NSS)的openssl和pp实用程序。 如果某人没有这些实用程序,则可以通过收集支持俄罗斯密码的openssl来获得第一个实用程序。 使用pp实用程序时,证书输出如下所示:



上面我们提到了fsb795软件包的Certificate类的formatCert属性。 因此,当运行该实用程序时,我们需要此属性的值来指示带有证书的文件格式。 例如,使用PEM文件格式调用pp实用程序如下所示:

 $pp –tc –u –a –i < > 

-a选项指示PEM文件的格式。 对于DER格式,未指定。
openssl的“ –inform”参数的设置方法相同。
Utility按钮用于指示openssl或pp实用程序的路径。
ViewCertFL63实用程序发行版位于此处
使用pyinstaller软件包构建发行版:

 $python pyinstaller.py --noconsole -F viewCertFL63.py 

Source: https://habr.com/ru/post/zh-CN421107/


All Articles