全部加密
使用標准加密演算法(比如DES3)加密整個視頻流,其中,P是原始的多媒體數據,p0是經過壓縮或不壓縮的數據,C是使用加密演算法加密過的數據,K是加密密鑰。解密過程與加密過程相對陳,這種加密方法將視頻比特流視作傳統的文本數據,沒有利用視頻壓縮後數據的特殊結構。這種方法顯然計算量巨大,很難保證視頻的實時傳輸
選擇性加密
選擇性加密是基於信源特徵的視頻加密方法的主要發展方向。其加密模型如下圖所示。選擇性加密可分為加班的選擇性加密演算法、僅加密頭部信息的方法和SECMPEG比特流方法。
Zigzag置亂演算法
Zigzag置亂演算法的基本思想是使用一個隨機的置亂序列來代替Zigzag掃描順序,來將各個8*8塊的DCT系數映射成一個1*64矢量。
Zigzag置亂演算法速度很快,不影響視頻的實時傳輸。但是經過加密的視頻壓縮後碼流大下顯著增加。因為運用非Zigzag順序將8*8塊映射到1*64矢量,將會極大減少連續零的個數,從而減少壓縮率。視頻流大小經過加密後增加可達46%。考慮到MPEG視頻數據量的巨大,這種大小增量是很難容忍的。
改變Huffiman碼表演算法
改變Huffiman碼表的視頻加密演算法原理是:對於熵編碼採用Huffiman編碼的視頻標准,將通用Huffiman碼表修改後使用,修改後的特殊Huffiman碼表作為密鑰。非接收方無此特殊碼表,就無法正確解密視頻信息。該演算法完全不增加計算量。適用於使用Huffiman編碼的各種視頻和圖像壓縮編碼標准和演算法。其缺點是安全性較差。
純置亂演算法
純置亂演算法簡單的置亂位元組流。置亂密碼序列的基數是根據密級和應用需求動態可變的。比如我們可以用64個數的置亂序列或一個長的I幀的1/8的置亂序列。這種演算法的問題在於它對已知明文攻擊非常脆弱。一旦通過比較密文和已知原始幀數據,獲取了隨機置亂序列,所有的幀將很容易被破解。為了找出隨機置亂序列,我們需要已知隨機序列長度倍數大小的明文。然而注意到MPEG數據流的單一性和幀大小在同一個數量級上,因此,基於香農理論,如果已知一個I幀數據足以破譯整個隨機序列。
如果你要是加密視頻的話最簡單的方法其實是下載一個視頻加密軟體就可以了,比如超級加密3000、金鑽視頻加密專家都可以加密視頻的。
⑵ 加密技術02-對稱加密-AES原理
AES 全稱 Advanced Encryption Standard(高級加密標准)。它的出現主要是為了取代 DES 加密演算法的,因為 DES 演算法的密鑰長度是 56 位,因此演算法的理論安全強度是 2^56。但二十世紀中後期正是計算機飛速發展的階段,元器件製造工藝的進步使得計算機的處理能力越來越強,所以還是不能滿足人們對安全性的要求。於是 1997 年 1 月 2 號,美國國家標准技術研究所宣布希望徵集高級加密標准,用以取代 DES。AES 也得到了全世界很多密碼工作者的響應,先後有很多人提交了自己設計的演算法。最終有5個候選演算法進入最後一輪:Rijndael,Serpent,Twofish,RC6 和 MARS。最終經過安全性分析、軟硬體性能評估等嚴格的步驟,Rijndael 演算法獲勝。
AES 密碼與分組密碼 Rijndael 基本上完全一致,Rijndael 分組大小和密鑰大小都可以為 128 位、192 位和 256 位。然而 AES 只要求分組大小為 128 位,因此只有分組長度為 128 位的 Rijndael 才稱為 AES 演算法。本文只對分組大小 128 位,密鑰長度也為 128 位的 Rijndael 演算法進行分析。密鑰長度為 192 位和 256 位的處理方式和 128 位的處理方式類似,只不過密鑰長度每增加 64 位,演算法的循環次數就增加 2 輪,128 位循環 10 輪、192 位循環 12 輪、256 位循環 14 輪。
給定一個 128 位的明文和一個 128 位的密鑰,輸出一個 128 位的密文。這個密文可以用相同的密鑰解密。雖然 AES 一次只能加密 16 個位元組,但我們只需要把明文劃分成每 16 個位元組一組的塊,就可以實現任意長度明文的加密。如果明文長度不是 16 個位元組的倍數,則需要填充,目前填充方式主要是 PKCS7 / PKCS5。
下來主要分析 16 個位元組的加解密過程,下圖是 AES 演算法框架。
密鑰生成流程
G 函數
關於輪常量的生成下文會介紹。
主要作用:一是增加密鑰編排中的非線性;二是消除AES中的對稱性。這兩種屬性都是抵抗某些分組密碼攻擊必要的。
接下來詳細解釋一下幾個關鍵步驟。
明文矩陣和當前回次的子密鑰矩陣進行異或運算。
位元組代換層的主要功能是通過 S 盒完成一個位元組到另外一個位元組的映射。
依次遍歷 4 * 4 的明文矩陣 P 中元素,元素高四位值為行號,低四位值為列號,然後在 S 盒中取出對應的值。
行位移操作最為簡單,它是用來將輸入數據作為一個 4 * 4 的位元組矩陣進行處理的,然後將這個矩陣的位元組進行位置上的置換。ShiftRows 子層屬於 AES 手動的擴散層,目的是將單個位上的變換擴散到影響整個狀態當,從而達到雪崩效應。它之所以稱作行位移,是因為它只在 4 * 4 矩陣的行間進行操作,每行 4 位元組的數據。在加密時,保持矩陣的第一行不變,第二行向左移動 1 個位元組、第三行向左移動 2 個位元組、第四行向左移動 3 個位元組。
列混淆層是 AES 演算法中最為復雜的部分,屬於擴散層,列混淆操作是 AES 演算法中主要的擴散元素,它混淆了輸入矩陣的每一列,使輸入的每個位元組都會影響到 4 個輸出位元組。行位移層和列混淆層的組合使得經過三輪處理以後,矩陣的每個位元組都依賴於 16 個明文位元組成可能。其實質是在有限域 GF(2^8) 上的多項式乘法運算,也稱伽羅瓦域上的乘法。
伽羅瓦域
伽羅瓦域上的乘法在包括加/解密編碼和存儲編碼中經常使用,AES 演算法就使用了伽羅瓦域 GF(2^8) 中的運算。以 2^n 形式的伽羅瓦域來說,加減法都是異或運算,乘法相對較復雜一些,下面介紹 GF(2^n) 上有限域的乘法運算。
本原多項式: 域中不可約多項式,是不能夠進行因子分解的多項式,本原多項式是一種特殊的不可約多項式。當一個域上的本原多項式確定了,這個域上的運算也就確定了,本原多項式一般通過查表可得,同一個域往往有多個本原多項式。通過將域中的元素化為多項式的形式,可以將域上的乘法運算轉化為普通的多項式乘法模以本原多項式的計算。比如 g(x) = x^3+x+1 是 GF(2^3) 上的本原多項式,那麼 GF(2^3) 域上的元素 3*7 可以轉化為多項式乘法:
乘二運算: 無論是普通計算還是伽羅瓦域上運算,乘二計算是一種非常特殊的運算。普通計算在計算機上通過向高位的移位計算即可實現,伽羅瓦域上乘二也不復雜,一次移位和一次異或即可。從多項式的角度來看,伽羅瓦域上乘二對應的是一個多項式乘以 x,如果這個多項式最高指數沒有超過本原多項式最高指數,那麼相當於一次普通計算的乘二計算,如果結果最高指數等於本原多項式最高指數,那麼需要將除去本原多項式最高項的其他項和結果進行異或。
比如:GF(2^8)(g(x) = x^8 + x^4 + x^3 + x^2 + 1)上 15*15 = 85 計算過程。
15 寫成生成元指數和異或的形式 2^3 + 2^2 + 2^1 + 1,那麼:
乘二運算計算過程:
列混淆 :就是把兩個矩陣的相乘,裡面的運算,加法對應異或運算,乘法對應伽羅瓦域 GF(2^8) 上的乘法(本原多項式為:x^8 + x^4 + x^3 + x^1 + 1)。
Galois 函數為伽羅瓦域上的乘法。
解碼過程和 DES 解碼類似,也是一個逆過程。基本的數學原理也是:一個數進行兩次異或運算就能恢復,S ^ e ^ e = S。
密鑰加法層
通過異或的特性,再次異或就能恢復原數。
逆Shift Rows層
恢復 Shift Rows層 的移動。
逆Mix Column層
通過乘上正矩陣的逆矩陣進行矩陣恢復。
一個矩陣先乘上一個正矩陣,然後再乘上他的逆矩陣,相當於沒有操作。
逆位元組代換層
通過再次代換恢復位元組代換層的代換操作。
比如:0x00 位元組的置換過程
輪常量生成規則如下:
演算法原理和 AES128 一樣,只是每次加解密的數據和密鑰大小為 192 位和 256 位。加解密過程幾乎是一樣的,只是循環輪數增加,所以子密鑰個數也要增加,最後輪常量 RC 長度增加。
⑶ 用c語言設計一個簡單地加密算,解密演算法,並說明其中的原理
恰巧這兩天剛看的一種思路,很簡單的加密解密演算法,我說一下吧。
演算法原理很簡單,假設你的原密碼是A,用A與數B按位異或後得到C,C就是加密後的密碼,用C再與數B按位異或後能得回A。即(A異或B)異或B=A。用C實現很簡單的。
這就相當於,你用原密碼A和特定數字B產生加密密碼C,別人拿到這個加密的密碼C,如果不知道特定的數字B,他是無法解密得到原密碼A的。
對於密碼是數字的情況可以用下面的代碼:
#include <stdio.h>
#define BIRTHDAY 19880314
int main()
{
long a, b;
scanf("%ld", &a);
printf("原密碼:%ld\n", a);
b = BIRTHDAY;
a ^= b;
printf("加密密碼:%ld\n", a);
a ^= b; printf("解密密碼:%ld\n", a);
return 0;
}
如果密碼是字元串的話,最簡單的加密演算法就是對每個字元重新映射,只要加密解密雙方共同遵守同一個映射規則就行啦。
⑷ java最常用的幾種加密演算法
簡單的Java加密演算法有:
第一種. BASE
Base是網路上最常見的用於傳輸Bit位元組代碼的編碼方式之一,大家可以查看RFC~RFC,上面有MIME的詳細規范。Base編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就採用了Base來將一個較長的唯一標識符(一般為-bit的UUID)編碼為一個字元串,用作HTTP表單和HTTP GET URL中的參數。在其他應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。
第二種. MD
MD即Message-Digest Algorithm (信息-摘要演算法),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、哈希演算法),主流編程語言普遍已有MD實現。將數據(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD的前身有MD、MD和MD。
MD演算法具有以下特點:
壓縮性:任意長度的數據,算出的MD值長度都是固定的。
容易計算:從原數據計算出MD值很容易。
抗修改性:對原數據進行任何改動,哪怕只修改個位元組,所得到的MD值都有很大區別。
弱抗碰撞:已知原數據和其MD值,想找到一個具有相同MD值的數據(即偽造數據)是非常困難的。
強抗碰撞:想找到兩個不同的數據,使它們具有相同的MD值,是非常困難的。
MD的作用是讓大容量信息在用數字簽名軟體簽署私人密鑰前被」壓縮」成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進制數字串)。除了MD以外,其中比較有名的還有sha-、RIPEMD以及Haval等。
第三種.SHA
安全哈希演算法(Secure Hash Algorithm)主要適用於數字簽名標准(Digital Signature Standard DSS)裡面定義的數字簽名演算法(Digital Signature Algorithm DSA)。對於長度小於^位的消息,SHA會產生一個位的消息摘要。該演算法經過加密專家多年來的發展和改進已日益完善,並被廣泛使用。該演算法的思想是接收一段明文,然後以一種不可逆的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或信息),並把它們轉化為長度較短、位數固定的輸出序列即散列值(也稱為信息摘要或信息認證代碼)的過程。散列函數值可以說是對明文的一種「指紋」或是「摘要」所以對散列值的數字簽名就可以視為對此明文的數字簽名。
SHA-與MD的比較
因為二者均由MD導出,SHA-和MD彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同:
對強行攻擊的安全性:最顯著和最重要的區別是SHA-摘要比MD摘要長 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對MD是^數量級的操作,而對SHA-則是^數量級的操作。這樣,SHA-對強行攻擊有更大的強度。
對密碼分析的安全性:由於MD的設計,易受密碼分析的攻擊,SHA-顯得不易受這樣的攻擊。
速度:在相同的硬體上,SHA-的運行速度比MD慢。
第四種.HMAC
HMAC(Hash Message Authentication Code,散列消息鑒別碼,基於密鑰的Hash演算法的認證協議。消息鑒別碼實現鑒別的原理是,用公開函數和密鑰產生一個固定長度的值作為認證標識,用這個標識鑒別消息的完整性。使用一個密鑰生成一個固定大小的小數據塊,即MAC,並將其加入到消息中,然後傳輸。接收方利用與發送方共享的密鑰進行鑒別認證等。
⑸ 加密演算法518867對應0,518866對應1,518873對應10,請問這是什麼演算法
對於大部分密碼加密,我們可以採用md5、sha1等方法。可以有效防止數據泄露,但是這些方法僅適用於無需還原的數據加密。對於需要還原的信息,則需要採用可逆的加密解密演算法,下面一組PHP函數是實現此加密解密的方法
加密演算法如下: 代碼如下: function encrypt($data, $key) { $key = md5($key); $x = 0; $len = strlen($data); $l = strlen($key); for ($i = 0; $i < $len; $i++) { if ($x == $l) { $x = 0; } $char .= $key{$x}; $x++; } for ($i = 0; $i < $len; $i++) { $str .= chr(ord($data{$i}) + (ord($char{$i})) % 256); } return base64_encode($str); } 解密演算法如下: 代碼如下: function decrypt($data, $key) { $key = md5($key); $x = 0; $data = base64_decode($data); $len = strlen($data); $l = strlen($key); for ($i = 0; $i < $len; $i++) { if ($x == $l) { $x = 0; } $char .= substr($key, $x, 1); $x++; } for ($i = 0; $i < $len; $i++) { if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) { $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1))); } else { $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1))); } } return $str; } 上述加密解密的過程均需要用到一個加密密鑰(即參數$key)。 代碼如下: $data = 'PHP加密解密演算法'; // 被加密信息 $key = '123'; // 密鑰 $encrypt = encrypt($data, $key); $decrypt = decrypt($encrypt, $key); echo $encrypt, "n", $decrypt; 上述將輸出類似如下結果: 代碼如下: gniCSOzZG+HnS9zcFea7SefNGhXF PHP加密解密演算法 從上述結果可以看出,這是一組可逆的加密解密演算法,可以用於部分需要還原的數據加密。
⑹ 對稱加密演算法以及使用方法
加密的原因:保證數據安全
加密必備要素:1、明文/密文 2、秘鑰 3、演算法
秘鑰:在密碼學中是一個定長的字元串、需要根據加密演算法確定其長度
加密演算法解密演算法一般互逆、也可能相同
常用的兩種加密方式:
對稱加密:秘鑰:加密解密使用同一個密鑰、數據的機密性雙向保證、加密效率高、適合加密於大數據大文件、加密強度不高(相對於非對稱加密)
非對稱加密:秘鑰:加密解密使用的不同秘鑰、有兩個密鑰、需要使用密鑰生成演算法生成兩個秘鑰、數據的機密性只能單向加密、如果想解決這個問題、雙向都需要各自有一對秘鑰、加密效率低、加密強度高
公鑰:可以公開出來的密鑰、公鑰加密私鑰解密
私鑰:需要自己妥善保管、不能公開、私鑰加密公鑰解密
安全程度高:多次加密
按位異或運算
凱撒密碼:加密方式 通過將銘文所使用的字母表按照一定的字數平移來進行加密
mod:取余
加密三要素:明文/密文(字母)、秘鑰(3)、演算法(向右平移3/-3)
安全常識:不要使用自己研發的演算法、不要鑽牛角尖、沒必要研究底層實現、了解怎麼應用;低強度的密碼比不進行任何加密更危險;任何密碼都會被破解;密碼只是信息安全的一部分
保證數據的機密性、完整性、認證、不可否認性
計算機操作對象不是文字、而是由0或1排列而成的比特序列、程序存儲在磁碟是二進制的字元串、為比特序列、將現實的東西映射為比特序列的操作稱為編碼、加密又稱之為編碼、解密稱之為解碼、根據ASCII對照表找到對應的數字、轉換成二進制
三種對稱加密演算法:DES\3DES\ AES
DES:已經被破解、除了用它來解密以前的明文、不再使用
密鑰長度為56bit/8、為7byte、每隔7個bit會設置一個用於錯誤檢查的比特、因此實際上是64bit
分組密碼(以組為單位進行處理):加密時是按照一個單位進行加密(8個位元組/64bit為一組)、每一組結合秘鑰通過加密演算法得到密文、加密後的長度不變
3DES:三重DES為了增加DES的強度、將DES重復三次所得到的一種加密演算法 密鑰長度24byte、分成三份 加密--解密--加密 目的:為了兼容DES、秘鑰1秘鑰2相同==三個秘鑰相同 ---加密一次 密鑰1秘鑰3相同--加密三次 三個密鑰不相同最好、此時解密相當於加密、中間的一次解密是為了有三個密鑰相同的情況
此時的解密操作與加密操作互逆,安全、效率低
數據先解密後加密可以么?可以、解密相當於加密、加密解密說的是演算法
AES:(首選推薦)底層演算法為Rijndael 分組長度為128bit、密鑰長度為128bit到256bit范圍內就可以 但是在AES中、密鑰長度只有128bit\192bit\256bit 在go提供的介面中、只能是16位元組(128bit)、其他語言中秘鑰可以選擇
目前為止最安全的、效率高
底層演算法
分組密碼的模式:
按位異或、對數據進行位運算、先將數據轉換成二進制、按位異或操作符^、相同為真、不同為假、非0為假 按位異或一次為加密操作、按位異或兩次為解密操作:a和b按位異或一次、結果再和b按位異或
ECB : 如果明文有規律、加密後的密文有規律不安全、go里不提供該介面、明文分組分成固定大小的塊、如果最後一個分組不滿足分組長度、則需要補位
CBC:密碼鏈
問題:如何對字元串進行按位異或?解決了ECB的規律可查缺點、但是他不能並行處理、最後一個明文分組也需要填充 、初始化向量長度與分組長度相同
CFB:密文反饋模式
不需要填充最後一個分組、對密文進行加密
OFB:
不需要對最後一組進行填充
CTR計數器:
不需要對最後一組進行填充、不需要初始化向量
Go中的實現
官方文檔中:
在創建aes或者是des介面時都是調用如下的方法、返回的block為一個介面
func NewCipher(key [] byte ) ( cipher . Block , error )
type Block interface {
// 返回加密位元組塊的大小
BlockSize() int
// 加密src的第一塊數據並寫入dst,src和dst可指向同一內存地址
Encrypt(dst, src []byte)
// 解密src的第一塊數據並寫入dst,src和dst可指向同一內存地址
Decrypt(dst, src []byte)
}
Block介面代表一個使用特定密鑰的底層塊加/解密器。它提供了加密和解密獨立數據塊的能力。
Block的Encrypt/Decrypt也能進行加密、但是只能加密第一組、因為aes的密鑰長度為16、所以進行操作的第一組數據長度也是16
如果分組模式選擇的是cbc
func NewCBCEncrypter(b Block, iv []byte) BlockMode 加密
func NewCBCDecrypter(b Block, iv []byte) BlockMode 解密
加密解密都調用同一個方法CryptBlocks()
並且cbc分組模式都會遇到明文最後一個分組的補充、所以會用到加密位元組的大小
返回一個密碼分組鏈接模式的、底層用b加密的BlockMode介面,初始向量iv的長度必須等於b的塊尺寸。iv自己定義
返回的BlockMode同樣也是一個介面類型
type BlockMode interface {
// 返回加密位元組塊的大小
BlockSize() int
// 加密或解密連續的數據塊,src的尺寸必須是塊大小的整數倍,src和dst可指向同一內存地址
CryptBlocks(dst, src []byte)
}
BlockMode介面代表一個工作在塊模式(如CBC、ECB等)的加/解密器
返回的BlockMode其實是一個cbc的指針類型中的b和iv
# 加密流程:
1. 創建一個底層使用des/3des/aes的密碼介面 "crypto/des" func NewCipher(key []byte) (cipher.Block, error) # -- des func NewTripleDESCipher(key []byte) (cipher.Block, error) # -- 3des "crypto/aes" func NewCipher(key []byte) (cipher.Block, error) # == aes
2. 如果使用的是cbc/ecb分組模式需要對明文分組進行填充
3. 創建一個密碼分組模式的介面對象 - cbc func NewCBCEncrypter(b Block, iv []byte) BlockMode # 加密 - cfb func NewCFBEncrypter(block Block, iv []byte) Stream # 加密 - ofb - ctr
4. 加密, 得到密文
流程:
填充明文:
先求出最後一組中的位元組數、創建新切片、長度為新切片、值也為切片的長度、然後利用bytes.Reapet將長度換成位元組切片、追加到原明文中
//明文補充
func padPlaintText(plaintText []byte,blockSize int)[]byte{
//1、求出需要填充的個數
padNum := blockSize-len(plaintText) % blockSize
//2、對填充的個數進行操作、與原明文進行合並
newPadding := []byte{byte(padNum)}
newPlain := bytes.Repeat(newPadding,padNum)
plaintText = append(plaintText,newPlain...)
return plaintText
}
去掉填充數據:
拿去切片中的最後一個位元組、得到尾部填充的位元組個數、截取返回
//解密後的明文曲調補充的地方
func createPlaintText(plaintText []byte,blockSize int)[]byte{
//1、得到最後一個位元組、並將位元組轉換成數字、去掉明文中此數字大小的位元組
padNum := int(plaintText[len(plaintText)-1])
newPadding := plaintText[:len(plaintText)-padNum]
return newPadding
}
des加密:
1、創建一個底層使用des的密碼介面、參數為秘鑰、返回一個介面
2、對明文進行填充
3、創建一個cbc模式的介面、需要創建iv初始化向量、返回一個blockmode對象
4、加密、調用blockmode中的cryptBlock函數進行加密、參數為目標參數和源參數
//des利用分組模式cbc進行加密
func EncryptoText(plaintText []byte,key []byte)[]byte{
//1、創建des對象
cipherBlock,err := des.NewCipher(key)
if err != nil {
panic(err)
}
//2、對明文進行填充
newText := padPlaintText(plaintText,cipherBlock.BlockSize())
//3、選擇分組模式、其中向量的長度必須與分組長度相同
iv := make([]byte,cipherBlock.BlockSize())
blockMode := cipher.NewCBCEncrypter(cipherBlock,iv)
//4、加密
blockMode.CryptBlocks(newText,newText)
return newText
}
des解密:
1、創建一個底層使用des的密碼介面、參數為秘鑰、返回一個介面
2、創建一個cbc模式的介面、需要創建iv初始化向量,返回一個blockmode對象
3、加密、調用blockmode中的cryptBlock函數進行解密、參數為目標參數和源參數
4、調用去掉填充數據的方法
//des利用分組模式cbc進行解密
func DecryptoText(cipherText []byte, key []byte)[]byte{
//1、創建des對象
cipherBlock,err := des.NewCipher(key)
if err != nil {
panic(err)
}
//2、創建cbc分組模式介面
iv := []byte("12345678")
blockMode := cipher.NewCBCDecrypter(cipherBlock,iv)
//3、解密
blockMode.CryptBlocks(cipherText,cipherText)
//4、將解密後的數據進行去除填充的數據
newText := clearPlaintText(cipherText,cipherBlock.BlockSize())
return newText
}
Main函數調用
func main(){
//需要進行加密的明文
plaintText := []byte("CBC--密文沒有規律、經常使用的加密方式,最後一個分組需要填充,需要初始化向量" +
"(一個數組、數組的長度與明文分組相等、數據來源:負責加密的人提供,加解密使用的初始化向量必須相同)")
//密鑰Key的長度需要與分組長度相同、且加密解密的密鑰相同
key := []byte("1234abcd")
//調用加密函數
cipherText := EncryptoText(plaintText,key)
newPlaintText := DecryptoText(cipherText,key)
fmt.Println(string(newPlaintText))
}
AES加密解密相同、所以只需要調用一次方法就可以加密、調用兩次則解密
推薦是用分組模式:cbc、ctr
aes利用分組模式cbc進行加密
//對明文進行補充
func paddingPlaintText(plaintText []byte , blockSize int ) []byte {
//1、求出分組余數
padNum := blockSize - len(plaintText) % blockSize
//2、將余數轉換為位元組切片、然後利用bytes.Repeat得出有該余數的大小的位元組切片
padByte := bytes.Repeat([]byte{byte(padNum)},padNum)
//3、將補充的位元組切片添加到原明文中
plaintText = append(plaintText,padByte...)
return plaintText
}
//aes加密
func encryptionText(plaintText []byte, key []byte) []byte {
//1、創建aes對象
block,err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//2、明文補充
newText := paddingPlaintText(plaintText,block.BlockSize())
//3、創建cbc對象
iv := []byte("12345678abcdefgh")
blockMode := cipher.NewCBCEncrypter(block,iv)
//4、加密
blockMode.CryptBlocks(newText,newText)
return newText
}
//解密後的去尾
func clearplaintText(plaintText []byte, blockSize int) []byte {
//1、得到最後一個位元組、並轉換成整型數據
padNum := int(plaintText[len(plaintText)-1])
//2、截取明文位元組中去掉得到的整型數據之前的數據、此處出錯、沒有用len-padNum
newText := plaintText[:len(plaintText)-padNum]
return newText
}
//aes解密
func deCryptionText(crypherText []byte, key []byte ) []byte {
//1、創建aes對象
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//2、創建cbc對象
iv := []byte("12345678abcdefgh")
blockMode := cipher.NewCBCDecrypter(block,iv)
//3、解密
blockMode.CryptBlocks(crypherText,crypherText)
//4、去尾
newText := clearplaintText(crypherText,block.BlockSize())
return newText
}
func main(){
//需要進行加密的明文
plaintText := []byte("CBC--密文沒有規律、經常使用的加密方式,最後一個分組需要填充,需要初始化向量")
//密鑰Key的長度需要與分組長度相同、且加密解密的密鑰相同
key := []byte("12345678abcdefgh")
//調用加密函數
cipherText := encryptionText(plaintText,key)
//調用解密函數
newPlaintText := deCryptionText(cipherText,key)
fmt.Println("解密後",string(newPlaintText))
}
//aes--ctr加密
func encryptionCtrText(plaintText []byte, key []byte) []byte {
//1、創建aes對象
block,err := aes.NewCipher(key)
if err != nil {
panic(err)
}
//2、創建ctr對象,雖然ctr模式不需要iv,但是go中使用ctr時還是需要iv
iv := []byte("12345678abcdefgh")
stream := cipher.NewCTR(block,iv)
stream.XORKeyStream(plaintText,plaintText)
return plaintText
}
func main() {
//aes--ctr加密解密、調用兩次即為解密、因為加密解密函數相同stream.XORKeyStream
ctrcipherText := encryptionCtrText(plaintText, key)
ctrPlaintText := encryptionCtrText(ctrcipherText,key)
fmt.Println("aes解密後", string(ctrPlaintText))
}
英文單詞:
明文:plaintext 密文:ciphertext 填充:padding/fill 去掉clear 加密Encryption 解密Decryption
⑺ 簡述aes演算法的加密過程
AES加密過程涉及到 4 種操作,分別是位元組替代、行移位、列混淆和輪密鑰加。
1.位元組替換:位元組代替的主要功能是通過S盒完成一個位元組到另外一個位元組的映射。
2.行移位:行移位的功能是實現一個4x4矩陣內部位元組之間的置換。
4.輪密鑰加:加密過程中,每輪的輸入與輪密鑰異或一次(當前分組和擴展密鑰的一部分進行按位異或);因為二進制數連續異或一個數結果是不變的,所以在解密時再異或上該輪的密鑰即可恢復輸入。
5.密鑰擴展:其復雜性是確保演算法安全性的重要部分。當分組長度和密鑰長度都是128位時,AES的加密演算法共迭代10輪,需要10個子密鑰。AES的密鑰擴展的目的是將輸入的128位密鑰擴展成11個128位的子密鑰。AES的密鑰擴展演算法是以字為一個基本單位(一個字為4個位元組),剛好是密鑰矩陣的一列。因此4個字(128位)密鑰需要擴展成11個子密鑰,共44個字。