爬蟲逆向基礎(chǔ),認識 SM1-SM9英染、ZUC 國密算法

【01x00】 簡介

國密即國家密碼局認定的國產(chǎn)加密算法揽惹,爬蟲工程師在做 JS 逆向的時候,會遇到各種各樣的加密算法四康,其中 RSA、AES狭握、SHA 等算法是最常見的闪金,這些算法都是國外的,在 K 哥以前的文章里也有介紹:《【爬蟲知識】爬蟲常見加密解密算法》

事實上從 2010 年開始论颅,我國國家密碼管理局就已經(jīng)開始陸續(xù)發(fā)布了一系列國產(chǎn)加密算法哎垦,這其中就包括 SM1、SM2恃疯、SM3 漏设、SM4、SM7今妄、SM9郑口、ZUC(祖沖之加密算法)等鸳碧,SM 代表商密,即商業(yè)密碼犬性,是指用于商業(yè)的瞻离、不涉及國家秘密的密碼技術(shù)。SM1 和 SM7 的算法不公開乒裆,其余算法都已成為 ISO/IEC 國際標準套利。

在這些國產(chǎn)加密算法中,SM2鹤耍、SM3肉迫、SM4 三種加密算法是比較常見的,在爬取部分 gov 網(wǎng)站時稿黄,也可能會遇到這些算法喊衫,所以作為爬蟲工程師是有必要了解一下這些算法的,如下圖所示某 gov 網(wǎng)站就使用了 SM2 和 SM4 加密算法:

01.png

【02x00】算法概述

算法名稱 算法類別 應(yīng)用領(lǐng)域 特點
SM1 對稱(分組)加密算法 芯片 分組長度抛猖、密鑰長度均為 128 比特
SM2 非對稱(基于橢圓曲線 ECC)加密算法 數(shù)據(jù)加密 ECC 橢圓曲線密碼機制 256 位格侯,相比 RSA 處理速度快,消耗更少
SM3 散列(hash)函數(shù)算法 完整性校驗 安全性及效率與 SHA-256 相當财著,壓縮函數(shù)更復雜
SM4 對稱(分組)加密算法 數(shù)據(jù)加密和局域網(wǎng)產(chǎn)品 分組長度联四、密鑰長度均為 128 比特,計算輪數(shù)多
SM7 對稱(分組)加密算法 非接觸式 IC 卡 分組長度撑教、密鑰長度均為 128 比特
SM9 標識加密算法(IBE) 端對端離線安全通訊 加密強度等同于 3072 位密鑰的 RSA 加密算法
ZUC 對稱(序列)加密算法 移動通信 4G 網(wǎng)絡(luò) 流密碼

【03x00】算法詳解

【03x01】SM1 分組加密算法

SM1 為分組加密算法朝墩,對稱加密,分組長度和密鑰長度都為 128 位伟姐,故對消息進行加解密時收苏,若消息長度過長,需要進行分組愤兵,要消息長度不足鹿霸,則要進行填充。算法安全保密強度及相關(guān)軟硬件實現(xiàn)性能與 AES 相當秆乳,該算法不公開懦鼠,僅以 IP 核的形式存在于芯片中,調(diào)用該算法時屹堰,需要通過加密芯片的接口進行調(diào)用肛冶,采用該算法已經(jīng)研制了系列芯片、智能 IC 卡扯键、智能密碼鑰匙睦袖、加密卡、加密機等安全產(chǎn)品荣刑,廣泛應(yīng)用于電子政務(wù)馅笙、電子商務(wù)及國民經(jīng)濟的各個應(yīng)用領(lǐng)域(包括國家政務(wù)通伦乔、警務(wù)通等重要領(lǐng)域),一般了解的人比較少延蟹,爬蟲工程師也不會遇到這種加密算法评矩。

【03x02】SM2 橢圓曲線公鑰加密算法

SM2 為橢圓曲線(ECC)公鑰加密算法,非對稱加密阱飘,SM2 算法和 RSA 算法都是公鑰加密算法斥杜,SM2 算法是一種更先進安全的算法,在我們國家商用密碼體系中被用來替換 RSA 算法沥匈,在不少 gov 網(wǎng)站會見到此類加密算法蔗喂。我國學者對橢圓曲線密碼的研究從 20 世紀 80 年代開始,目前已取得不少成果高帖,SM2 橢圓曲線公鑰密碼算法比 RSA 算法有以下優(yōu)勢:

SM2 RSA
安全性 256 位 SM2 強度已超過 RSA-2048 一般
算法結(jié)構(gòu) 基本橢圓曲線(ECC) 基于特殊的可逆模冪運算
計算復雜度 完全指數(shù)級 亞指數(shù)級
存儲空間(密鑰長度) 192-256 bit 2048-4096 bit
秘鑰生成速度 較 RSA 算法快百倍以上
解密加密速度 較快 一般

【03x03】SM3 雜湊算法

SM3 為密碼雜湊算法缰儿,采用密碼散列(hash)函數(shù)標準,用于替代 MD5/SHA-1/SHA-2 等國際算法散址,是在 SHA-256 基礎(chǔ)上改進實現(xiàn)的一種算法乖阵,消息分組長度為 512 位,摘要值長度為 256 位预麸,其中使用了異或瞪浸、模、模加吏祸、移位对蒲、與、或贡翘、非運算蹈矮,由填充、迭代過程鸣驱、消息擴展和壓縮函數(shù)所構(gòu)成泛鸟。在商用密碼體系中,SM3 主要用于數(shù)字簽名及驗證踊东、消息認證碼生成及驗證谈况、隨機數(shù)生成等。據(jù)國家密碼管理局表示递胧,其安全性及效率要高于 MD5 算法和 SHA-1 算法,與 SHA-256 相當赡茸。

【03x04】SM4 分組加密算法

SM4 為無線局域網(wǎng)標準的分組加密算法缎脾,對稱加密,用于替代 DES/AES 等國際算法占卧,SM4 算法與 AES 算法具有相同的密鑰長度和分組長度遗菠,均為 128 位联喘,故對消息進行加解密時,若消息長度過長辙纬,需要進行分組豁遭,要消息長度不足,則要進行填充贺拣。加密算法與密鑰擴展算法都采用 32 輪非線性迭代結(jié)構(gòu)蓖谢,解密算法與加密算法的結(jié)構(gòu)相同,只是輪密鑰的使用順序相反譬涡,解密輪密鑰是加密輪密鑰的逆序闪幽。

SM4 DES AES
計算輪數(shù) 32 16(3DES 為 16*3) 10/12/14
密碼部件 S 盒、非線性變換涡匀、線性變換盯腌、合成變換 標準算術(shù)和邏輯運算、先替換后置換陨瘩,不含線性變換 S 盒腕够、行移位變換、列混合變換舌劳、圈密鑰加變換(AddRoundKey)

【03x05】SM7 分組加密算法

SM7 為分組加密算法帚湘,對稱加密,該算法不公開蒿囤,應(yīng)用包括身份識別類應(yīng)用(非接觸式 IC 卡客们、門禁卡、工作證材诽、參賽證等)底挫,票務(wù)類應(yīng)用(大型賽事門票、展會門票等)脸侥,支付與通卡類應(yīng)用(積分消費卡建邓、校園一卡通、企業(yè)一卡通等)睁枕。爬蟲工程師基本上不會遇到此類算法官边。

【03x06】SM9 標識加密算法

SM9 為標識加密算法(Identity-Based Cryptography),非對稱加密外遇,標識加密將用戶的標識(如微信號注簿、郵件地址、手機號碼跳仿、QQ 號等)作為公鑰诡渴,省略了交換數(shù)字證書和公鑰過程,使得安全系統(tǒng)變得易于部署和管理菲语,適用于互聯(lián)網(wǎng)應(yīng)用的各種新興應(yīng)用的安全保障妄辩,如基于云技術(shù)的密碼服務(wù)惑灵、電子郵件安全、智能終端保護眼耀、物聯(lián)網(wǎng)安全英支、云存儲安全等等。這些安全應(yīng)用可采用手機號碼或郵件地址作為公鑰哮伟,實現(xiàn)數(shù)據(jù)加密干花、身份認證、通話加密澈吨、通道加密等把敢。在商用密碼體系中,SM9 主要用于用戶的身份認證谅辣,據(jù)新華網(wǎng)公開報道修赞,SM9 的加密強度等同于 3072 位密鑰的 RSA 加密算法。

【03x07】ZUC 祖沖之算法

ZUC 為流密碼算法桑阶,對稱加密柏副,該機密性算法可適用于 3GPP LTE 通信中的加密和解密,該算法包括祖沖之算法(ZUC)蚣录、機密性算法(128-EEA3)和完整性算法(128-EIA3)三個部分割择。已經(jīng)被國際組織 3GPP 推薦為 4G 無線通信的第三套國際加密和完整性標準的候選算法。

【04x00】編程語言實現(xiàn)

【04x01】Python 語言實現(xiàn)

在 Python 里面并沒有比較官方的庫來實現(xiàn)國密算法萎河,這里僅列出了其中兩個較為完善的第三方庫荔泳,需要注意的是,SM1 和 SM7 算法不公開虐杯,目前大多庫僅實現(xiàn)了 SM2玛歌、SM3、SM4 三種密算法擎椰。

其中 gmssl-python 是 gmssl 的改進版支子,gmssl-python 新增支持了 SM9 算法,不過截止本文編寫時达舒,gmssl-python 并未發(fā)布 pypi值朋,也未 PR 到 gmssl,使用 pip install gmssl 安裝的 gmssl 不支持 SM9 算法巩搏。若要使用 SM9 算法昨登,可下載 gmssl-python 源碼手動安裝。

以 gmssl 的 SM2 算法為例贯底,實現(xiàn)如下(其他算法和詳細用法可參考其官方文檔):

SM2 加密(encrypt)和解密(decrypt):

from gmssl import sm2


# 16 進制的公鑰和私鑰
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

# 待加密數(shù)據(jù)和加密后數(shù)據(jù)為 bytes 類型
data = b"this is the data to be encrypted"
enc_data = sm2_crypt.encrypt(data)
dec_data = sm2_crypt.decrypt(enc_data)

print('enc_data: ', enc_data.hex())
print('dec_data: ', dec_data)

# enc_data:  3cb96dd2e0b6c24df8e22a5da3951d061a6ee6ce99f46a446426feca83e501073288b1553ca8d91fad79054e26696a27c982492466dafb5ed06a573fb09947f2aed8dfae243b095ab88115c584bb6f0814efe2f338a00de42b244c99698e81c7913c1d82b7609557677a36681dd10b646229350ad0261b51ca5ed6030d660947

# dec_data:  b'this is the data to be encrypted'

SM2 簽名(sign)和校驗(verify):

from gmssl import sm2, func


# 16 進制的公鑰和私鑰
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207'
sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key)

# 待簽名數(shù)據(jù)為 bytes 類型
data = b"this is the data to be signed"
random_hex_str = func.random_hex(sm2_crypt.para_len)

#  16 進制
sign = sm2_crypt.sign(data, random_hex_str)
verify = sm2_crypt.verify(sign, data)

print('sign: ', sign)
print('verify: ', verify)

# sign:  45cfe5306b1a87cf5d0034ef6712babdd1d98547e75bcf89a17f3bcb617150a3f111ab05597601bab8c41e2b980754b74ebe9a169a59db37d549569910ae273a

# verify:  True

【04x02】JavaScript 語言實現(xiàn)

在 JavaScript 中已有比較成熟的實現(xiàn)庫篙骡,這里推薦 sm-crypto,目前支持 SM2、SM3 和 SM4糯俗,需要注意的是,SM2 非對稱加密的結(jié)果由 C1睦擂、C2得湘、C3 三部分組成,其中 C1 是生成隨機數(shù)的計算出的橢圓曲線點顿仇,C2 是密文數(shù)據(jù)淘正,C3 是 SM3 的摘要值,最開始的國密標準的結(jié)果是按 C1C2C3 順序的臼闻,新標準的是按 C1C3C2 順序存放的鸿吆,sm-crypto 支持設(shè)置 cipherMode,也就是 C1C2C3 的排列順序述呐。

sm-crypto:https://www.npmjs.com/package/sm-crypto

以 SM2 算法為例惩淳,實現(xiàn)如下(其他算法和詳細用法可參考其官方文檔):

SM2 加密(encrypt)和解密(decrypt):

const sm2 = require('sm-crypto').sm2

// 1 - C1C3C2,0 - C1C2C3乓搬,默認為1
const cipherMode = 1

// 獲取密鑰對
let keypair = sm2.generateKeyPairHex()
let publicKey = keypair.publicKey   // 公鑰
let privateKey = keypair.privateKey // 私鑰

let msgString = "this is the data to be encrypted"
let encryptData = sm2.doEncrypt(msgString, publicKey, cipherMode)    // 加密結(jié)果
let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) // 解密結(jié)果

console.log("encryptData: ", encryptData)
console.log("decryptData: ", decryptData)

// encryptData:  ddf261103fae06d0efe20ea0fe0d82bcc170e8efd8eeae24e9559b3835993f0ed2acb8ba6782fc21941ee74ca453d77664a5cb7dbb91517e6a3b0c27db7ce587ae7af54f8df48d7fa822b7062e2af66c112aa57de94d12ba28e5ba96bf4439d299b41da4a5282d054696adc64156d248049d1eb1d0af28d76b542fe8a95d427e

// decryptData:  this is the data to be encrypted

SM2 簽名(sign)和校驗(verify):

const sm2 = require('sm-crypto').sm2

// 獲取密鑰對
let keypair = sm2.generateKeyPairHex()
let publicKey = keypair.publicKey   // 公鑰
let privateKey = keypair.privateKey // 私鑰

// 純簽名 + 生成橢圓曲線點
let msgString = "this is the data to be signed"
let sigValueHex = sm2.doSignature(msgString, privateKey)                    // 簽名
let verifyResult = sm2.doVerifySignature(msgString, sigValueHex, publicKey) // 驗簽結(jié)果

console.log("sigValueHex: ", sigValueHex)
console.log("verifyResult: ", verifyResult)

// sigValueHex:  924cbb9f2b5adb554ef77129ff1e3a00b2da42017ad3ec2f806d824a77646987ba8c8c4fb94576c38bc11ae69cc98ebbb40b5d47715171ec7dcea913dfc6ccc1

// verifyResult:  true

【04x03】其他語言實現(xiàn)以及參考資料

【05x00】附:GM/T 密碼行業(yè)標準

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末思犁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子进肯,更是在濱河造成了極大的恐慌激蹲,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件江掩,死亡現(xiàn)場離奇詭異学辱,居然都是意外死亡,警方通過查閱死者的電腦和手機环形,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門策泣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斟赚,你說我怎么就攤上這事着降。” “怎么了拗军?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵任洞,是天一觀的道長。 經(jīng)常有香客問我发侵,道長交掏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任刃鳄,我火速辦了婚禮盅弛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己挪鹏,他們只是感情好见秽,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著讨盒,像睡著了一般解取。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上返顺,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天禀苦,我揣著相機與錄音,去河邊找鬼遂鹊。 笑死振乏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的秉扑。 我是一名探鬼主播慧邮,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼邻储!你這毒婦竟也來了赋咽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吨娜,失蹤者是張志新(化名)和其女友劉穎脓匿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宦赠,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡陪毡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了勾扭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片毡琉。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖妙色,靈堂內(nèi)的尸體忽然破棺而出桅滋,到底是詐尸還是另有隱情,我是刑警寧澤身辨,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布丐谋,位于F島的核電站,受9級特大地震影響煌珊,放射性物質(zhì)發(fā)生泄漏号俐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一定庵、第九天 我趴在偏房一處隱蔽的房頂上張望吏饿。 院中可真熱鬧踪危,春花似錦、人聲如沸猪落。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽许布。三九已至兴革,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蜜唾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工庶艾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袁余,地道東北人。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓咱揍,卻偏偏與公主長得像颖榜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子煤裙,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容