SM2國密算法公鑰解壓縮

SM2一般用到的或者第三方提供的公鑰都是壓縮過的,長度爲66個長度,既33字節。

格式如下,保密期間祕鑰內容用*代替了,從02到....3F3B共33字節。66個長度

06:028736002931F****************43986E66********D4FF11E9936A6CB9A3F3B
14:03017459D79C*****************88D6E6D********DDF979E40170F61308FAB
15:0286933F6EF6*****************C306FCD7545CEB4DDD214049001657D1C0DE
17:02D5795D52E******************48F282DCAD5EEF129ED2DF1D8FF806626FC0

但是封裝後的接口如:

int SM2_do_verify(unsigned char* message, int len, unsigned char* xA, unsigned char* yA, unsigned char* r, unsigned char* s)
那麼如何調用呢?

壓縮公鑰中,哪個是xA? 哪個是yA?  xA和yA不應該有32個字節嗎?怎麼提供的壓縮公鑰是33字節?

以下解答這些疑問。

前面的 06: ,17:爲公鑰的索引。且爲16機制的。 0x17 == 23

提供的33字節的壓縮公鑰,最面前的02和03不是公鑰的內容,因此排除第一個字節,後面的32字節纔是真正的壓縮公鑰。

壓縮公鑰如何解壓出xA和yA呢?其實xA沒有壓縮,排除前面的02或03,後面的32字節就是xA. yA是根據xA算出來的。

調用以下接口即可:

int SM2_get_Py(unsigned char y0, unsigned char Px[],unsigned char Py[])
 

這個y0參數傳啥?是個什麼意思?

y0代表公鑰y座標的最後一位。有兩個取值,是0還是1 。

如果公鑰X壓縮碼爲02,則這個取值傳0.如果公鑰X壓縮碼爲03,則這個值取1.

y0取0或取1涉及算法內部的一些翻轉操作,不能傳錯。

這樣調用key_get_y(&pubkeyX[1], 32, pubkeyY, 32, bc) 就獲取到了y座標公鑰啦。

其實y公鑰就是從X獲取到的。X是誰呢,就是那串壓縮公鑰,原封不動。

至於內部具體怎麼解壓的,看代碼,能看出點兒端倪。

SM2的曲線方程爲y2 = x3 + ax + b,其中知道了x當然就能求出y。這裏的x就是提供的壓縮公鑰。

r,s爲數字簽名(r, s),相當於這個公式裏的a和b吧。

只不過裏面涉及了大數運算,要不是有大數運算,應該很好理解吧。用上了大數運算,就得藉助openssl或miral大數庫了。

Function: SM2_get_Py
Description: SM2 public key decompress to get Py
Input: public key Px,y0(Py last right bit)
Output: pubKey y // pubKey=[priKey]G
Return: 0: sucess

int SM2_get_Py(unsigned char y0, unsigned char Px[],unsigned char Py[])
{
    big x_3;
    big x,y;
    big tmp;
    big y2;

    miracl *mip=mirsys(10000,16);
    mip->IOBASE=16;
    SM2_Init();
    x_3=mirvar(0);
    x=mirvar(0);
    y=mirvar(0);
    y2=mirvar(0);
    tmp=mirvar(0);

    bytes_to_big(SM2_NUMWORD,Px,x);
    //printf(x);

    power (x, 3, p, x_3); //x_3=x^3 mod p
    multiply (x, a,x); //x=a*x
    divide (x, p, tmp); //x=a*x mod p , tmp=a*x/p
    add(x_3,x,x); //x=x^3+ax
    add(x,b,x); //x=x^3+ax+b
    divide(x,p,tmp); //x=x^3+ax+b mod p

    if(!sqroot(x, p, y))
    { return 1; }
    big_to_bytes(SM2_NUMWORD,y,Py, TRUE);

    if( ( y0 & 0x01) != (Py[31] & 0x01) )
    {
        //y0 = 0;
        subtract(p, y, y2);
        big_to_bytes(SM2_NUMWORD,y2,Py, TRUE);
        printf("-----------------------------------------------------------------py key step 2\n");
    }
    
    return 0;
}

SM2對應RSA, SM4對應 AES或 3DES,SM3對應SHA或MD5哈希算法。

其實SM2 和3和4 功能和作用和RSA,3DES,SHA等是一樣的,只是實現了國產化替代。

SM1則貌似沒有公開或者要求只能由硬件實現,資料很少。算法安全保密強度及相關軟硬件實現性能與 AES 相當,該算法不公開,僅以 IP 核的形式存在於芯片中。

以下內容,摘自網絡,感興趣的可以瞭解下算法原理。

作者:島叔
鏈接:https://www.zhihu.com/question/290243441/answer/469697191
來源:知乎

在金融領域目前主要使用公開的SM2、SM3、SM4三類算法,分別是非對稱算法、哈希算法和對稱算法。

SM2算法:SM2橢圓曲線公鑰密碼算法是我國自主設計的公鑰密碼算法,包括SM2-1橢圓曲線數字簽名算法,SM2-2橢圓曲線密鑰交換協議,SM2-3橢圓曲線公鑰加密算法,分別用於實現數字簽名密鑰協商和數據加密等功能。SM2算法與RSA算法不同的是,SM2算法是基於橢圓曲線上點羣離散對數難題,相對於RSA算法,256位的SM2密碼強度已經比2048位的RSA密碼強度要高。

SM3算法:SM3雜湊算法是我國自主設計的密碼雜湊算法,適用於商用密碼應用中的數字簽名和驗證消息認證碼的生成與驗證以及隨機數的生成,可滿足多種密碼應用的安全需求。爲了保證雜湊算法的安全性,其產生的雜湊值的長度不應太短,例如MD5輸出128比特雜湊值,輸出長度太短,影響其安全性SHA-1算法的輸出長度爲160比特,SM3算法的輸出長度爲256比特,因此SM3算法的安全性要高於MD5算法和SHA-1算法。

SM4算法:SM4分組密碼算法是我國自主設計的分組對稱密碼算法,用於實現數據的加密/解密運算,以保證數據和信息的機密性。要保證一個對稱密碼算法的安全性的基本條件是其具備足夠的密鑰長度,SM4算法與AES算法具有相同的密鑰長度分組長度128比特,因此在安全性上高於3DES算法。

SM2、SM3及SM4加密標準

轉自:https://wenku.baidu.com/view/108aad77710abb68a98271fe910ef12d2bf9a945.html

  • 概述
  1. SM2橢圓曲線公鑰密碼算法加密標準

SM2算法就是ECC橢圓曲線密碼機制,但在簽名、密鑰交換方面不同於ECDSA、ECDH等國際標準,而是採取了更爲安全的機制。SM2-1橢圓曲線數字簽名算法,SM2-2橢圓曲線密鑰交換協議,SM2-3橢圓曲線公鑰加密算法,分別用於實現數字簽名密鑰協商和數據加密等功能。SM2算法與RSA算法不同的是,SM2算法是基於橢圓曲線上點羣離散對數難題,相對於RSA算法,256位的SM2密碼強度已經比2048位的RSA密碼強度要高。

橢圓曲線算法公鑰密碼所基於的曲線性質:橢圓曲線多倍點運算構成一個單向函數。在多倍點運算中,已知多倍點與基點,求解倍數的問題稱爲橢圓曲線離散對數問題。對於一般橢圓曲線的離散對數問題,目前只存在指數級計算複雜度的求解方法。與大數分解問題及有限域上離散對數問題相比,橢圓曲線離散對數問題的求解難度要大得多。因此,在相同安全程度要求下,橢圓曲線密碼較其他公鑰密碼所需的祕鑰規模要小得多。

  1. SM3哈希算法加密標準

SM3是一種密碼散列函數標準。密碼散列函數是散列函數的一種。它被認爲是一種單向函數,也就是說極其難以由散列函數輸出的結果,回推輸入的數據是什麼。這種散列函數的輸入數據,通常被稱爲消息,而它的輸出結果,經常被稱爲消息摘要。

SM3適用於商用密碼應用中的數字簽名和驗證消息認證碼的生成與驗證以及隨機數的生成,可滿足多種密碼應用的安全需求。爲了保證雜湊算法的安全性,其產生的雜湊值的長度不應太短,例如MD5輸出128比特雜湊值,輸出長度太短,影響其安全性SHA-1算法的輸出長度爲160比特,SM3算法的輸出長度爲256比特,因此SM3算法的安全性要高於MD5算法和SHA-1算法。

一個理想的密碼散列函數應該有這些特性:對於任何一個給定的消息,它都很容易就能運算出散列數值;難以由一個已知的散列數值,去推算出原始的消息;在不更動散列數值的前提下,修改消息內容是不可行的;對於兩個不同的消息,它不能給與相同的散列數值。

  1. SM4分組密碼算法加密標準

SM4算法是一個分組對稱密鑰算法,明文、密鑰、密文都是16字節,加密和解密密鑰相同。加密算法與密鑰擴展算法都採用32輪非線性迭代結構。解密過程與加密過程的結構相似,只是輪密鑰的使用順序相反。

SM4用於實現數據的加密/解密運算,以保證數據和信息的機密性。要保證一個對稱密碼算法的安全性的基本條件是其具備足夠的密鑰長度,SM4算法與AES算法具有相同的密鑰長度分組長度128比特,因此在安全性上高於3DES算法。

  • SM2加密標準
  1. SM2基本原理
  1. 基礎參數

SM2的曲線方程爲y2 = x3 + ax + b,其中:

  1. a: 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
  2. b: 0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
  3. c: 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
  4. 私鑰長度:32字節
  5. 公鑰長度:SM2非壓縮公鑰格式字節串長度爲65字節,壓縮格式長度爲33字節,若公鑰y座標最後一位爲0,則首字節爲0x02,否則爲0x03。非壓縮格式公鑰首字節爲0x04。
  6. 簽名長度:64字節
  1. 密鑰對生成

SM2密鑰生成是指生成SM2算法的密鑰對的過程,該密鑰對包括私鑰和與之對應的公鑰。

  1. 輸入:一個有效的Fq(q=p且p爲大於3的素數,或q=2m)上橢圓曲線系統參數的集合。
  2. 輸出:與橢圓曲線系統參數相關的一個密鑰對(d, P)

k: SM2PrivateKey,SM2私鑰

      Q: SM2PublicKey,SM2公鑰

     用隨機數發生器產生整數 d∈[1, n-2];

     G爲基點,計算點P=(xP, yP)=[d]G

     密鑰對是(d, P),其中d爲私鑰,P爲公鑰

  1. 簽名算法
  1. 預處理1

預處理1指使用簽名方的用戶身份標識和簽名方公鑰,通過運算得到Z值的過程,Z值用於預處理2。

  1. 輸入:ID 字符串,用戶身份標識;Q SM2PublicKey,用戶的公鑰。
  2. 輸出:Z 字節串,預處理1的輸出。
  3. 計算公式:Z=SM3(ENTL||ID||a||b||xG||yG||xA||yA)
  4. 參數說明:

ENTL: 由兩個字節標識的ID的比特長度;

ID: 用戶身份標識,一般情況下,其長度爲16字節,默認值從左至右依次是:0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38。

a, b: 爲系統曲線參數;

xG, yG爲基點;xA, yA爲用戶的公鑰。

  1. 預處理2

預處理2是指使用Z值和待簽名消息,通過SM3運算得到雜湊值H的過程。雜湊值H用戶SM2數字簽名。

  1. 輸入:Z 字節串;M 字節串,待簽名消息
  2. 輸出:H 字節串,雜湊值
  3. 計算公式:H=SM3(Z||M)
  1. 生成簽名

SM2簽名是指使用預處理2的結果和簽名者的私鑰,通過簽名計算得到簽名結果的過程。

  1. 輸入:d: SM2PrivateKey,簽名者私鑰;H 字節串,預處理2的結果
  2. 輸出:sign: SM2Signature,簽名值

設待簽名的消息爲M,爲了獲取消息M的數字簽名(r,s)(r,s)(r,s),作爲簽名者的用戶A應實現以下運算步驟:

置M’=ZA||M;計算e=Hv(M’),將e的數據類型轉化爲整數;用隨機數發生器產生隨機數k∈[1, n-1];計算橢圓曲線點(x1, y1)=[k]G,將x1的數據類型轉化爲整數;計算r=(e+x1)mod n,若r=0或r+k=n則返回第3步;計算s=((1+dA)-1*(k-r*dA))mod n,若s=0則返回第3步;將r, s轉化爲字節串。消息M的簽名爲(r, s)。

  1. 簽名驗證
  1. 輸入:H:字節串,預處理2的結果;sign:SM2Signature,簽名值;Q:PublicKey,簽名者的公鑰
  2. 輸出:爲真表示驗證通過,爲假表示驗證不通過。

爲了檢驗收到的消息 M及其數字簽名(r, s),作爲驗證者的用戶B應實現以下運算步驟:

  1. 檢驗r∈[1,n-1],是否成立,若不成立則驗證不通過;
  2. 檢驗s∈[1,n-1],是否成立,若不成立則驗證不通過;
  3. 置M’=ZA||M;
  4. 計算e=Hv(M’),將e的數據類型轉化爲整數;
  5. 將r,s的數據類型轉化爲整數,計算t=(r+s)mod n,若t=0,則驗證不通過;
  6. 計算橢圓曲線點(x1, y1)=[s]G+[t]PA;
  7. 將x1的數據類型轉化爲整數,計算R=(e+x1)mod n,檢驗R=r是否成立,若成立則驗證通過;否則驗證不通過。
  1. SM2的應用

SM2在固件安全中的應用:

固件控制着整個存儲系統的正常運行,倘若非法人員可以隨意導入固件、修改固件,那麼數據也將完全暴露,因此保護數據存儲安全的首要一點就是要確保固件在導入、保存和執行過程中的安全。

在固件導入過程中使用SM2算法進行驗籤,其中用到的公鑰保存在主控芯片內部,私鑰由受信用的固件廠商保存。對於要導入的固件,需要使用私鑰對其進行簽名,將簽名和固件一起導入到盤片,帶有簽名的固件下載到緩存RAM後,再用公鑰進行SM2驗籤。只有使用合法私鑰簽名的固件才能通過驗籤,成功導入,沒有簽名或者使用非法私鑰簽名的固件無法通過驗籤而被丟棄。如此,擁有合法私鑰的用戶才擁有固件的導入權限,從源頭上確保了盤片內部固件的合法性。

  1. 對比SM2與同類型算法

RSA算法數學原理簡單,在工程應用中比較易於實現,但它的單位安全強度相對較低。目前國際上公認的對於RSA算法最有效的攻擊方法,即一般數域篩方法去破譯和攻擊RSA算法,它的破譯或求解難度是亞指數級的。

SM2算法的數學理論非常深奧複雜,在工程應用中比較難於實現,但它的單位安全強度相對較高。用國際上公認的對於SM2算法最有效的攻擊方法Pollard rho去破譯攻擊SM2算法,它的破譯或求解難度基本上是指數級的。SM2算法的單位安全強度高於RSA算法。一般認爲當SM2密碼體制的密鑰長度爲160比特時,其安全性相當於RSA使用1024比特密鑰長度,密鑰短意味着更短的處理時間和密鑰存儲空間。

SM2具有安全性能更高、計算量小、處理速度快、存儲空間佔用小、帶寬要求低和便於密碼管理等優點,能在整體上提高加密過程中的速度與安全性。

  • SM3加密標準
  1. SM3基本原理

對長度爲l(l < 2^64) 比特的消息m, SM3雜湊算法經過填充和迭代壓縮,生成雜湊值,雜湊值長度爲256比特。

  1. 填充

假設消息m 的長度爲l 比特。首先將比特“1”添加到消息的末尾,再添加k 個“0”, k是滿足l + 1 + k ≡ 448mod512 的最小的非負整數。然後再添加一個64位比特串,該比特串是長度l的二進制表示。填充後的消息m的比特長度爲512的倍數。

  1. 迭代

將填充後的消息m按512比特進行分組:m’=B(0)B(1)…B(n-1),其中n=(l+k+65)/512。對m按下列方式迭代:

FOR i=0 TO n-1

V(i+1)=CF(V(i), B(i))

      ENDFOR

      其中CF是壓縮函數,V(0)爲256比特初始值IV,B(i)爲填充後的消息分組,迭代壓縮的結果爲V(n)

  1. 消息擴展

將消息分組B(i)按以下方法擴展生成132個字W0, W1,…, W67 , W0’, W1’, …, W63,用於壓縮函數CF

將消息分組B(i)劃分爲16個字W0, W1, …, W15

FOR j=16 TO 67

WjßP1(Wj-16⊕Wj-9⊕(Wj-3<<<15))⊕(Wj-13<<<7)⊕Wj-6

      ENDFOR

      FOR j=0 TO 63

          W’j=Wj⊕Wj+4

      ENDFOR

  1. 壓縮函數

令A,B,C,D,E,F,G,H爲字寄存器,SS1,SS2,TT1,TT2爲中間變量,壓縮函數Vi+1=CF(V(i), B(i)), 0<=i<=n-1,計算過程如下:

FOR j=0 TO 63

SS1ß((A<<<12)+E+(Tj<<<j))<<<7

SS2ßSS1⊕(A<<<12)

TT1ßFFj(A,B,C)+D+SS2+W’j

TT2ßGGj(E,F,G)+H+SS1+Wj

DßC

CßB<<<9

BßA

AßTT1

HßG

GßF<<<19

FßE

EßP0(TT2)

       ENDFOR

       V(i+1)ßABCDEFGH⊕V(i)

  1. 雜湊值

ABCDEFGHßV(n)

輸出256比特的雜湊值y=ABCDEFGH

  1. SM3的應用

SM3在芯片中的應用:

芯片中有sm3函數的入口,每次只能輸入8個字節(64位)的16進制數,所以要把文件拆分成N*8字節,並轉爲16進制,需要執行sm3函數N次

前面N-1次和最後一次執行函數所用的報文不同,前面N-1次中報文的p1=01(沒有返回雜湊值,但是函數中記錄下迭代中間結果,作爲下一次迭代輸入,不輸出),最後一次報文的p1=02,(結合上面迭代中間值,輸出最終雜湊值)。

  1. 對比SM3與同類型算法

摘要函數在密碼學中具有重要的地位,被廣泛應用在數字簽名,消息認證,數據完整性檢測等領域。摘要函數通常被認爲需要滿足三個基本特性:碰撞穩固性,原根穩固性和第二原根穩固性。2005年,Wang等人給出了MD5算法和SHA-1算法的碰撞攻擊方法,現今被廣泛應用的MD5算法和SHA-1算法不再是安全的算法。

SM3算法適用於商用密碼應用中的數字簽名和驗證,是在SHA-256基礎上改進實現的一種算法。SM3算法採用Merkle-Damgard結構,消息分組長度爲512位,摘要值長度爲256位。SM3算法的壓縮函數與SHA-256的壓縮函數具有相似的結構,但是SM3算法的設計更加複雜,比如壓縮函數的每一輪都使用2個消息字。SM3的安全性相對較高。

  • SM4加密標準
  1. SM4基本原理
  1. 參數產生

字節由8位二進制數表示,字由32位二進制數表示;S盒爲固定的8比特輸入和輸出置換;加密密鑰長度爲128bit,表示爲MK=(MK0,MK1,MK2,MK3),其中MKi (i=0,1,2,3)爲字。輪密鑰表示爲rki(i=0,1,2.....,31)爲字。FK=(FK0,FK1,FK2,FK3)爲系統參數,CK=(CK0,CK1,.....,CK31)爲固定參數,都爲字。

  1. 輪函數

整體的加密函數爲:

Xi+4=F(Xi, Xi+1, Xi+2, Xi+3, rki)=XiT(Xi+1Xi+2Xi+3⊕rki)

其中T爲一個合成置換,由非線性變換和線性變換複合而成。

  1. 非線性變換由4個平行的S盒構成,S盒的數據均採用16進制。
  2. 線性變換公式如下,其中B爲非線性變換得到的字

C=L(B)=B⊕(B<<2)⊕(B<<10)⊕(B<<18)⊕(B<<24)

  1. 密鑰擴展

已知加密密鑰MK=(MK0,MK1,MK2,MK3),系統參數FK=(FK0,FK1,FK2,FK3),固定參數CK=(CK0,CK1,.....,CK31)。rki爲輪密鑰,輪密鑰由加密密鑰生成。

首先(K0, K1, K2, K3)=(MK0FK0, MK1FK1, MK2FK2, MK3FK3),然後對i=0,1,2,…,31:rki=Ki+4=Ki⊕T’(Ki+1Ki+2Ki+3CKi),該變換與加密中的T變換基本相同,只是將其中的線性變換改爲:L’(B)=B(B<<13) ⊕(B<<23),由於系統參數個固定參數是已知的,輪密鑰即可求得。

  1. 加密解密過程

加密最後一輪變換時,輸出爲:

(Y0, Y1, Y2, Y3)=R(X32, X33, X34, X35)=(X35, X34, X33, X32)

 最後輸出是加密的反序,解密時只是將輪密鑰的使用順序進行逆向進行。

  1. SM4的應用

SM4在數據安全中的應用:

以固態硬盤爲例,若用戶數據的明文直接保存在存儲介質上,那麼只要拿到存儲數據的存儲介質,就能以一定的途徑獲取到其中存儲的用戶數據,比如換上其它的主控芯片、對存儲介質上的電平進行分析等。我們可以在數據讀寫路徑上加上一道門鎖——SM4加解密:數據由主機傳輸到緩存RAM的過程中,使用SM4 算法加密,寫入到緩存上的就是密文,並最終以密文的形式保存在存儲介質Flash上;讀取數據時再解密出明文返回給主機。

以上所述的加密過程對用戶是完全透明的,用戶完全感知不到加解密過程的存在。爲確保明文數據只對授權用戶可見,需要對加解密數據的密鑰——介質密鑰(MKey)進行保護,將其與授權用戶關聯起來。一種簡單的關聯方式如下圖所示,一方面使用SM3算法對用戶口令進行雜湊生成口令摘要,保存口令摘要用於身份鑑權;另一方面,對用戶口令進行派生構造加密密鑰(EKey),對介質密鑰進行加密保存。

  1. 對比SM4與同類型算法

國際的DES算法和國產的SM4算法的目的都是爲了加密保護靜態儲存和傳輸信道中的數據。從算法上看,國產SM4算法在計算過程中增加非線性變換,理論上能大大提高其算法的安全性,並且由專業機構進行了密碼分析,民間也對21輪SM4進行了差分密碼分析,安全性較高。

參考文獻

[1] 國密算法在數據存儲中的安全應用

[2] 國密標準文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章