<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      20221320馮泰瑞-實(shí)驗(yàn)四密碼模塊應(yīng)用實(shí)踐過程記錄

      20221320馮泰瑞-實(shí)驗(yàn)四密碼模塊應(yīng)用實(shí)踐過程記錄

      實(shí)踐要求

      1. 完成電子公文交換系統(tǒng),系統(tǒng)功能,(15 分)
      mindmap root((電子公文系統(tǒng))) 發(fā)文 公文起草 公文查看 發(fā)文審核(審核員) 公文發(fā)送 公文查詢 收文 公文簽收 公文查看 公文處理 公文查詢 系統(tǒng)管理 組織單位 用戶管理 操作員(科員) 審核員(科長(zhǎng),處長(zhǎng)):至少有一級(jí)審核功能 系統(tǒng)管理員:至少管理用戶賬號(hào),組織單位功能 安全保密管理員:至少有權(quán)限管理功能,密鑰管理功能 安全審計(jì)員:至少有日志查看功能 權(quán)限設(shè)置(安全保密管理員) 系統(tǒng)日志 數(shù)據(jù)字典(選做)

      系統(tǒng)功能

      • 總體要求
        • 項(xiàng)目類型必須是B/S或C/S架構(gòu)
        • 項(xiàng)目程序設(shè)計(jì)語(yǔ)言可以是C,Python,Rust等
      1. 三員制度是指將系統(tǒng)管理員、安全保密管理員和安全審計(jì)員三個(gè)角色分離,分別負(fù)責(zé)系統(tǒng)運(yùn)行、安全保密和安全管理,相互制約,共同保障信息系統(tǒng)安全。三員職責(zé)
      • 系統(tǒng)管理員
        • 負(fù)責(zé)信息系統(tǒng)的日常維護(hù)、故障處理和升級(jí)更新。
        • 確保系統(tǒng)正常運(yùn)行,對(duì)系統(tǒng)資源進(jìn)行合理分配。
        • 負(fù)責(zé)用戶賬號(hào)的創(chuàng)建、修改和刪除。
        • 定期備份重要數(shù)據(jù),確保數(shù)據(jù)安全。
      • 安全保密管理員
        • 負(fù)責(zé)制定和實(shí)施安全保密策略,確保信息系統(tǒng)安全。
        • 對(duì)用戶進(jìn)行安全意識(shí)培訓(xùn),提高用戶安全防范能力。
        • 監(jiān)控網(wǎng)絡(luò)安全狀況,發(fā)現(xiàn)異常情況及時(shí)處理。
        • 負(fù)責(zé)信息系統(tǒng)安全事件的應(yīng)急響應(yīng)和處理。
      • 安全審計(jì)員
        • 負(fù)責(zé)對(duì)信息系統(tǒng)進(jìn)行安全審計(jì),評(píng)估安全風(fēng)險(xiǎn)。
        • 監(jiān)督系統(tǒng)管理員和安全保密管理員的工作,確保其履行職責(zé)。
        • 對(duì)信息系統(tǒng)安全事件進(jìn)行調(diào)查,提出整改建議。
      1. 黃金法則(5 分)
        • 身份鑒別:口令不能存,數(shù)據(jù)庫(kù)要保存加鹽的SM3Hash值
        • 訪問控制:操作員,審核員,安全三員的權(quán)限設(shè)置
        • 安全審計(jì):至少完成日志查詢功能
      2. 密碼(15 分)
        • 算法:SM2,SM3,SM4,推薦使用 Key
        • 密鑰管理:所有私鑰,對(duì)稱算法密鑰等不能明存
      3. 系統(tǒng)量化評(píng)估(5分)
      4. 提交要求:
      • 提交實(shí)踐過程Markdown和轉(zhuǎn)化的PDF文件

      • 代碼,文檔托管到gitee或github等,推薦 gitclone

      • 記錄實(shí)驗(yàn)過程中遇到的問題,解決過程,反思等內(nèi)容,用于后面實(shí)驗(yàn)報(bào)告

      開源倉(cāng)庫(kù)

      我使用了前輩之前的倉(cāng)庫(kù),倉(cāng)庫(kù)地址為青青草原七匹狼/電子公文傳輸系統(tǒng),使用git clone命令下載即可。

      環(huán)境配置

      系統(tǒng)部分環(huán)境需要進(jìn)行修改,配置過程如下所示:

      個(gè)人配置

      Windows 11

      Python: 3.13

      參考博客:(超詳細(xì))Python+PyCharm的安裝步驟及PyCharm的使用(含快捷鍵)

      Pycharm: Community Edition 2024.3

      參考博客:(超詳細(xì))Python+PyCharm的安裝步驟及PyCharm的使用(含快捷鍵)

      OpenSSL:3.4.0 22 Oct ~2024

      參考博客:環(huán)境篇-Windows下安裝OpenSSL

      MySQL:9.0

      參考博客:Windows環(huán)境下MySQL安裝與配置(超詳細(xì)、超細(xì)致)

      環(huán)境配置

      在D盤(推薦)使用git clone https://gitee.com/Electronic-document-transfer-system/Document-transmission.git命令獲取源代碼,使用Pycharm打開項(xiàng)目,項(xiàng)目結(jié)構(gòu)如下所示。

      在左上角中,根據(jù)文件->設(shè)置->Project:Document-transmission->Python Interpreter的路徑打開解釋器,點(diǎn)擊加號(hào)以安裝其他包。

      在里面搜索如下包進(jìn)行安裝:DjangoPyPDF2captcha、django-sslserverfiletypegmssl、mysqlclientstandard-imghdrdjango-simple-captcha包。

      接著,需要我們創(chuàng)建名為testdocument的數(shù)據(jù)庫(kù)。

      在命令行中使用如下命令進(jìn)行數(shù)據(jù)表的創(chuàng)建。

      python manage.py makemigrations                                             
      python manage.py migrate                                                    
      

      顯示如下提示代表創(chuàng)建成功。

      (.venv) PS D:\信息安全系統(tǒng)設(shè)計(jì)\Document-transmission-master\Document-transmission-master> python manage.py migrate
      System check identified some issues:
      
      WARNINGS:
      user.MyUser: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
              HINT: Configure the DEFAULT_AUTO_FIELD setting or the UserConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
      Operations to perform:
        Apply all migrations: admin, auth, captcha, contenttypes, index, sessions, user
      Running migrations:
        Applying contenttypes.0001_initial... OK
        Applying contenttypes.0002_remove_content_type_name... OK
        Applying auth.0001_initial... OK
        Applying auth.0002_alter_permission_name_max_length... OK
        Applying auth.0003_alter_user_email_max_length... OK
        Applying auth.0004_alter_user_username_opts... OK
        Applying auth.0005_alter_user_last_login_null... OK
        Applying auth.0006_require_contenttypes_0002... OK
        Applying auth.0007_alter_validators_add_error_messages... OK
        Applying auth.0008_alter_user_username_max_length... OK
        Applying auth.0009_alter_user_last_name_max_length... OK
        Applying auth.0010_alter_group_name_max_length... OK
        Applying auth.0011_update_proxy_permissions... OK
        Applying user.0001_initial... OK
        Applying admin.0001_initial... OK
        Applying admin.0002_logentry_remove_auto_add... OK
        Applying admin.0003_logentry_add_action_flag_choices... OK
        Applying auth.0012_alter_user_first_name_max_length... OK
        Applying captcha.0001_initial... OK
        Applying captcha.0002_alter_captchastore_id... OK
        Applying index.0001_initial... OK
        Applying index.0002_auto_20210601_1010... OK
        Applying index.0003_document_type... OK
        Applying index.0004_document_lyrics... OK
        Applying index.0005_auto_20210602_0952... OK
        Applying index.0006_auto_20210602_0953... OK
        Applying index.0007_document_key... OK
        Applying index.0008_auto_20210605_1920... OK
        Applying sessions.0001_initial... OK
        Applying user.0002_auto_20210605_1743... OK
        Applying user.0003_alter_myuser_first_name... OK
      

      index_document表里面有一個(gè)外鍵,不知道有什么用,但是帶著這個(gè)外鍵又會(huì)報(bào)錯(cuò)。我們?cè)?code>SQL命令行把這個(gè)外鍵刪了,使用如下命令:

      use testdocument;
      alter table index_document drop foreign key index_document_label_id_b5ce761f_fk_index_label_id;
      

      之后的報(bào)錯(cuò)記錄就又少了一條。緊接著,在electronicDocument/settings.py中修改數(shù)據(jù)庫(kù)登錄的密碼,第91行中有如下代碼:

              'PASSWORD': '1619553792',
      

      把這個(gè)1619553792修改成數(shù)據(jù)庫(kù)的密碼123456即可。如果登錄賬戶不是root,在上一行中的'USER': 'root'進(jìn)行類似的修改即可。

      代碼修改

      首先是SSL的問題,如果直接運(yùn)行項(xiàng)目,可能會(huì)報(bào)這樣的錯(cuò):

      AttributeError: module 'ssl' has no attribute 'wrap_socket'

      這是因?yàn)榘陌姹靖铝税?,沒有這個(gè)用法了,把對(duì)應(yīng)文件修改一下就可以。

      打開項(xiàng)目中的runsslserver.py文件,第48行有一個(gè)SecureHTTPServer類,將其修改為如下所示:

      class SecureHTTPServer(ThreadedWSGIServer):
          def __init__(self, address, handler_cls, certificate, key, ipv6=False):
              super(SecureHTTPServer, self).__init__(address, handler_cls, ipv6=ipv6)
              context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
              context.load_cert_chain(certificate, key)
              self.socket = context.wrap_socket(self.socket,
                                             server_side=True,)
      

      之后SSL的配置就完成了。

      users/views.py,第88行有一個(gè)uploadView函數(shù),這個(gè)函數(shù)需要大改一下。

      我們可以看到里面有很多D:/electronicDocument/meida/...這樣的路徑。這也是我推薦把項(xiàng)目克隆到D盤的原因,這個(gè)項(xiàng)目里有很多的文件路徑都是絕對(duì)路徑。

      我們的路徑里面沒有electronicDocument。如果直接把項(xiàng)目克隆到了D盤,直接把它替換成Document-transmission-master即可。不在D盤的情況下把替換為對(duì)應(yīng)路徑。其他文件中也會(huì)出現(xiàn)類似的問題,如果在運(yùn)行項(xiàng)目時(shí),出現(xiàn)FileNotFound的問題,通常就是因?yàn)檫@個(gè)沒有修改,運(yùn)行過程中出現(xiàn)報(bào)錯(cuò)再修改也可以。

      還有PyPDF2的一些方法也被修改了,在200行附近,可以看到如下代碼:

      		file_reader = PdfFileReader("D:\\electronicDocument\\media\\documentFile\\"+str(myFile))
              file_writer = PdfFileWriter()
              for page in range(file_reader.getNumPages()):
                  file_writer.addPage(file_reader.getPage(page))
      

      遺憾的是一些方法已經(jīng)使用不了了,將其修改為如下代碼:

              file_reader = PdfReader("D:\\Document-transmission-msaster\\media\\documentFile\\"+str(myFile))
              file_writer = PdfWriter()
              for page in range(len(file_reader.pages)):
                  file_writer.add_page(file_reader.pages[page])
      

      這樣上傳公文的功能就可以使用了。

      修改到目前,這種狀況只能查看文件名為純英文的文件,不能上傳為文件名含有其他語(yǔ)言字符的文件,這是由于查看公文時(shí)傳到后臺(tái)的文件名中的其他語(yǔ)言字符進(jìn)行了URL編碼,但是查找文件的沒有將編碼轉(zhuǎn)化為對(duì)應(yīng)字符。

      play/views.py中,開頭第一行寫入from urllib.parse import unquote進(jìn)行包的導(dǎo)入。在第10行左右有一個(gè)playview函數(shù),下滑到65行左右有一行代碼file = documents.file.url[1::],在這行的下一行添加如下代碼:

      file = unquote(file)
      

      再下滑到最底部,有一個(gè)downloadr函數(shù)。同理,在115行左右的file = document.file.url[1::]下一行中添加如下代碼:

      file = unquote(file)
      

      這樣就能進(jìn)行相關(guān)的文件查看和下載了。

      到此,代碼幾乎修改完成。

      項(xiàng)目運(yùn)行

      項(xiàng)目需要我們找到development.crtdevelopment.key兩個(gè)文件,應(yīng)該在Python中Lib\site-package\sslserver\certs文件夾里面,我的路徑是D:\信息安全系 ocument-transmission-master\.venv\Lib\site-packages\sslserver\certs\development.crtD:\信息安全系統(tǒng)設(shè)計(jì)\Document-transmission-master\.venv\Libckages\sslserver\certs\development.key 。

      在終端中使用如下命令啟動(dòng)服務(wù):

      (.venv) PS D:\信息安全系統(tǒng)設(shè)計(jì)\Document-transmission-master\Document-transmission-master> python manage.py runsslserver --certificate D:\信息安全系 ocument-transmission-master\.venv\Lib\site-packages\sslserver\certs\development.crt --key D:\信息安全系統(tǒng)設(shè)計(jì)\Document-transmission-master\.venv\Libckages\sslserver\certs\development.key         
      

      --certificate用于指定證書,--key用于指定私鑰。

      之后可能會(huì)有一些報(bào)錯(cuò),應(yīng)該是因?yàn)槿笔承┌凑丈鲜霭惭b包的方式一起安裝就可以了;也可能是因?yàn)槎丝谝呀?jīng)被占用,這時(shí)候需要?dú)⑺蓝丝谒谶M(jìn)程。

      在這之后,如果出現(xiàn)如下提升,便證明服務(wù)啟動(dòng)成功:

      Watching for file changes with StatReloader
      Validating models...
      
      System check identified some issues:
      
      WARNINGS:
      user.MyUser: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
              HINT: Configure the DEFAULT_AUTO_FIELD setting or the UserConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
      
      System check identified 1 issue (0 silenced).
      December 08, 2024 - 15:54:27
      Django version 5.1.4, using settings 'electronicDocument.settings'
      Starting development server at https://127.0.0.1:8000/
      Using SSL certificate: D:\信息安全系統(tǒng)設(shè)計(jì)\Document-transmission-master\.venv\Lib\site-packages\sslserver\certs\development.crt
      Using SSL key: D:\信息安全系統(tǒng)設(shè)計(jì)\Document-transmission-master\.venv\Lib\site-packages\sslserver\certs\development.key
      Quit the server with CTRL-BREAK.
      

      此時(shí),你的服務(wù)已經(jīng)啟動(dòng)成功,可以在https://127.0.0.1:8000/進(jìn)行相關(guān)操作了。

      完成電子公文交換系統(tǒng),系統(tǒng)功能展示

      操作員界面

      注冊(cè)界面

      登陸界面

      首頁(yè)

      用戶中心

      發(fā)文

      發(fā)送公文
      從本地上傳公文(公開)

      成功上傳

      從本地上傳公文(私密)

      成功上傳

      查看公文(附有SM3哈希值后16位,可用于文件完整性檢驗(yàn))
      公開的公文

      私密的公文

      審核公文(公文批復(fù))

      查詢公文

      收文

      公文簽收(下載公文)

      查看公文(附有哈希值,可用于文件完整性檢驗(yàn))

      查詢公文

      后臺(tái)管理員界面(系統(tǒng)管理員、用戶管理員)

      修改數(shù)據(jù)庫(kù)內(nèi)is_superuser is_staff is_secert的值從0變?yōu)?,使得我能順利地在站點(diǎn)管理頁(yè)面成功登陸

      登錄界面

      首頁(yè)

      用戶管理員

      增、刪、改用戶

      需要錄入用戶名、密碼等信息

      權(quán)限設(shè)置(用戶認(rèn)證授權(quán))[是否為超級(jí)用戶(審計(jì)員、安全審計(jì)員、安全保密管理員、系統(tǒng)管理員、操作員)]

      系統(tǒng)管理員

      系統(tǒng)日志(查看公文信息)

      可以查看公文標(biāo)題、上傳者、發(fā)文機(jī)關(guān)、上傳時(shí)間、公文縮略圖

      組織單位(根據(jù)發(fā)文單位篩選公文)
      以中辦電科院為發(fā)文機(jī)關(guān)的公文

      以北京電子科技學(xué)院為發(fā)文機(jī)關(guān)的公文

      黃金法則

      身份鑒別:口令不能明存,數(shù)據(jù)庫(kù)要保存加鹽的SM3Hash值

      file = documents.file.url[1::]
          file = unquote(file)
          path_doc = os.path.join("D:/信息安全系統(tǒng)設(shè)計(jì)/Document-transmission-master/Document-transmission-master/", file)
          # print(path_doc)
          try:
              sm3_hash = "openssl dgst -sm3 " + path_doc
              bash_r = os.popen(sm3_hash)
              info = bash_r.readlines()  # 讀取命令行的輸出到一個(gè)list
      
              for line in info:  # 按行遍歷
                  line = line.strip('\r\n')
                  hash_16 =line[-16::]
                  print(hash_16)
                  # print(line)
          except:
              print('sm3 error')
          return render(request, 'play.html', locals())
      

      訪問控制:操作員,審核員,安全三員的權(quán)限設(shè)置

      詳見前面系統(tǒng)展示部分

      安全審計(jì):至少完成日志查詢功能

      可以查看公文標(biāo)題、上傳者、發(fā)文機(jī)關(guān)、上傳時(shí)間、公文縮略圖

      密碼

      算法:SM2,SM3,SM4,推薦使用 Key

      部分代碼展示如下:

      sm2.py

      import binascii
      from random import choice
      from . import sm3, func
      from Cryptodome.Util.asn1 import DerSequence, DerInteger
      from binascii import unhexlify
      # 選擇素域,設(shè)置橢圓曲線參數(shù)
      
      default_ecc_table = {
          'n': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123',
          'p': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF',
          'g': '32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7'
               'bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0',
          'a': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC',
          'b': '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93',
      }
      
      
      class CryptSM2(object):
      
          def __init__(self, private_key, public_key, ecc_table=default_ecc_table, mode=0, asn1=False):
              """
              mode: 0-C1C2C3, 1-C1C3C2 (default is 1)
              """
              self.private_key = private_key
              self.public_key = public_key.lstrip("04") if public_key.startswith("04") else public_key
              self.para_len = len(ecc_table['n'])
              self.ecc_a3 = (
                  int(ecc_table['a'], base=16) + 3) % int(ecc_table['p'], base=16)
              self.ecc_table = ecc_table
              assert mode in (0, 1), 'mode must be one of (0, 1)'
              self.mode = mode
              self.asn1 = asn1
      
          def _kg(self, k, Point):  # kP運(yùn)算
              Point = '%s%s' % (Point, '1')
              mask_str = '8'
              for i in range(self.para_len - 1):
                  mask_str += '0'
              mask = int(mask_str, 16)
              Temp = Point
              flag = False
              for n in range(self.para_len * 4):
                  if (flag):
                      Temp = self._double_point(Temp)
                  if (k & mask) != 0:
                      if (flag):
                          Temp = self._add_point(Temp, Point)
                      else:
                          flag = True
                          Temp = Point
                  k = k << 1
              return self._convert_jacb_to_nor(Temp)
      
          def _double_point(self, Point):  # 倍點(diǎn)
              l = len(Point)
              len_2 = 2 * self.para_len
              if l < self.para_len * 2:
                  return None
              else:
                  x1 = int(Point[0:self.para_len], 16)
                  y1 = int(Point[self.para_len:len_2], 16)
                  if l == len_2:
                      z1 = 1
                  else:
                      z1 = int(Point[len_2:], 16)
      
                  T6 = (z1 * z1) % int(self.ecc_table['p'], base=16)
                  T2 = (y1 * y1) % int(self.ecc_table['p'], base=16)
                  T3 = (x1 + T6) % int(self.ecc_table['p'], base=16)
                  T4 = (x1 - T6) % int(self.ecc_table['p'], base=16)
                  T1 = (T3 * T4) % int(self.ecc_table['p'], base=16)
                  T3 = (y1 * z1) % int(self.ecc_table['p'], base=16)
                  T4 = (T2 * 8) % int(self.ecc_table['p'], base=16)
                  T5 = (x1 * T4) % int(self.ecc_table['p'], base=16)
                  T1 = (T1 * 3) % int(self.ecc_table['p'], base=16)
                  T6 = (T6 * T6) % int(self.ecc_table['p'], base=16)
                  T6 = (self.ecc_a3 * T6) % int(self.ecc_table['p'], base=16)
                  T1 = (T1 + T6) % int(self.ecc_table['p'], base=16)
                  z3 = (T3 + T3) % int(self.ecc_table['p'], base=16)
                  T3 = (T1 * T1) % int(self.ecc_table['p'], base=16)
                  T2 = (T2 * T4) % int(self.ecc_table['p'], base=16)
                  x3 = (T3 - T5) % int(self.ecc_table['p'], base=16)
      
                  if (T5 % 2) == 1:
                      T4 = (T5 + ((T5 + int(self.ecc_table['p'], base=16)) >> 1) - T3) % int(
                          self.ecc_table['p'], base=16)
                  else:
                      T4 = (T5 + (T5 >> 1) - T3) % int(self.ecc_table['p'], base=16)
      
                  T1 = (T1 * T4) % int(self.ecc_table['p'], base=16)
                  y3 = (T1 - T2) % int(self.ecc_table['p'], base=16)
      
                  form = '%%0%dx' % self.para_len
                  form = form * 3
                  return form % (x3, y3, z3)
      
          def _add_point(self, P1, P2):  # 點(diǎn)加函數(shù),P2點(diǎn)為仿射坐標(biāo)即z=1,P1為Jacobian加重射影坐標(biāo)
              len_2 = 2 * self.para_len
              l1 = len(P1)
              l2 = len(P2)
              if (l1 < len_2) or (l2 < len_2):
                  return None
              else:
                  X1 = int(P1[0:self.para_len], 16)
                  Y1 = int(P1[self.para_len:len_2], 16)
                  if (l1 == len_2):
                      Z1 = 1
                  else:
                      Z1 = int(P1[len_2:], 16)
                  x2 = int(P2[0:self.para_len], 16)
                  y2 = int(P2[self.para_len:len_2], 16)
      
                  T1 = (Z1 * Z1) % int(self.ecc_table['p'], base=16)
                  T2 = (y2 * Z1) % int(self.ecc_table['p'], base=16)
                  T3 = (x2 * T1) % int(self.ecc_table['p'], base=16)
                  T1 = (T1 * T2) % int(self.ecc_table['p'], base=16)
                  T2 = (T3 - X1) % int(self.ecc_table['p'], base=16)
                  T3 = (T3 + X1) % int(self.ecc_table['p'], base=16)
                  T4 = (T2 * T2) % int(self.ecc_table['p'], base=16)
                  T1 = (T1 - Y1) % int(self.ecc_table['p'], base=16)
                  Z3 = (Z1 * T2) % int(self.ecc_table['p'], base=16)
                  T2 = (T2 * T4) % int(self.ecc_table['p'], base=16)
                  T3 = (T3 * T4) % int(self.ecc_table['p'], base=16)
                  T5 = (T1 * T1) % int(self.ecc_table['p'], base=16)
                  T4 = (X1 * T4) % int(self.ecc_table['p'], base=16)
                  X3 = (T5 - T3) % int(self.ecc_table['p'], base=16)
                  T2 = (Y1 * T2) % int(self.ecc_table['p'], base=16)
                  T3 = (T4 - X3) % int(self.ecc_table['p'], base=16)
                  T1 = (T1 * T3) % int(self.ecc_table['p'], base=16)
                  Y3 = (T1 - T2) % int(self.ecc_table['p'], base=16)
      
                  form = '%%0%dx' % self.para_len
                  form = form * 3
                  return form % (X3, Y3, Z3)
      
          def _convert_jacb_to_nor(self, Point):  # Jacobian加重射影坐標(biāo)轉(zhuǎn)換成仿射坐標(biāo)
              len_2 = 2 * self.para_len
              x = int(Point[0:self.para_len], 16)
              y = int(Point[self.para_len:len_2], 16)
              z = int(Point[len_2:], 16)
              z_inv = pow(
                  z, int(self.ecc_table['p'], base=16) - 2, int(self.ecc_table['p'], base=16))
              z_invSquar = (z_inv * z_inv) % int(self.ecc_table['p'], base=16)
              z_invQube = (z_invSquar * z_inv) % int(self.ecc_table['p'], base=16)
              x_new = (x * z_invSquar) % int(self.ecc_table['p'], base=16)
              y_new = (y * z_invQube) % int(self.ecc_table['p'], base=16)
              z_new = (z * z_inv) % int(self.ecc_table['p'], base=16)
              if z_new == 1:
                  form = '%%0%dx' % self.para_len
                  form = form * 2
                  return form % (x_new, y_new)
              else:
                  return None
      
          def verify(self, Sign, data):
              # 驗(yàn)簽函數(shù),sign簽名r||s,E消息hash,public_key公鑰
              if self.asn1:
                  unhex_sign = unhexlify(Sign.encode())
                  seq_der = DerSequence()
                  origin_sign = seq_der.decode(unhex_sign)
                  r = origin_sign[0]
                  s = origin_sign[1]
              else:
                  r = int(Sign[0:self.para_len], 16)
                  s = int(Sign[self.para_len:2*self.para_len], 16)
              e = int(data.hex(), 16)
              t = (r + s) % int(self.ecc_table['n'], base=16)
              if t == 0:
                  return 0
      
              P1 = self._kg(s, self.ecc_table['g'])
              P2 = self._kg(t, self.public_key)
              # print(P1)
              # print(P2)
              if P1 == P2:
                  P1 = '%s%s' % (P1, 1)
                  P1 = self._double_point(P1)
              else:
                  P1 = '%s%s' % (P1, 1)
                  P1 = self._add_point(P1, P2)
                  P1 = self._convert_jacb_to_nor(P1)
      
              x = int(P1[0:self.para_len], 16)
              return r == ((e + x) % int(self.ecc_table['n'], base=16))
      
          def sign(self, data, K):
              """
              簽名函數(shù), data消息的hash,private_key私鑰,K隨機(jī)數(shù),均為16進(jìn)制字符串
              :param self: 
              :param data: data消息的hash
              :param K: K隨機(jī)數(shù)
              :return: 
              """
              E = data.hex()  # 消息轉(zhuǎn)化為16進(jìn)制字符串
              e = int(E, 16)
      
              d = int(self.private_key, 16)
              k = int(K, 16)
      
              P1 = self._kg(k, self.ecc_table['g'])
      
              x = int(P1[0:self.para_len], 16)
              R = ((e + x) % int(self.ecc_table['n'], base=16))
              if R == 0 or R + k == int(self.ecc_table['n'], base=16):
                  return None
              d_1 = pow(
                  d+1, int(self.ecc_table['n'], base=16) - 2, int(self.ecc_table['n'], base=16))
              S = (d_1*(k + R) - R) % int(self.ecc_table['n'], base=16)
              if S == 0:
                  return None
              elif self.asn1:
                  return DerSequence([DerInteger(R), DerInteger(S)]).encode().hex()
              else:
                  return '%064x%064x' % (R, S)
      
          def encrypt(self, data):
              # 加密函數(shù),data消息(bytes)
              msg = data.hex()  # 消息轉(zhuǎn)化為16進(jìn)制字符串
              k = func.random_hex(self.para_len)
              C1 = self._kg(int(k, 16), self.ecc_table['g'])
              xy = self._kg(int(k, 16), self.public_key)
              x2 = xy[0:self.para_len]
              y2 = xy[self.para_len:2*self.para_len]
              ml = len(msg)
              t = sm3.sm3_kdf(xy.encode('utf8'), ml/2)
              if int(t, 16) == 0:
                  return None
              else:
                  form = '%%0%dx' % ml
                  C2 = form % (int(msg, 16) ^ int(t, 16))
                  C3 = sm3.sm3_hash([
                      i for i in bytes.fromhex('%s%s%s' % (x2, msg, y2))
                  ])
                  if self.mode:
                      return bytes.fromhex('%s%s%s' % (C1, C3, C2))
                  else:
                      return bytes.fromhex('%s%s%s' % (C1, C2, C3))
      
          def decrypt(self, data):
              # 解密函數(shù),data密文(bytes)
              data = data.hex()
              len_2 = 2 * self.para_len
              len_3 = len_2 + 64
              C1 = data[0:len_2]
      
              if self.mode:
                  C3 = data[len_2:len_3]
                  C2 = data[len_3:]
              else:
                  C2 = data[len_2:-64]
                  C3 = data[-64:]
      
              xy = self._kg(int(self.private_key, 16), C1)
              # print('xy = %s' % xy)
              x2 = xy[0:self.para_len]
              y2 = xy[self.para_len:len_2]
              cl = len(C2)
              t = sm3.sm3_kdf(xy.encode('utf8'), cl/2)
              if int(t, 16) == 0:
                  return None
              else:
                  form = '%%0%dx' % cl
                  M = form % (int(C2, 16) ^ int(t, 16))
                  u = sm3.sm3_hash([
                      i for i in bytes.fromhex('%s%s%s' % (x2, M, y2))
                  ])
                  return bytes.fromhex(M)
      
          def _sm3_z(self, data):
              """
              SM3WITHSM2 簽名規(guī)則:  SM2.sign(SM3(Z+MSG),PrivateKey)
              其中: z = Hash256(Len(ID) + ID + a + b + xG + yG + xA + yA)
              """
              # sm3withsm2 的 z 值
              z = '0080'+'31323334353637383132333435363738' + \
                  self.ecc_table['a'] + self.ecc_table['b'] + self.ecc_table['g'] + \
                  self.public_key
              z = binascii.a2b_hex(z)
              Za = sm3.sm3_hash(func.bytes_to_list(z))
              M_ = (Za + data.hex()).encode('utf-8')
              e = sm3.sm3_hash(func.bytes_to_list(binascii.a2b_hex(M_)))
              return e
      
          def sign_with_sm3(self, data, random_hex_str=None):
              sign_data = binascii.a2b_hex(self._sm3_z(data).encode('utf-8'))
              if random_hex_str is None:
                  random_hex_str = func.random_hex(self.para_len)
              sign = self.sign(sign_data, random_hex_str)  # 16進(jìn)制
              return sign
      
          def verify_with_sm3(self, sign, data):
              sign_data = binascii.a2b_hex(self._sm3_z(data).encode('utf-8'))
              return self.verify(sign, sign_data)
      

      sm3.py

      import binascii
      from math import ceil
      from .func import rotl, bytes_to_list
      
      IV = [
          1937774191, 1226093241, 388252375, 3666478592,
          2842636476, 372324522, 3817729613, 2969243214,
      ]
      
      T_j = [
          2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
          2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
          2043430169, 2043430169, 2043430169, 2043430169, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
          2055708042, 2055708042, 2055708042, 2055708042
      ]
      
      def sm3_ff_j(x, y, z, j):
          if 0 <= j and j < 16:
              ret = x ^ y ^ z
          elif 16 <= j and j < 64:
              ret = (x & y) | (x & z) | (y & z)
          return ret
      
      def sm3_gg_j(x, y, z, j):
          if 0 <= j and j < 16:
              ret = x ^ y ^ z
          elif 16 <= j and j < 64:
              #ret = (X | Y) & ((2 ** 32 - 1 - X) | Z)
              ret = (x & y) | ((~ x) & z)
          return ret
      
      def sm3_p_0(x):
          return x ^ (rotl(x, 9 % 32)) ^ (rotl(x, 17 % 32))
      
      def sm3_p_1(x):
          return x ^ (rotl(x, 15 % 32)) ^ (rotl(x, 23 % 32))
      
      def sm3_cf(v_i, b_i):
          w = []
          for i in range(16):
              weight = 0x1000000
              data = 0
              for k in range(i*4,(i+1)*4):
                  data = data + b_i[k]*weight
                  weight = int(weight/0x100)
              w.append(data)
      
          for j in range(16, 68):
              w.append(0)
              w[j] = sm3_p_1(w[j-16] ^ w[j-9] ^ (rotl(w[j-3], 15 % 32))) ^ (rotl(w[j-13], 7 % 32)) ^ w[j-6]
              str1 = "%08x" % w[j]
          w_1 = []
          for j in range(0, 64):
              w_1.append(0)
              w_1[j] = w[j] ^ w[j+4]
              str1 = "%08x" % w_1[j]
      
          a, b, c, d, e, f, g, h = v_i
      
          for j in range(0, 64):
              ss_1 = rotl(
                  ((rotl(a, 12 % 32)) +
                  e +
                  (rotl(T_j[j], j % 32))) & 0xffffffff, 7 % 32
              )
              ss_2 = ss_1 ^ (rotl(a, 12 % 32))
              tt_1 = (sm3_ff_j(a, b, c, j) + d + ss_2 + w_1[j]) & 0xffffffff
              tt_2 = (sm3_gg_j(e, f, g, j) + h + ss_1 + w[j]) & 0xffffffff
              d = c
              c = rotl(b, 9 % 32)
              b = a
              a = tt_1
              h = g
              g = rotl(f, 19 % 32)
              f = e
              e = sm3_p_0(tt_2)
      
              a, b, c, d, e, f, g, h = map(
                  lambda x:x & 0xFFFFFFFF ,[a, b, c, d, e, f, g, h])
      
          v_j = [a, b, c, d, e, f, g, h]
          return [v_j[i] ^ v_i[i] for i in range(8)]
      
      def sm3_hash(msg):
          # print(msg)
          len1 = len(msg)
          reserve1 = len1 % 64
          msg.append(0x80)
          reserve1 = reserve1 + 1
          # 56-64, add 64 byte
          range_end = 56
          if reserve1 > range_end:
              range_end = range_end + 64
      
          for i in range(reserve1, range_end):
              msg.append(0x00)
      
          bit_length = (len1) * 8
          bit_length_str = [bit_length % 0x100]
          for i in range(7):
              bit_length = int(bit_length / 0x100)
              bit_length_str.append(bit_length % 0x100)
          for i in range(8):
              msg.append(bit_length_str[7-i])
      
          group_count = round(len(msg) / 64)
      
          B = []
          for i in range(0, group_count):
              B.append(msg[i*64:(i+1)*64])
      
          V = []
          V.append(IV)
          for i in range(0, group_count):
              V.append(sm3_cf(V[i], B[i]))
      
          y = V[i+1]
          result = ""
          for i in y:
              result = '%s%08x' % (result, i)
          return result
      
      def sm3_kdf(z, klen): # z為16進(jìn)制表示的比特串(str),klen為密鑰長(zhǎng)度(單位byte)
          klen = int(klen)
          ct = 0x00000001
          rcnt = ceil(klen/32)
          zin = [i for i in bytes.fromhex(z.decode('utf8'))]
          ha = ""
          for i in range(rcnt):
              msg = zin  + [i for i in binascii.a2b_hex(('%08x' % ct).encode('utf8'))]
              ha = ha + sm3_hash(msg)
              ct += 1
          return ha[0: klen * 2]
      

      sm4.py

      # -*-coding:utf-8-*-
      import copy
      from .func import xor, rotl, get_uint32_be, put_uint32_be, \
          bytes_to_list, list_to_bytes, pkcs7_padding, pkcs7_unpadding, zero_padding, zero_unpadding
      
      # Expanded SM4 box table
      SM4_BOXES_TABLE = [
          0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c,
          0x05, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86,
          0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed,
          0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa,
          0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c,
          0x19, 0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb,
          0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25,
          0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
          0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38,
          0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34,
          0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82,
          0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45,
          0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 0x8d, 0x1b, 0xaf,
          0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a, 0xc1,
          0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89,
          0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
          0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39,
          0x48,
      ]
      
      # System parameter
      SM4_FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]
      
      # fixed parameter
      SM4_CK = [
          0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
          0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
          0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
          0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
          0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
          0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
          0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
          0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
      ]
      
      SM4_ENCRYPT = 0
      SM4_DECRYPT = 1
      
      PKCS7 = 0
      ZERO = 1
      
      
      class CryptSM4(object):
      
          def __init__(self, mode=SM4_ENCRYPT, padding_mode=PKCS7):
              self.sk = [0] * 32
              self.mode = mode
              self.padding_mode = padding_mode
          # Calculating round encryption key.
          # args:    [in] a: a is a 32 bits unsigned value;
          # return: sk[i]: i{0,1,2,3,...31}.
      
          @classmethod
          def _round_key(cls, ka):
              b = [0, 0, 0, 0]
              a = put_uint32_be(ka)
              b[0] = SM4_BOXES_TABLE[a[0]]
              b[1] = SM4_BOXES_TABLE[a[1]]
              b[2] = SM4_BOXES_TABLE[a[2]]
              b[3] = SM4_BOXES_TABLE[a[3]]
              bb = get_uint32_be(b[0:4])
              rk = bb ^ (rotl(bb, 13)) ^ (rotl(bb, 23))
              return rk
      
          # Calculating and getting encryption/decryption contents.
          # args:    [in] x0: original contents;
          # args:    [in] x1: original contents;
          # args:    [in] x2: original contents;
          # args:    [in] x3: original contents;
          # args:    [in] rk: encryption/decryption key;
          # return the contents of encryption/decryption contents.
          @classmethod
          def _f(cls, x0, x1, x2, x3, rk):
              # "T algorithm" == "L algorithm" + "t algorithm".
              # args:    [in] a: a is a 32 bits unsigned value;
              # return: c: c is calculated with line algorithm "L" and nonline
              # algorithm "t"
              def _sm4_l_t(ka):
                  b = [0, 0, 0, 0]
                  a = put_uint32_be(ka)
                  b[0] = SM4_BOXES_TABLE[a[0]]
                  b[1] = SM4_BOXES_TABLE[a[1]]
                  b[2] = SM4_BOXES_TABLE[a[2]]
                  b[3] = SM4_BOXES_TABLE[a[3]]
                  bb = get_uint32_be(b[0:4])
                  c = bb ^ (
                      rotl(
                          bb,
                          2)) ^ (
                      rotl(
                          bb,
                          10)) ^ (
                      rotl(
                          bb,
                          18)) ^ (
                      rotl(
                          bb,
                          24))
                  return c
              return (x0 ^ _sm4_l_t(x1 ^ x2 ^ x3 ^ rk))
      
          def set_key(self, key, mode):
              key = bytes_to_list(key)
              MK = [0, 0, 0, 0]
              k = [0] * 36
              MK[0] = get_uint32_be(key[0:4])
              MK[1] = get_uint32_be(key[4:8])
              MK[2] = get_uint32_be(key[8:12])
              MK[3] = get_uint32_be(key[12:16])
              k[0:4] = xor(MK[0:4], SM4_FK[0:4])
              for i in range(32):
                  k[i + 4] = k[i] ^ (
                      self._round_key(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ SM4_CK[i]))
                  self.sk[i] = k[i + 4]
              self.mode = mode
              if mode == SM4_DECRYPT:
                  for idx in range(16):
                      t = self.sk[idx]
                      self.sk[idx] = self.sk[31 - idx]
                      self.sk[31 - idx] = t
      
          def one_round(self, sk, in_put):
              out_put = []
              ulbuf = [0] * 36
              ulbuf[0] = get_uint32_be(in_put[0:4])
              ulbuf[1] = get_uint32_be(in_put[4:8])
              ulbuf[2] = get_uint32_be(in_put[8:12])
              ulbuf[3] = get_uint32_be(in_put[12:16])
              for idx in range(32):
                  ulbuf[idx + 4] = self._f(ulbuf[idx],
                                           ulbuf[idx + 1],
                                           ulbuf[idx + 2],
                                           ulbuf[idx + 3],
                                           sk[idx])
      
              out_put += put_uint32_be(ulbuf[35])
              out_put += put_uint32_be(ulbuf[34])
              out_put += put_uint32_be(ulbuf[33])
              out_put += put_uint32_be(ulbuf[32])
              return out_put
      
          def crypt_ecb(self, input_data):
              # SM4-ECB block encryption/decryption
              input_data = bytes_to_list(input_data)
              if self.mode == SM4_ENCRYPT:
                  if self.padding_mode == PKCS7:
                      input_data = pkcs7_padding(input_data)
                  elif self.padding_mode == ZERO:
                      input_data = zero_padding(input_data)
      
              length = len(input_data)
              i = 0
              output_data = []
              while length > 0:
                  output_data += self.one_round(self.sk, input_data[i:i + 16])
                  i += 16
                  length -= 16
              if self.mode == SM4_DECRYPT:
                  if self.padding_mode == PKCS7:
                      return list_to_bytes(pkcs7_unpadding(output_data))
                  elif self.padding_mode == ZERO:
                      return list_to_bytes(zero_unpadding(output_data))
              return list_to_bytes(output_data)
      
          def crypt_cbc(self, iv, input_data):
              # SM4-CBC buffer encryption/decryption
              i = 0
              output_data = []
              tmp_input = [0] * 16
              iv = bytes_to_list(iv)
              if self.mode == SM4_ENCRYPT:
                  input_data = pkcs7_padding(bytes_to_list(input_data))
                  length = len(input_data)
                  while length > 0:
                      tmp_input[0:16] = xor(input_data[i:i + 16], iv[0:16])
                      output_data += self.one_round(self.sk, tmp_input[0:16])
                      iv = copy.deepcopy(output_data[i:i + 16])
                      i += 16
                      length -= 16
                  return list_to_bytes(output_data)
              else:
                  length = len(input_data)
                  while length > 0:
                      output_data += self.one_round(self.sk, input_data[i:i + 16])
                      output_data[i:i + 16] = xor(output_data[i:i + 16], iv[0:16])
                      iv = copy.deepcopy(input_data[i:i + 16])
                      i += 16
                      length -= 16
                  return list_to_bytes(pkcs7_unpadding(output_data))
      

      詳細(xì)代碼詳見提交在青青草原七匹狼/電子公文傳輸系統(tǒng)Gitee庫(kù)或壓縮包里的代碼

      密鑰管理:所有私鑰,對(duì)稱算法密鑰等不能明存

      系統(tǒng)量化評(píng)估

      按照商用密碼應(yīng)用安全性評(píng)估量化評(píng)估規(guī)則,計(jì)算自己系統(tǒng)的得分,只計(jì)算應(yīng)用和數(shù)據(jù)安全

      1.根據(jù)《商用密碼應(yīng)用安全性評(píng)估量化評(píng)估規(guī)則》文件,我們需要關(guān)注的測(cè)評(píng)指標(biāo)包括:

      • 身份鑒別
      • 通信數(shù)據(jù)完整性
      • 通信過程中重要數(shù)據(jù)的機(jī)密性
      • 數(shù)據(jù)存儲(chǔ)和傳輸?shù)陌踩?/li>

      測(cè)評(píng)對(duì)象包括:

      • 用戶賬號(hào)管理
      • 公文的起草、審核、發(fā)送和查詢
      • 系統(tǒng)日志和審計(jì)

      2. 評(píng)估密碼使用安全(D)

      用戶賬號(hào)管理

      • 系統(tǒng)實(shí)現(xiàn)了身份認(rèn)證,對(duì)口令做了加鹽的SHA-256哈希保護(hù)。這符合密碼使用安全的要求。

      公文傳輸

      • 系統(tǒng)使用非對(duì)稱密鑰(SM2)保護(hù)對(duì)稱密鑰,再用對(duì)稱密鑰實(shí)現(xiàn)對(duì)文件的加解密。這符合密碼使用安全的要求。

      3. 評(píng)估密碼算法/技術(shù)合規(guī)性(A)

      密碼算法使用

      • 系統(tǒng)使用了SM2算法進(jìn)行加密,符合商用密碼應(yīng)用安全性評(píng)估量化評(píng)估規(guī)則中對(duì)算法的要求。

      4. 評(píng)估密鑰管理安全(K)

      密鑰管理

      • 私鑰保護(hù):系統(tǒng)使用SM2算法,這是一種合規(guī)的國(guó)產(chǎn)密碼算法,用于保護(hù)對(duì)稱密鑰,符合密鑰管理安全要求。
      • 對(duì)稱密鑰管理:系統(tǒng)使用加鹽的SHA-256哈希存儲(chǔ)密碼,符合安全要求。

      5. 計(jì)算測(cè)評(píng)對(duì)象評(píng)分(Si,j,k)

      根據(jù)上述評(píng)估,每個(gè)測(cè)評(píng)對(duì)象的得分如下:

      • 用戶賬號(hào)管理:1(完全符合)
      • 公文傳輸:1(完全符合)
      • 系統(tǒng)日志和審計(jì):0.5(部分符合,因?yàn)殡m然有日志記錄,但未明確說明密鑰管理細(xì)節(jié))

      6. 計(jì)算測(cè)評(píng)單元得分(Si,j)

      測(cè)評(píng)單元得分為測(cè)評(píng)對(duì)象得分的算術(shù)平均值:
      image

      7. 計(jì)算安全層面得分(Si)

      應(yīng)用和數(shù)據(jù)安全層面的權(quán)重為30(根據(jù)文件《商用密碼應(yīng)用安全性評(píng)估量化評(píng)估規(guī)則》中的權(quán)重設(shè)置),則:
      image

      8. 整體得分計(jì)算

      根據(jù)文件《商用密碼應(yīng)用安全性評(píng)估量化評(píng)估規(guī)則》中的權(quán)重和得分計(jì)算方法,整體得分為:
      image

      計(jì)算結(jié)果為:

      image

      9. 結(jié)合高風(fēng)險(xiǎn)判定

      根據(jù)《商用密碼應(yīng)用安全性評(píng)估量化評(píng)估規(guī)則》,如果系統(tǒng)存在高風(fēng)險(xiǎn)問題,即使得分較高,也需要結(jié)合高風(fēng)險(xiǎn)判定來確定最終的安全評(píng)估結(jié)果。系統(tǒng)實(shí)現(xiàn)了多種安全措施,包括防御XSS、CSRF、SQL注入等,沒有明確指出存在高風(fēng)險(xiǎn)問題。

      綜上所述,電子公文傳輸系統(tǒng)在應(yīng)用與數(shù)據(jù)安全層面的商用密碼應(yīng)用安全性評(píng)估量化評(píng)估得分較高,表明系統(tǒng)在密碼應(yīng)用安全性方面表現(xiàn)良好。

      posted @ 2025-01-27 18:23  20221320馮泰瑞  閱讀(40)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 中文字幕在线国产精品| 日韩精品中文字幕人妻| 免费费很色大片欧一二区| 91福利视频一区二区| 国产成人精品亚洲资源| 亚洲韩国精品无码一区二区三区 | 成人国产精品一区二区网站公司 | 内射视频福利在线观看| 99精品国产一区二区三区| 激情亚洲一区国产精品| 亚洲精品麻豆一二三区| 亚洲国产精品无码观看久久| 61精品人妻一区二区三区| 国产成人人综合亚洲欧美丁香花 | 久热综合在线亚洲精品| 久久国产成人亚洲精品影院老金| 国产成人精品视频国产| 亚洲女同精品久久女同| 亚洲性日韩精品一区二区三区| 黑人大战欲求不满人妻| 日韩精品不卡一区二区三区| 一区二区三区精品视频免费播放| 欧美高清狂热视频60一70| 九九热免费在线观看视频| 疯狂做受xxxx高潮欧美日本| 人妻精品久久无码区| 国产精品天天看天天狠| 四虎国产精品永久在线| 午夜国产小视频| 真实国产乱子伦视频| 日本韩国一区二区精品| 欧美不卡一区二区三区| 欧美大胆老熟妇乱子伦视频| 激情在线网| 久久9精品区-无套内射无码| 国产av一区二区麻豆熟女| 亚洲第一综合天堂另类专| 日本一区二区中文字幕久久| 99精品国产中文字幕| 亚洲AV无码专区亚洲AV桃| 国产在线精品一区二区三区不卡|