Rijndael加密法

密碼學(xué)中的高級(jí)加密標(biāo)準(zhǔn)(Advanced Encryption Standard,AES)牢贸,又稱(chēng)Rijndael加密法竹观,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES潜索,已經(jīng)被多方分析且廣為全世界所使用臭增。經(jīng)過(guò)五年的甄選流程,高級(jí)加密標(biāo)準(zhǔn)由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院 (NIST)于2001年11月26日發(fā)布于FIPS PUB 197竹习,并在2002年5月26日成為有效的標(biāo)準(zhǔn)誊抛。2006年,高級(jí)加密標(biāo)準(zhǔn)已然成為對(duì)稱(chēng)密鑰加密中最流行的算法之一整陌。

該算法為比利時(shí)密碼學(xué)家Joan Daemen和Vincent Rijmen所設(shè)計(jì)拗窃,結(jié)合兩位作者的名字瞎领,以Rijndael之命名之,投稿高級(jí)加密標(biāo)準(zhǔn)的甄選流程随夸。(Rijdael的發(fā)音近于 “Rhinedoll”)

AES 是一個(gè)新的可以用于保護(hù)電子數(shù)據(jù)的加密算法九默。明確地說(shuō),AES 是一個(gè)迭代的宾毒、對(duì)稱(chēng)密鑰分組的密碼驼修,它可以使用128、192 和 256 位密鑰诈铛,并且用 128 位(16字節(jié))分組加密和解密數(shù)據(jù)乙各。與公共密鑰密碼使用密鑰對(duì)不同,對(duì)稱(chēng)密鑰密碼使用相同的密鑰加密和解密數(shù)據(jù)癌瘾。通過(guò)分組密碼返回的加密數(shù)據(jù)的位數(shù)與輸入數(shù)據(jù)相同觅丰。迭代加密使用一個(gè)循環(huán)結(jié)構(gòu),在該循環(huán)中重復(fù)置換(permutations )和替換(substitutions)輸入數(shù)據(jù)妨退。Figure 1 顯示了 AES 用192位密鑰對(duì)一個(gè)16位字節(jié)數(shù)據(jù)塊進(jìn)行加密和解密的情形妇萄。

對(duì)稱(chēng)密碼體制的發(fā)展趨勢(shì)將以分組密碼為重點(diǎn)。分組密碼算法通常由密鑰擴(kuò)展算法和加密(解密)算法兩部分組成咬荷。密鑰擴(kuò)展算法將b字節(jié)用戶主密鑰擴(kuò)展成r個(gè)子密鑰冠句。加密算法由一個(gè)密碼學(xué)上的弱函數(shù)f與r個(gè)子密鑰迭代r次組成⌒移梗混亂和密鑰擴(kuò)散是分組密碼算法設(shè)計(jì)的基本原則懦底。抵御已知明文的差分和線性攻擊,可變長(zhǎng)密鑰和分組是該體制的設(shè)計(jì)要點(diǎn)罕扎。

AES是美國(guó)國(guó)家標(biāo)準(zhǔn)技術(shù)研究所NIST旨在取代DES的21世紀(jì)的加密標(biāo)準(zhǔn)聚唐。

AES的基本要求是,采用對(duì)稱(chēng)分組密碼體制腔召,密鑰長(zhǎng)度的最少支持為128杆查、192、256臀蛛,分組長(zhǎng)度128位亲桦,算法應(yīng)易于各種硬件和軟件實(shí)現(xiàn)。1998年NIST開(kāi)始AES第一輪分析浊仆、測(cè)試和征集客峭,共產(chǎn)生了15個(gè)候選算法。1999年3月完成了第二輪AES2的分析抡柿、測(cè)試舔琅。2000年10月2日美國(guó)政府正式宣布選中比利時(shí)密碼學(xué)家Joan Daemen 和 Vincent Rijmen 提出的一種密碼算法RIJNDAEL 作為 AES.

AES加密數(shù)據(jù)塊大小最大是256bit,但是密鑰大小在理論上沒(méi)有上限沙绝。AES加密有很多輪的重復(fù)和變換搏明。大致步驟如下:

1. 密鑰擴(kuò)展(KeyExpansion)

2. 初始輪(Initial Round)

3. 重復(fù)輪(Rounds)鼠锈,每一輪又包括:SubBytes、ShiftRows星著、MixColumns购笆、AddRoundKey

4. 最終輪(Final Round),最終輪沒(méi)有MixColumns虚循。

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.KeyGenerator;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.SecretKey;

import javax.crypto.spec.SecretKeySpec;

import java.io.UnsupportedEncodingException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

public abstract class AesHelper {

? ? /**

? ? * 加密

? ? *

? ? * @param content 需要加密的內(nèi)容

? ? * @param salt? ? 加密密碼

? ? * @return

? ? */

? ? public static byte[] encrypt(String content, String salt) {

? ? ? ? try {

? ? ? ? ? ? SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

? ? ? ? ? ? random.setSeed(salt.getBytes());

? ? ? ? ? ? KeyGenerator kgen = KeyGenerator.getInstance("AES");

? ? ? ? ? ? kgen.init(128, random);

? ? ? ? ? ? SecretKey secretKey = kgen.generateKey();

? ? ? ? ? ? byte[] enCodeFormat = secretKey.getEncoded();

? ? ? ? ? ? SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

? ? ? ? ? ? Cipher cipher = Cipher.getInstance("AES");// 創(chuàng)建密碼器

? ? ? ? ? ? byte[] byteContent = content.getBytes("utf-8");

? ? ? ? ? ? cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化

? ? ? ? ? ? byte[] result = cipher.doFinal(byteContent);

? ? ? ? ? ? return result; // 加密

? ? ? ? } catch (NoSuchAlgorithmException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (NoSuchPaddingException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (InvalidKeyException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (UnsupportedEncodingException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (IllegalBlockSizeException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (BadPaddingException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? ? ? return null;

? ? }

? ? /**

? ? * 解密

? ? *

? ? * @param content 待解密內(nèi)容

? ? * @param salt? ? 解密密鑰

? ? * @return

? ? */

? ? public static byte[] decrypt(byte[] content, String salt) {

? ? ? ? try {

? ? ? ? ? ? KeyGenerator kgen = KeyGenerator.getInstance("AES");

? ? ? ? ? ? SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

? ? ? ? ? ? secureRandom.setSeed(salt.getBytes());

? ? ? ? ? ? kgen.init(128, secureRandom);

? ? ? ? ? ? SecretKey secretKey = kgen.generateKey();

? ? ? ? ? ? byte[] enCodeFormat = secretKey.getEncoded();

? ? ? ? ? ? SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");

? ? ? ? ? ? Cipher cipher = Cipher.getInstance("AES");// 創(chuàng)建密碼器

? ? ? ? ? ? cipher.init(Cipher.DECRYPT_MODE, key);// 初始化

? ? ? ? ? ? byte[] result = cipher.doFinal(content);

? ? ? ? ? ? return result; // 加密

? ? ? ? } catch (NoSuchAlgorithmException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (NoSuchPaddingException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (InvalidKeyException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (IllegalBlockSizeException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } catch (BadPaddingException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? ? ? return null;

? ? }

? ? public static String bytesToHexString(byte[] src) {

? ? ? ? StringBuffer sb = new StringBuffer();

? ? ? ? for (int i = 0; i < src.length; i++) {

? ? ? ? ? ? String hex = Integer.toHexString(src[i] & 0xFF);

? ? ? ? ? ? if (hex.length() == 1) {

? ? ? ? ? ? ? ? hex = '0' + hex;

? ? ? ? ? ? }

? ? ? ? ? ? sb.append(hex.toUpperCase());

? ? ? ? }

? ? ? ? return sb.toString();

? ? }

? ? public static String encryptToStr(String content, String password){

? ? ? ? return bytesToHexString(encrypt(content,password));

? ? }

? ? public static byte[] decrypt(String content, String keyWord) {

? ? ? ? return decrypt(hexStringToBytes(content), keyWord);

? ? }

? ? public static byte[] hexStringToBytes(String hexString) {

? ? ? ? if (hexString.length() < 1)

? ? ? ? ? ? return null;

? ? ? ? byte[] result = new byte[hexString.length() / 2];

? ? ? ? for (int i = 0; i < hexString.length() / 2; i++) {

? ? ? ? ? ? int high = Integer.parseInt(hexString.substring(i * 2, i * 2 + 1), 16);

? ? ? ? ? ? int low = Integer.parseInt(hexString.substring(i * 2 + 1, i * 2 + 2), 16);

? ? ? ? ? ? result[i] = (byte) (high * 16 + low);

? ? ? ? }

? ? ? ? return result;

? ? }

}

public class TestMain {

? ? public void main(){

? ? ? ? String content = "carl.zhao";

? ? ? ? String Key = "http://www.csdn.net";

? ? ? ? //加密

? ? ? ? String encryptResult = AesHelper.encryptToStr(content, Key);

? ? ? ? //解密

? ? ? ? byte[] decryptResult = AesHelper.decrypt(encryptResult,Key);

? ? ? ? Assert.assertEquals(content, new String(decryptResult));

? ? }

}

輸出結(jié)果:

@@eac7cf4369966a656d1355939632cab1611696f7aed973b20f13e8a0e08f1b2ae51d24b41678e12267cd7d8e549674b0fef081fbc0557ec7a7f1eb37bf28e4645a0f6863dae03c2278ea668b03b50102@@

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末同欠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子横缔,更是在濱河造成了極大的恐慌铺遂,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茎刚,死亡現(xiàn)場(chǎng)離奇詭異襟锐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)膛锭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)粮坞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人初狰,你說(shuō)我怎么就攤上這事莫杈。” “怎么了奢入?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵筝闹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我腥光,道長(zhǎng)关顷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任武福,我火速辦了婚禮解寝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艘儒。我一直安慰自己,他們只是感情好夫偶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布界睁。 她就那樣靜靜地躺著,像睡著了一般兵拢。 火紅的嫁衣襯著肌膚如雪翻斟。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,775評(píng)論 1 307
  • 那天说铃,我揣著相機(jī)與錄音访惜,去河邊找鬼嘹履。 笑死,一個(gè)胖子當(dāng)著我的面吹牛债热,可吹牛的內(nèi)容都是我干的砾嫉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼窒篱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼焕刮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起墙杯,我...
    開(kāi)封第一講書(shū)人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤配并,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后高镐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體溉旋,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年嫉髓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了观腊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岩喷,死狀恐怖恕沫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纱意,我是刑警寧澤婶溯,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站偷霉,受9級(jí)特大地震影響迄委,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜类少,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一叙身、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧硫狞,春花似錦信轿、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至泣侮,卻和暖如春即彪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背活尊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工隶校, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漏益,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓深胳,卻偏偏與公主長(zhǎng)得像绰疤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子稠屠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

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

  • 概述 之前一直對(duì)加密相關(guān)的算法知之甚少峦睡,只知道類(lèi)似DES、RSA等加密算法能對(duì)數(shù)據(jù)傳輸進(jìn)行加密权埠,且各種加密算法各有...
    Henryzhu閱讀 3,020評(píng)論 0 14
  • Base64.java public final class Base64 { static private ...
    BUG弄潮兒閱讀 799評(píng)論 0 0
  • 1. ASCII 編碼 ASCII(American Standard Code for Information ...
    s酸菜閱讀 8,692評(píng)論 0 8
  • 今天上午讓做一個(gè)ase的加密榨了,從網(wǎng)上找了好多都是支持windows的,在Linux下運(yùn)行時(shí)解密時(shí)攘蔽,總是出現(xiàn)報(bào)這個(gè)異...
    Easy的幸福閱讀 1,631評(píng)論 0 3
  • 目錄介紹 1.加密和解密1.1 問(wèn)答環(huán)節(jié)1.2 加解密概況 2.對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密2.1 什么是對(duì)稱(chēng)加密2.2 ...
    楊充211閱讀 795評(píng)論 0 6