一文了解密碼/國密及應用,密碼也卡脖子?

安木夕發表於2023-11-10

image.png

當我們開發金融、國企、政府資訊系統時,不僅要符合網路安全的等保二級、等保三級,還要求符合國密的安全要求,等保測評已經實行很久了,而國密測評近兩年才剛開始。那什麼是密碼/國密?什麼是密評?本文就關於密碼/國密及應用進行基礎的知識梳理、記錄。


01、密碼(國密)演算法有哪些?

國產化替代大家應該都熟悉了,為了應對日益複雜多變的國際形勢(醜國),保障我們的IT技術自助可控,從硬體到軟體,都在進行著國產化替代。密碼領域也不例外,國密就是用來代替國際密碼的。先來了解下密碼的分類,及對應的國密演算法。

image

?國產密碼演算法(國密演算法)是指國家密碼局認定的國產商用密碼演算法,在一般資訊化系統開發中主要使用公開的SM2(非對稱)、SM3(摘要)、SM4(對稱)三類演算法。

Base64是一種編碼格式,並不屬於加密,常用於資料傳輸、相容性問題。Base64編碼本質上是一種將二進位制資料轉成文字資料的方案,將一些不適合傳輸的資料內容進行編碼來適合傳輸。

1.1、對稱加密(DES/AES⇒SM4)

?基本特點

  • 同一個秘鑰進行加密、解密。因此秘鑰的保密性就很重要,不能洩漏。
  • 計算量小、效率高。

?應用場景

  • 資料加密儲存。
  • 加密通訊,如HTTPS、SSL、VPN,會與其他加密演算法混合使用。

1.2、非對稱加密(RSA/ECC⇒SM2)

?基本特點

  • 金鑰配對:一個私鑰、一個公鑰,用私鑰加密,用公鑰解密。注意每一個金鑰對都是獨一無二、天生一對的,只能配對的秘鑰加密、解密。簡單來說,公鑰加密的資料,只能配對的私鑰才能解密。
  • 安全性高,但計算量大。
  • 基本原理:利用某一數學公式,正向計算容易,反向推理則非常難。

?應用場景

  • HTTPS、SSH協議,如Git的ssh認證。
  • HTTPS的安全傳輸就是混合了非對稱加密、對稱加密,非對稱加密協商會話秘鑰,用會話秘鑰對稱加密傳輸資料。
  • 敏感資料的加密傳輸,如客戶端登入時傳輸使用者名稱、密碼資訊時,採用公鑰加密資料,服務端私鑰解密。
  • 對資料進行簽名、驗籤,保障資料的完整性,同時驗證身份。

1.3、雜湊(摘要/雜湊)演算法(MD5/SHA⇒SM3)

image.png

?基本特點

  • 無需秘鑰,“加密”後的資料不可逆。所以這也不算是“加密”,一般稱為雜湊(Hash)。
  • 任何長度的資料生成的雜湊值長度都固定。
  • 相同資料每次生成的雜湊值相同,不同的資料則不同。

?應用場景

  • 資料摘要/雜湊,驗證資料是否被篡改、或資料丟失,保障資料的完整性、不可篡改性。
  • 單向加密儲存資料,如密碼的儲存,密碼的儲存普遍都是存的雜湊值,登入時比較其hash值即可。

?彩虹表破解:由於雜湊演算法的特點(同一資料生成雜湊值始終一樣),如果儲存了大量(海量)字元內容的雜湊值,就很容易進行查詢破解了,這就是彩虹表,暴力破解也是一樣的道理。常用的6位數字密碼是相當容易破解的,如CMD5這個網站就利用儲存的大量密文字典,反向查詢破解。怎麼解決呢?

  • 提升雜湊演算法的安全性,常用方法就是加“鹽”,核心思想就是在雜湊過程中新增一些自定義的內容、規則,僅自己知道,從而避免被字典破解。
  • 最簡單的比如在密文中某一位置新增一串隨機字元,只有自己知道,使用的時候去掉干擾字元即可。
  • 加鹽的具體方式很多,可以完全自己DIV,常用的一種模式如下圖,加鹽+雙重雜湊。

  • 如果加鹽的規則被竊取了,對於現代的硬體還是挺容易被破解的,只能設定儘量複雜的密碼+定期更換了。

?實際應用中,可能會多種加密演算法組合使用。

  • 比如HTTPS的安全資料傳輸就是同時用了對稱加密、非對稱加密,用非對稱傳送(動態)金鑰,對稱加密傳輸資料。參考《HTTP協議圖文簡述
  • 對一個資料進行多重加密,以防被破解。

02、什麼是國密?

為了保障國家資訊保安、自主可控,我國制定了自己的密碼法律、法規,及配套的密碼演算法。《中華人民共和國密碼法》中將密碼劃分為核心密碼、普通密碼和商用密碼。

  • 核心密碼、 普通密碼屬於國家秘密,商業系統都不涉及。
  • 商用密碼用於保護不屬於國家秘密的資訊,公民、法人和其他 組織可以依法使用商用密碼保護網路與資訊保安,一般開發中接觸更多的是商用密碼。企業(民企、國企)系統、政務系統用的都是商用密碼。

?2018年2月,密標委釋出了GM/T 0054-2018 《資訊系統密碼應用基本要求》簡稱國密0054標準,也是我們常說的國密標準。該標準中對資訊系統各項(密碼)安全制定了標準依據。因此,當我們開發金融、國企、政府資訊系統時,越來越多的系統會要求符合國密標準。

2.1、國密標準

國密的安全技術要求如下圖,從硬體、網路到系統、資料全方位的加密安全要求,對於軟體系統開發而言就是資料傳輸、資料儲存的加密,主要涉及SM2、SM3、SM4、SM9

  • 對於WEB應用,資料傳輸加密還是基於HTTPS協議,只是加密演算法全面要替換為國密。這方面已經有比較完整的解放方案了,服務端用國密版Nginx(得益於開源的Nginx)。客戶端用國密版的瀏覽器,如360的國密版瀏覽器、零信瀏覽器,基本都是基於chrome核心,內建了國密演算法、國密CA。
  • 對於資料加密,就主要是SM2(非對稱)、SM3(摘要)、SM4(對稱)三類演算法了,替換掉以前常用的RSA、MD5、SHA演算法。

2.2、還有密評?

做過國企、政府專案的都知道,系統都是要過安全測評(等保三級),對於密碼現在也有了密評,就是評價系統是否符合國密安全要求,評測透過才能上線,沒透過的系統就得改造升級了。

image.png

??密評物件:關基(關鍵資訊基礎設施)、等保三級及以上系統、國家政務系統,密評頻率為每年至少一次。

  • 基礎資訊網路:電信網、廣播電視網、網際網路。
  • 重要資訊系統:能源、教育、公安、測繪地理資訊、社保、交通、衛生計生、金融等涉及國計民生和基礎資訊資源的重要資訊系統。
  • 重要工業控制系統:核設施、航空航天、先進製造、石油石化、油氣管網、電力系統、交通運輸、水利樞紐、城市設施等重要工業控制系統。
  • 面向社會服務的政務資訊系統:黨政機關和使用財政性資金的事業單位和團體組織使用的面向社會服務的資訊系統。

密評的實施過程:方案評估》系統測試》定期檢查,密評的執行是由專門的密評機構(公司)進行的。


03、開源密碼庫

對於國際加密演算法是已經很成熟了,有很多開源的庫,一些語言框架還內建了。但國密演算法的開源庫雖然沒那麼豐富,也基本夠用了。

名稱 描述 github
crypto-js MD5、SHA1、SHA2、SHA3、RIPEMD-160 的雜湊雜湊
AES、DES、Rabbit、RC4、Triple DES 對稱加解密
star=14.5K/fork=2.5K
JSEncrypt 非對稱RSA加解密,只支援瀏覽器,不支援Node star=6.3K/fork=2K
node-rsa 支援Node執行的RSA加解密庫 star=1.3K/fork=211
Web Cryptography API W3C制定的密碼規範API,主流瀏覽器、Node15都已支援
opensm 開源國密SM2/SM3/SM4演算法,基於GmSSL,基於OpenSSL1.1.0,7年前(老) star=9/fork=1.5K
TencentKonaSMSuite 騰訊開源的國密套件SDK(Java) star=191/fork=41
sm-crypto 國密演算法sm2、sm3和sm4的JavaScript實現,有關聯java版 star=576/fork=233
gm-crypto 國密演算法sm2、sm3和sm4的JavaScript實現 star=135/fork=43
sm-crypto-v2 國密演算法 sm2、sm3 和 sm4 的 JavaScript 實現 star=5/fork=223
GmSSL 北京大學國密開源庫,包含多個版本Java、JS、PHP、Go...,沒有npm包 star=4.1K/fork=1.5K
Tongsuo 銅鎖 阿里開源的綜合性基礎密碼庫,功能比較全 star=724/fork=133

JSEncrypt的示例程式碼如下,使用很簡單:

?秘鑰有很多生成方式,如OpenSSL,下面示例用了線上小工具:線上生成公鑰私鑰對,RSA公私鑰生成

<script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.2.1/jsencrypt.min.js"></script>

<script>
  // 公鑰加密
  const encrypt = new JSEncrypt();
  const pubkey='MFwwDQYJK...'
  encrypt.setPublicKey(pubkey);
  const encrypted = encrypt.encrypt('密文內容');
  console.log({encrypted}) //{encrypted: 'CTiPct/iuLXWxcCsZFVSqHglejMzhz9Bg2O6pV0HpCRZK98orNigeARhdP0wBzBiapeiZHiOJY3T9mLmKvjt3w=='}

  // 私鑰解密
  var decrypt = new JSEncrypt();
  const prikey ='MIIBVgIBAD...'
  decrypt.setPrivateKey(prikey);
  var uncrypted = decrypt.decrypt(encrypted);
  console.log({uncrypted}) //{uncrypted: '密文內容'}
</script>

國密的使用:sm-crypto-v2

npm install --save sm-crypto-v2

雜湊sm3:結果值的長度為固定的256Bit = 32個位元組 = 下面結果為64個字元。

import { sm3 } from 'sm-crypto-v2'
// 雜湊演算法,
console.log(sm3('123456')) //207cf410532f92a47dee245ce9b11ff71f578ebd763eb3bbea44ebd043d018fb
console.log(sm3('test'))   //55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23
console.log(sm3('admin'))  //dc1fd00e3eeeb940ff46f457bf97d66ba7fcc36e0b20802383de142860e76ae6
  • 位元(Bit):最小的二進位制長度,值為0/1
  • 位元組(byte):8個二進位制位,即 1 位元組 = 8Bit
  • 16進位制字元每個字元的長度是4位元,剛好 2^4=16

非對稱加密sm2:(sm2也可以用於數字簽名)

import { sm2 } from 'sm-crypto-v2'

// 1.生成秘鑰對(公鑰、私鑰)
const { publicKey, privateKey } = sm2.generateKeyPairHex()
console.table({ publicKey, privateKey }) // 公鑰長度130位,私鑰長度64

// 2. 加密
const encrypted = sm2.doEncrypt('123456', publicKey)
console.log(encrypted) //長度204,基於內容

// 3.解密
const decrypt = sm2.doDecrypt(encrypted, privateKey)
console.log(decrypt) //123456

參考資料


相關文章