• 最強加密算法?AES加解密算法Matlab和Verilog實現

    目錄

    • 背景

    • AES加密的幾種模式

    • 基本運算

    • AES加密原理

    • Matlab實現

    • Verilog實現

    • Testbench


    本文首發于公眾號【兩猿社】,重點講述了AES加密算法的加密模式和原理,用MATLAB和Verilog進行加解密的實現。

    美劇《硅谷》第六季居然已經完結了!小猿追了6年的劇就這么結束了,然而結局感覺并不那么喜劇。比爾·蓋茨和Twitter前CEO也在最后一集本色出演了。

    《硅谷》每一季的內容都緊跟當時科技前沿,最后一季也不例外,焦點聚集于信息安全。經過Richard升級之后的超級AI—Son of Anton2.0,因為能自動破解現存世界上任何一種加密算法,使得世界上再無隱私可言,而迫使Pied Piper宣布解散,至此全季終。劇中提到了一種加密算法:ECC P-256。

    ECC是橢圓曲線密碼學(Elliptic?Curve?Cryptography)的簡稱,而P-256是“P-256”橢圓曲線。

    聽上去挺唬人,這個P-256加密安全性怎么樣呢?

    早在2011年,美國國家標準技術研究院(NIST)審查了有關攻擊密碼算法的學術文獻,并對不同算法提供的實際安全性提出了建議。

    可以看到,P-256的安全性和AES-128等同。在同等密鑰長度密鑰條件下,AES的加密安全性超過Hash、RSA和ECC。

    AES加密究竟是個什么算法呢?

    廢話不多說,我們直接進入正題!

    (小猿盡可能用淺顯易懂的方式講解,但文中也不可避免的出現了一些公式和計算,篇幅較長,具有一定專業性。如果您僅想要獲取源碼,請直接跳到文末。)

    *ps:**關注公眾號【兩猿社】,回復【AES】可獲取Matlab和Verilog源碼,還有NIST FIPS原版AES spec哦!*


    背景

    隨著5G等高新技術的快速普及,大眾生活水平和認知的同步提高,信息安全逐漸引起普通受眾的重視。再加上硬件加密相比軟件加密的天生優勢,國內加密芯片也開始嶄露頭角,在IC行業中擁有了一席之位。

    AES?(Advanced Encryption Standard)是由NIST標準化的對稱分組密碼,是對稱加密事實上的標準(上文提到的ECC屬于非對稱加密)。由于上一代的DES算法密鑰長度小(56bits),容易被破解而被AES取代。可以發現,目前市面上幾乎所有的大型SOC芯片中,AES的身影必不可少。

    在AES中,數據塊固定128bits長度,加解密的密鑰長度有三種,分別是128bits,192bits和256bits。本文以AES-128bits為例講解。其他兩種密鑰長度在實現上僅是密鑰擴展和輪數的差別。

    AES分類

    將以32bits為一個字長進行分組,由于數據固有128bits,數據的分組長度Nb常為4,密鑰分組長度Nk分別為4(128bits)、6(192bits)和8(256bits)。

    AES加解密常見結構


    AES加密的幾種模式

    • ECB(Electronic Code Book)

    ECB是最簡單的塊密碼加密模式,加密前根據加密塊大小(如AES為128位)分成若干塊,將使用相同的密鑰和相同的算法對每個塊進行加密,解密同理。

    ECB模式

    ECB模式由于每塊數據的加密是獨立的,因此加密和解密都可以并行計算,ECB模式最大的缺點是加密相同的明文會得到相同的密文。


    • CBC(Cipher-block chaining)

    CBC模式對于每個待加密的密碼塊在加密前會先與前一個密碼塊的密文異或然后再用加密器加密。第一個明文塊與初始化向量(IV)異或,IV具有與加密塊相同的大小。通常,IV是隨機數,而不是定數。

    CBC模式

    明文分為多個塊,需要添加填充數據。首先,我們將對IV使用明文塊異或。然后,將結果經過AES核加密得到密文塊。在下一個塊中,將使用加密結果與明文塊進行異或,一直到最后一個塊。

    在這種模式下,即使加密相同的明文塊,也將獲得不同的密文塊。


    • CFB(Cipher feedback)

    與ECB和CBC模式只能夠加密塊數據不同,CFB能夠將塊密文(Block Cipher)轉換為流密文(Stream Cipher),它仍需要IV。

    CFB模式

    首先,需加密IV,將其與明文塊進行異或運算得到密文。然后將加密結果再加密,與明文進行異或。由于此模式不會直接加密明文,僅使用密文與明文進行異或運算以獲取密文。因此,在這種模式下,不需要填充數據。

    而且它可以并行解密數據。此模式類似于CBC,如果有壞塊,它將影響所有后續塊。


    • OFB(Output feedback)

    OFB是先用塊加密器生成密鑰流(Keystream),然后再將密鑰流與明文流異或得到密文流,解密是先用塊加密器生成密鑰流,再將密鑰流與密文流異或得到明文,由于異或操作的對稱性所以加密和解密的流程是完全一樣的。

    OFB模式

    它與CFB不同,它始終對IV進行加密。它不能并行加密/解密IV。


    • CTR(Counter)

    在CTR操作模式下,計數值作為加密器(Encrypt)的輸入塊,即為IV,計數器的值(Counter,Counter + 1,…,Counter + N – 1)被加密。它也是流加密器。

    CTR模式

    計數器的大小與所用塊的大小相同。如圖所示,將加密器的輸出塊與明文塊異或。所有加密塊都使用相同的加密密鑰。這種模式下,它不會受到壞塊的影響。非常像OFB模式。但是CTR每次都會使用計數器進行加密,而不是使用IV。因此,如果可以直接獲得計數器,則可以并行加密/解密數據。

    注:上文所提到的塊加密器即FIPS第197號文中所描述的 AES加密算法,即AES加密核。


    基本運算

    咳咳,好了,上面是什么玩意兒不管了,沒關系,讓我們重新開始學加法和乘法吧......

    行行行,你看一遍能懂算我輸。

    AES算法中,所涉及到的計算都是在有限域GF(\(2^8\))上的。

    GF(\(2^8\))域是由8位2進制數組成,其空間大小為256(00~ff),因此記為\(2^8\)

    在有限域中進行的加法運算和乘法運算不同于我們平常使用的基本算術運算,下面是它的幾個特點:

    1) 對于GF(\(2^8\))域來說,多項式的系數只可能是0或1。
    2) 合并同類項時,各系數進行的是沒有進位的二進制相加運算,與異或運算相同。
    3) GF(\(2^8\))域沒有減法運算,域中減法運算就等同于加法運算。


    • GF(\(2^8\))域加法

    單比特的相加實則是異或操作。
    1⊕1=0
    1⊕0=1
    0⊕0=0
    多比特相加則對應系數異或:


    • GF(\(2^8\))域乘法

    有限域GF(\(2^8\))上的乘法運算較為復雜,依然滿足分配律和結合律。

    GF(\(2^8\))域中的兩個多項式做乘法后,其最高次項會在0~14之間,需要對一個最高次項為8的固定不可約分多項式取模。

    在AES算法中運算都是以字節為單位的,其不可約分多項式固定為
    \[m(x)=x^8+x^4+x^3+x+1\]
    二進制形式表示為{0000001}{00011011},十六進制為{01}{1b}。

    取模運算后使最終結果的多項式x的最高次項不大于7,才能適應AES算法的字節運算要求。如果做乘法之后的最高次項不大于7,則不需要做取模運算。

    由于有限域中乘法運算符合交換律和分配律,多項式與任何數的乘法運算都可以分解為多個乘{02}與{01}后的有限域加法運算,與{02}的乘法運算可以用移位實現,與{01}的乘法運算結果則是其本身。

    AES算法中每個計算單位都是8位,乘法分解之后最高次項最大為\(x^8\)\(x^7\)?{02}),移位后的等效多項式如下:
    \[m(x)=b_7x^8+b_6x^7+b_5x^6+b_4x^5+b_3x^4+b_2x^3+b_1x^2+b_0x\]

    如果\(x^8\)項系數\(b_7\)為0,則證明結果無溢出;為1則證明結果溢出,需要與{01}{1b}取模運算。由于已經事先知道最高項為8次方項,與{01}取模后的結果為0。因此只用考慮與{1b}的取模運算,而最高次項此時最大為7次方,與{1b}的取模運算和異或操作等同。

    加法很簡單吧,你說什么,乘法看不懂?沒關系,接著往下看。


    AES加密原理

    AES-128bits加密算法中共有十輪迭代變換,每一輪迭代包含4個計算,分別是字節替換(SubBytes)、行移位(ShiftRows)、列混合(MixColumns)及輪密鑰加(AddRoundKey)。

    AES輪函數

    可以表示為:

    Round (State,RoundKey)
    {
        SubBytes   (state);
        ShiftRows  (state);
        MixColumns (state);
        AddRoundKey(state); 
    }

    • 加密步驟

    明文在輸入加密核之后,經過第一次輪密鑰加,開始輪函數的迭代,即依次通過字節替換,行移位,列混合和輪密鑰加運算;而在最后一輪即第十輪變換時,省去了列混合這一步驟。

    AES加解密流程

    解密的步驟剛好相反,順序不同。密文通過一次輪密鑰加之后,進入解密輪函數,依次是行移位,字節替換,輪密鑰加和列混合的逆運算(由于輪密鑰加為異或運算,其逆運算也是異或運算,所以它的逆運算不變),最后一輪同樣也沒有逆列混合。

    注意加密和解密所用的擴展后密鑰順序是相反的,且加解密的最后一個操作都是輪密鑰加,這樣可以防止攻擊者繞過密鑰而直接對系統進行攻擊,使算法具有很好的安全性。


    • 字節替換

    字節替換(SubBytes)是AES算法中惟一的非線性運算,使用替換表(S-Box)對矩陣中的每一個字節元素進行獨立運算。且s-box是可逆的。為了實現方便,使用S-Box替換的方式進行。verilog中使用查找表實現。

    S-box

    轉換方式為:假設輸入的字節為{\(a_7\) \(a_6\) \(a_5\) \(a_4\) \(a_3\) \(a_2\) \(a_1\) \(a_0\)}
    則經過S-Box之后的輸出值為S[\(a_7\) \(a_6\) \(a_5\) \(a_4\)][\(a_3\) \(a_2\) \(a_1\) \(a_0\)]

    例如:如輸入二進制字節為{10110100},十六進制為{B4},參照S-Box替換表替換后的值為S[B][4]=8D,再經過Inverse S-Box可得到替換前的值 =B4(AES解密中的逆變換會在下一篇講解)。

    字節替換流程


    • 行移位

    行移位(ShiftRows)是實現4×4矩陣內部字節的置換。

    行移位示意圖

    實際操作是:第零行不改動,將第一行每個字向左循環移1 byte,第二行每個字向左循環移2 byte,第三行每個字向左循環移3 byte。


    • 列混合

    列混合(MixColumns)是對GF(\(2^8\))域某些算術性質的等效,是狀態矩陣與域中一個固定多項式做乘法運算,然后與多項式(\(x^4+1\))取模,其中固定多項式a(x)為:
    \[a(x)=(03)x^3+(01)x^2+(01)x+(02)\]
    ()中的數為十六進制字節。則列混合表示為:
    \[s'(x)=a(x)?s(x)\]

    用矩陣乘法表示為:

    可以看出,固定矩陣的值由3個十六進制字節組成,即{01}、{02}、{03},列混合中的加法運算和乘法運算都是有限域中的算術運算。所以符合以下規則:

    1) 某個字節的值乘以{02},則是將該字節向左移1 bit,如果該字節最高位為1(移位后溢出),則要將乘2后的值異或{1b},二進制形式為{00011011};
    2) GF(\(2^8\))域中的乘法運算滿足分配律,例如:
    \[07?S_0,_0=(01⊕02⊕04)S_0,_0=S_0,_0⊕(02?S_0,_0)⊕(04?S_0,_0)\]

    列混合等效圖


    • 輪密鑰加

    輪密鑰加(AddRoundKey)的計算原理相對簡單,將輸入狀態矩陣中對應的元素與輸入的密鑰或者擴展后的密鑰相異或。

    輪密鑰加示意圖


    • 密鑰擴展

    密鑰擴展(KeyExpansion)是用輸入的128位(AES-128)密鑰做為初始密鑰,使用特定的計算方法產生新的擴展密鑰的操作。

    對AES-128來說,密鑰擴展共有10輪,每一輪產生4個32bits的子密鑰,一共產生10×4×32bits的子密鑰。

    密鑰擴展流程圖

    上圖(a)中,k矩陣為輸入的128bits初始密鑰,按每列4個字節的方式分為4個32bits的字,將這4個初始密鑰組合成的字\(w_1\)\(w_2\)\(w_3\)\(w_4\)作為加密時第一次輪密鑰加的輪密鑰。然后依次以下面的方法求出\(w_j\)

    1) 若j不為4的整數倍,則\(w_j\)由下式確定:
    \[w_j=w_j-_4⊕w_j-_1\]
    2) 若j為4的整數倍,則\(w_j\)由下式確定:
    \[w_j=w_j-_4⊕g(w_j-_1)\]

    \(g(w)\)函數如(b)所示,操作如下:

    1) 首先將w中的元素循環左移1 byte。
    2) 每個元素在S-Box進行替換。
    3) 與32bits常量{RC[j/4],00,00,00}異或,其中RC是一個固定的一維數組,RC值如下:RC={00,01,02,04,08,10,20,40,80,1B,36}

    ps:原本的RC值有10個(沒有RC[0]即00),而此處加上00是為了公式中表示數組時的便利。在g函數的運算過程中,由于j的值最小為4,j/4的值最小為1,所以不會產生影響。

    現在加密輪函數和密鑰擴展都已經知道了,那按照加密流程中一步步計算,即可得到加密后的密文。

    由于篇幅原因,本文只對加密原理進行講解,解密原理即逆運算原理如有需要會在后續更新,可關注后續文章。


    matlab實現

    AES Matlab仿真結果

    matlab驗證結果。(源碼獲取關注公眾號【兩猿圈】,回復【AES】)


    Verilog實現

    本設計為AES-128bits,輸入的128bits明文和初始密鑰,對明文(密文)進行十輪加解密之后輸出密文(明文)。

    • 模塊結構

    AES加密模塊結構

    該設計包含數據收發模塊、Sbox和Inv_Sbox模塊、密鑰擴展模塊以及加解密模塊。其中在加密模式下,由于每字節明文對應一個Sbox,則加密時需要16個Sbox(密鑰擴展在開始加密前就已經完成,所用的4個Sbox可復用),解密模式下需要16個Inv_Sbox和4個Sbox(密鑰擴展)。


    • 接口信號

    AES模塊接口信號

    考慮到AES-128模式下密鑰及明文或密文的寬度都是128bits,如果使用FPGA直接綜合,輸入和輸出至少需要384個IO口,因此為了節約IO口,本設計使用32bits寬度進行數據的傳輸。


    Testbench

    AES加密testbench結構

    Testbench結構包括發送模型send_model,接收模型receive_model,仿真模型即參考模型refer_model和自動對比模型auto_com。

    仿真結果

    呼,終于完了,現在你了解AES加密了嗎?


    關注公眾號【兩猿社】,微信號 : twomonkeysclub
    回復【AES】,獲取Matlab和Verilog源碼。
    在這里,我會分享互聯網、IC編程知識,以及一些有趣的想法和經歷。

    posted @ 2020-03-01 14:55  兩猿社  閱讀(...)  評論(...編輯  收藏
    贵州快三平台贵州快三主页贵州快三网站贵州快三官网贵州快三娱乐贵州快三开户贵州快三注册贵州快三是真的吗贵州快三登入贵州快三快三贵州快三时时彩贵州快三手机app下载贵州快三开奖 嘉祥县 | 确山县 | 多伦县 | 嵊州市 | 三都 | 宝应县 | 台南县 | 云阳县 | 朔州市 | 高州市 | 镶黄旗 | 南城县 | 德阳市 | 西乌 | 体育 | 互助 | 牟定县 | 青海省 | 苏尼特左旗 | 淮北市 | 淮安市 | 朔州市 | 焉耆 | 二连浩特市 | 辽宁省 | 台北市 | 江口县 | 彭泽县 | 介休市 | 威远县 | 金山区 | 当雄县 | 济宁市 | 安新县 | 衡东县 | 离岛区 | 长兴县 | 自贡市 | 喀什市 | 双鸭山市 | 南宁市 | 施秉县 | 铜川市 | 玉屏 | 曲水县 | 吴旗县 | 丁青县 | 贞丰县 | 揭东县 | 方城县 | 白城市 | 巴林右旗 | 阿克苏市 | 普兰县 | 光山县 | 石景山区 | 瓮安县 | 来安县 | 尖扎县 | 南陵县 | 金沙县 | 岢岚县 | 寿光市 | 疏附县 | 汾阳市 | 靖江市 | 高密市 | 子洲县 | 甘孜 | 泾川县 | 乐都县 | 庆阳市 | 普兰县 | 宜良县 | 澄迈县 | 潢川县 | 上虞市 | 新河县 | 盈江县 | 余江县 | 崇礼县 | 重庆市 | 罗源县 | 琼结县 | 济阳县 | 昂仁县 | 昆山市 | 揭阳市 | 金坛市 | 郧西县 | 泾阳县 | 竹北市 | 建平县 | 龙岩市 | 泰安市 | 嘉禾县 | 南川市 | 内江市 | 泸州市 | 新丰县 | 淮滨县 | 潜江市 | 金门县 | 木兰县 | 青龙 | 淮滨县 | 德惠市 | 和田县 | 随州市 | 文化 | 建始县 | 定州市 | 韶关市 | 尖扎县 | 长兴县 | 长寿区 | 宣武区 | 磐安县 | 汕头市 | 渭源县 | 永嘉县 | 章丘市 | 汉寿县 | 信宜市 | 高州市 | 长葛市 | 邵阳市 | 连城县 | 宝清县 | 白沙 | 佛山市 | 丰县 | 镇原县 | 冷水江市 | 和顺县 | 德江县 | 常州市 | 马关县 | 平湖市 | 重庆市 | 平顺县 | 开封县 | 临夏县 | 侯马市 | 嵊州市 | 旌德县 | 永州市 | 峨眉山市 | 崇文区 | 龙口市 | 江口县 | 泽州县 | 和龙市 | 定南县 | 新田县 | 平原县 | 繁昌县 | 潞城市 | 台南市 | 浦北县 | 临邑县 | 库尔勒市 | 靖西县 | 宜丰县 | 台南市 | 南城县 | 尉犁县 | 鄂伦春自治旗 | 六盘水市 | 彰武县 | 南昌县 | 湖南省 | 德阳市 | 定日县 | 玉门市 | 温宿县 | 深泽县 | 原平市 | 健康 | 和静县 | 延安市 | 丹棱县 | 济源市 | 松原市 | 扎兰屯市 | 合作市 | 田东县 | 岱山县 | 碌曲县 | 嘉禾县 | 岢岚县 | 武隆县 | 天镇县 | 远安县 | 古浪县 | 新昌县 | 大竹县 | 金塔县 | 迁西县 | 滁州市 | 秭归县 | 德保县 | 巫溪县 | 儋州市 | 玉环县 | 长白 | 洪湖市 |