日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AES对称加密

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AES对称加密 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

對稱加密(Symmetric Cryptography)

  • 對稱加密是最快速、最簡單的一種加密方式,加密(encryption)與解密(decryption)用的是同樣的密鑰(secret key)。
  • 對稱加密通常使用的是相對較小的密鑰,一般小于256 bit。因為密鑰越大,加密越強,但加密與解密的過程越慢。
  • 對稱加密的一大缺點是密鑰的管理與分配,換句話說,如何把密鑰發送到需要解密你的消息的人的手里是一個問題。在發送密鑰的過程中,密鑰有很大的風險會被黑客們攔截。現實中通常的做法是將對稱加密的密鑰進行非對稱加密,然后傳送給需要它的人。
  • 對稱加密,加密速度非常快,適合經常發送數據的場合。缺點是密鑰的傳輸比較麻煩。
  • 非對稱加密(Asymmetric Cryptography)

  • 非對稱加密為數據的加密與解密提供了一個非常安全的方法,它使用了一對密鑰,公鑰(public key)和私鑰(private key)。私鑰只能由一方安全保管,不能外泄,而公鑰則可以發給任何請求它的人。非對稱加密使用這對密鑰中的一個進行加密,而解密則需要另一個密鑰。
  • 非對稱算法,加密解密的速度比較慢,適合偶爾發送數據的場合。優點是密鑰傳輸方便。常見的非對稱加密算法為RSA、ECC和EIGamal
  • 相關概念

    分組:用來執行加密程序的內存空間有限。
    密鑰長度:128 bits、192 bits或256 bits。密鑰的長度不同,推薦加密輪數也不同。
    初始向量(IV):防止同樣的明文塊,始終加密成同樣的密文塊
    填充方式:密鑰只能對確定長度的數據塊進行處理,所以需要對最后一塊做額外處理,常用的模式有PKCS5, PKCS7, NOPADDING

    要想學習AES,首先要清楚三個基本的概念:密鑰填充模式

    秘鑰

    密鑰是AES算法實現加密和解密的根本

    • 對稱加密算法之所以對稱,是因為這類算法對明文的加密和解密需要使用同一個密鑰。

    AES支持三種長度的密鑰: 128位,192位,256位

    • 平時大家所說的AES128,AES192,AES256,實際上就是指AES算法對不同長度密鑰的使用。
      三種密鑰的區別:從安全性來看,AES256安全性最高。從性能看,AES128性能最高。本質原因是它們的加密處理輪數不同。

    填充

    要想了解填充的概念,我們先要了解AES的分組加密特性。

    什么是分組加密?

    如上圖所示,AES算法在對明文加密的時候,并不是把整個明文一股腦的加密成一整段密文,而是把明文拆分成一個個獨立的明文塊,每一個明文塊長度128bit。

    這些明文塊經過AES加密器復雜處理,生成一個個獨立的密文塊,這些密文塊拼接在一起,就是最終的AES加密的結果。

    但這里涉及到一個問題,假如一段明文長度是196bit,如果按每128bit一個明文塊來拆分的話,第二個明文塊只有64bit,不足128bit。這時候怎么辦呢?就需要對明文塊進行填充(Padding)。

    幾種典型的填充方式:

  • NoPadding:不做任何填充,但是要求明文必須是16字節的整數倍(一般不會使用)
  • PKCS5Padding(默認): 如果明文塊少于16個字節(128bit),在明文塊末尾補足相應數量的字符,且每個字節的值等于缺少的字符數。 比如明文:{1,2,3,4,5,a,b,c,d,e},缺少6個字節,則補全為{1,2,3,4,5,a,b,c,d,e,6,6,6,6,6,6}
  • ISO10126Padding:如果明文塊少于16個字節(128bit),在明文塊末尾補足相應數量的字節,最后一個字符值等于缺少的字符數,其他字符填充隨機數。比如明文:
    {1,2,3,4,5,a,b,c,d,e},缺少6個字節,則可能補全為
    {1,2,3,4,5,a,b,c,d,e,5,c,3,G,$,6}
  • PKCS7Padding:原理與PKCS5Padding相似,區別是PKCS5Padding的blocksize為8字節,而PKCS7Padding的blocksize可以為1到255字節
  • ANSIX9.23:跟ISO10126很像,只不過ANSI X9.23其他字節填的都是0而不是隨機數
  • 需要注意的是,如果在AES加密的時候使用了某一種填充方式,解密的時候也必須采用同樣的填充方式。

    工作模式

    AES的工作模式,體現在把明文塊加密成密文塊的處理過程中。
    AES加密算法提供了五種不同的工作模式: ECB、CBC、CFB、OFB、CTR

    AES加密算法 - 加密模式

  • 電碼本模式(Electronic Codebook Book (ECB))
  • 密碼分組鏈接模式(Cipher Block Chaining (CBC))
  • 密碼反饋模式(Cipher FeedBack (CFB))
  • 輸出反饋模式(Output FeedBack (OFB))
  • 計算器模式(Counter (CTR))
  • ECB

    最簡單的加密模式,明文消息被分成固定大小的塊(分組),并且每個塊被單獨加密。

    每個塊的加密和解密都是獨立的,且使用相同的方法進行加密,所以可以進行并行計算,但是這種方法一旦有一個塊被破解,使用相同的方法可以解密所有的明文數據,安全性比較差。

    適用于數據較少的情形,加密前需要把明文數據填充到塊大小的整倍數。

    優點:
    1.簡單
    2.有利于并行計算
    3.誤差不會被傳送
    缺點:
    1.不能隱藏明文的模式
    2.可能對明文進行主動攻擊

    CBC

    這種模式是先將明文切分成若干小段,然后每一小段與初始塊或者上一段的密文段進行異或運算后,再與密鑰進行加密。

    這樣每個密文塊依賴該塊之前的所有明文塊,為了保持每條消息都具有唯一性,第一個數據塊進行加密之前需要用初始化向量IV進行異或操作。

    CBC模式是一種最常用的加密模式,它主要缺點是加密是連續的,不能并行處理,并且與ECB一樣消息塊必須填充到塊大小的整倍數。

    優點:
    1.不容易主動攻擊,安全性好于ECB,適合傳輸長度長的報文,是SSL、IPSec的標準。
    缺點:
    1.不利于并行計算
    2.誤差傳遞
    3.需要初始化向量IV

    CFB

    和CBC模式比較相似,前一個分組的密文加密后和當前分組的明文XOR異或操作生成當前分組的密文。CFB模式的解密和CBC模式的加密在流程上其實是非常相似的。

    優點:
    1.隱藏了明文模式
    2.分組密碼轉化為流模式
    3.可以及時加密傳送小于分組的數據
    缺點:
    1.不利于并行計算
    2.誤差傳送:一個明文單元損壞影響多個單元
    3.唯一的IV

    OFB

    將分組密碼轉換為同步流密碼,也就是說可以根據明文長度先獨立生成相應長度的流密碼。通過流程圖可以看出,OFB和CFB非常相似,CFB是前一個分組的密文加密后XOR當前分組明文,OFB是前一個分組與前一個明文塊異或之前的流密碼XOR當前分組明文。由于異或操作的對稱性,OFB模式的解密和加密完全一樣的流程。

    優點:
    1.隱藏了明文模式
    2.分組密碼轉化為流模式
    3.可以及時加密傳送小于分組的數據
    缺點:
    1.不利于并行計算
    2.對明文的主動攻擊是可能的
    3.誤差傳送:一個明文單元損壞影響多個單元

    CTR

    對一系列輸入數據塊(稱為計數)進行加密,產生一系列的輸出塊,輸出塊與明文異或得到密文

    加密過程使用了密鑰、Nonce(類似IV)、Counter(一個從0到n的編號)

    最大的優勢是可以并行執行,因為所有的塊只依賴于Nonce與Counter,并不會依賴于前一個密文塊,可事先進行加解密準備,適合高速傳輸需求

    GCM工作模式

    CBC、CFB、OFB 三種模式可以解決 ECB 模式中相同明文生成相同密文的缺陷,CTR 又可以在此基礎上提供多分組并行加密特性,但是它們都不能提供密文消息完整性校驗功能,所有就有了 GCM 模式。

    微信支付成功回調通知使用了該模式

    完整性

    有的人可能會想到,如果將密文的hash值隨密文一起發送,接收者對收到的密文計算hash值,與收到的hash值進行比對,這樣是否就能校驗消息的完整性呢?

    但再仔細想想,就能發現這其中的漏洞。

    如果篡改者截獲原始密文后,先篡改密文,而后計算篡改后的密文hash,替換掉原始消息中的密文hash。這樣,接收者依舊沒有辦法發現對密文的篡改。

    可見,使用單向散列函數計算hash值仍然不能解決消息完整性校驗的問題。

    MAC消息驗證碼

    MAC:Message Authentication Code, 消息驗證碼

    消息驗證碼是一種與密鑰相關的單項散列函數。

    發送者使用密鑰和消息得到MAC值,接收者利用密鑰和收到的密文計算MAC值,與隨消息而來的MAC值做 比較,從而判斷消息是否被改過(完整性)。

    當篡改者篡改密文后,因為沒有密鑰,就無法計算篡改后的密文的MAC值。

    GMAC

    GMAC:Galois message authentication code mode, 伽羅瓦消息驗證碼

    對應到上圖中的消息認證碼,GMAC就是利用伽羅華域(Galois Field,GF,有限域)乘法運算來計算消息的MAC值。

    GCM

    GCM中的G 就是值GMAC,C就是指CTR。 所以GCM可以提供對消息的加密和完整性校驗。

    就像CTR模式下一樣,先對塊進行順序編號,然后將該塊編號與初始向量(IV)組合,并使用密鑰K,對輸入做AES加密,然后,將加密的結果與明文進行XOR運算來生成密文。像CTR模式下一樣,應該對每次加密使用不同的IV。對于附加消息,會使用密鑰H(由密鑰K得出),運行GMAC,將結果與密文進行XOR運算,從而生成可用于驗證數據完整性的身份驗證標簽。最后,密文接收者會收到一條完整的消息,包含密文、IV(計數器CTR的初始值)、身份驗證標簽(MAC值)。

    代碼示例

    /*** 密鑰長度:128位、192位、256位* 工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128* 填充方式:Nopadding/PKCS5Padding/ISO10126Padding/*/ public class AESUtils {private static final String KEY_ALGORITHM = "AES";private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默認的加密算法public static byte[] initSecretKey() throws NoSuchAlgorithmException {//返回生成指定算法密鑰生成器的 KeyGenerator 對象KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);//初始化此密鑰生成器,使其具有確定的密鑰大小//AES 要求密鑰長度為 256kg.init(256);//生成一個密鑰SecretKey secretKey = kg.generateKey();return secretKey.getEncoded();}private static Key toKey(byte[] key){//生成密鑰return new SecretKeySpec(key, KEY_ALGORITHM);}public static byte[] encrypt(byte[] data, Key key) throws Exception{return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);}public static byte[] decrypt(byte[] data, Key key) throws Exception{return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);}public static byte[] encrypt(byte[] data, byte[] key) throws Exception{return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);}public static byte[] decrypt(byte[] data, byte[] key) throws Exception{return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM);}public static byte[] encrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception{//還原密鑰Key k = toKey(key);return encrypt(data, k, cipherAlgorithm);}public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception{//實例化Cipher cipher = Cipher.getInstance(cipherAlgorithm);//使用密鑰初始化,設置為加密模式cipher.init(Cipher.ENCRYPT_MODE, key);//執行操作return cipher.doFinal(data);}public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception{//還原密鑰Key k = toKey(key);return decrypt(data, k, cipherAlgorithm);}public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception{//實例化Cipher cipher = Cipher.getInstance(cipherAlgorithm);//使用密鑰初始化,設置為解密模式cipher.init(Cipher.DECRYPT_MODE, key);//執行操作return cipher.doFinal(data);}private static String showByteArray(byte[] data){if(null == data){return null;}StringBuilder sb = new StringBuilder("{");for(byte b:data){sb.append(b).append(",");}sb.deleteCharAt(sb.length()-1);sb.append("}");return sb.toString();}public static void main(String[] args) throws Exception {byte[] key = initSecretKey();System.out.println("key字節數組:"+showByteArray(key));Key k = toKey(key); //生成秘鑰System.out.println("key base64編碼:" + Base64.getEncoder().encodeToString(key));System.out.println("key base64解碼:" + showByteArray(Base64.getDecoder().decode(Base64.getEncoder().encodeToString(key))));System.out.println();String data ="AES數據";System.out.println("加密前數據: string: "+data);System.out.println("加密前數據: byte[]: "+showByteArray(data.getBytes()));System.out.println();byte[] encryptData = encrypt(data.getBytes(), k);//數據加密System.out.println("加密后數據: byte[]: "+showByteArray(encryptData));String base64Data = Base64.getEncoder().encodeToString(encryptData);System.out.println("加密后數據: base64: " + base64Data); // System.out.println("加密后數據: hexStr:"+Hex.encodeHexStr(encryptData));System.out.println();byte[] decryptData = decrypt(Base64.getDecoder().decode(base64Data), k);//數據解密System.out.println("解密后數據: byte[]:"+showByteArray(decryptData));System.out.println("解密后數據: string:"+new String(decryptData));}}

    總結

    以上是生活随笔為你收集整理的AES对称加密的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。