AES-Java加密PHP解密

需求:在安卓客戶端中灭返,使用AES算法對字符串內(nèi)容加密并發(fā)送到后臺秩彤,后臺使用php對加密內(nèi)容進(jìn)行解密杨凑。

代碼

1刽宪、Java
先看AESUtil_0文件的getKey方法:

private static Key getKey(@NotNull String password) throws NoSuchAlgorithmException {
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 
    random.setSeed(password.getBytes()); 
    keyGenerator.init(128, random); 
    SecretKey secretKey = keyGenerator.generateKey(); 
    byte[] enKeyBytes = secretKey.getEncoded(); 
    return new SecretKeySpec(enKeyBytes, "AES");
}

對于AES算法,SecretKeySpec只能接受長度為16的byte數(shù)組诚卸。假如你的password的長度固定是16的葵第,可以直接

return new SecretKeySpec(password.getBytes(), "AES");

但是長度不是16時,會報InvalidKeyException錯誤合溺,因此在加密解密操作前卒密,需要先對password進(jìn)行處理。網(wǎng)上很多方法都是使用SHA1PRNG隨機算法棠赛,以password為種子哮奇,將長度設(shè)置成128位(1byte=8bit),生成一個長度為16的byte數(shù)組睛约。只要password一樣鼎俘,每次生成的數(shù)組都是一樣的,所以可以用來做加密解密的key辩涝。但是使用SHA1PRNG有一個問題贸伐,就是在php中沒有現(xiàn)成的方法實現(xiàn)。除非自己用php實現(xiàn)一個SHA1PRNG算法膀值,否則不能利用password生成同樣的key來解密內(nèi)容棍丐。因此最好換一種方法對password進(jìn)行處理。

現(xiàn)在看AESUtil_1文件:

/** 
* 生成salt, 用于對password進(jìn)行處理沧踏。 
* 加密和解密時用到的salt必須一致, 否則解密不了歌逢。 
*/
@Nullable
public static byte[] createSalt() {
    try {
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 
        byte[] salt = new byte[16]; 
        random.nextBytes(salt); 
        return salt;
     } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
     }
    return null;
}

private static Key getKey(@NotNull String password, @NotNull byte[] salt) 
        throws NoSuchAlgorithmException, InvalidKeySpecException {
    int iterations = 1000; 
    int keySize = 128; 
    PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, keySize); 
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    byte[] bytes = factory.generateSecret(spec).getEncoded(); 
    return new SecretKeySpec(bytes, "AES");
}

網(wǎng)上有人推薦PBKDF2算法,要使用這個算法翘狱,先要用SHA1PRNG算法生成一個隨機byte數(shù)組salt秘案,并利用salt對password處理得到加密解密的key。這樣做有個好處就是每次生成的key都是不一樣的潦匈,降低password被破解的風(fēng)險阱高,但是保存加密內(nèi)容的同時也要保存對應(yīng)的salt,因為解密時salt必須相同才能得到正確的內(nèi)容茬缩。

得到key之后赤惊,加密內(nèi)容的方法就比較簡單了:

/** 
* 加密方法 
*
* @param content 要被加密的內(nèi)容 
* @param password 密碼 
* @return 被加密后的內(nèi)容 
*/
@Nullablepublic static String encrypt(@NotNull String content, @NotNull String password, @NotNull byte[] salt) {
    try {
        Key key = getKey(password, salt); 
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 創(chuàng)建密碼器 
        byte[] contentBytes = content.getBytes("utf-8"); 
        cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化 
        byte[] result = cipher.doFinal(contentBytes); 
        return parseByte2HexStr(result); // 加密 
    } catch (Exception e) {
        e.printStackTrace(); 
    }
    return null;
}

得到加密的內(nèi)容后,為了方便凰锡,我把salt經(jīng)過parseByte2HexStr方法處理得到的字符串加在encrypt得到的字符串前面未舟,并一起發(fā)給后臺服務(wù)器圈暗。具體實現(xiàn)看java項目的main方法。

2裕膀、php
php解密比較簡單员串,在請求中拿到salt和加密內(nèi)容后調(diào)用Util::decrypt方法進(jìn)行解密。

<?php

class Util
{
    public static function parseHexStr2Str($hexStr)
    {
        $str = "";
        for ($i = 0, $size = strlen($hexStr) / 2; $i < $size; $i++) {
            $c = hexdec(substr($hexStr, $i * 2, 2));
            $str .= chr($c);
        }
        return $str;
    }

    public static function decrypt($content, $password, $salt)
    {
        // 這個方法得到的字符串類似于java工程中parseByte2HexStr(@NotNull byte buf[])得到的字符串; 
        // 數(shù)組buf的長度是16, 對應(yīng)等到的字符串長度為32, 因此這里第五個參數(shù)填32昼扛。 
        $hash = hash_pbkdf2("sha1", $password, $salt, 1000, 32);// 打開算法和模式對應(yīng)的模塊 
        $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
        $hex_iv = '00000000000000000000000000000000';
        mcrypt_generic_init($td, Util::parseHexStr2Str($hash), Util::parseHexStr2Str($hex_iv));
        $resultStr = mdecrypt_generic($td, $content);// 釋放加密模塊資源 
        
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);return $resultStr;
    }
}

define("PASSWORD", "12345678");
if (isset($_POST["content"])) {
    $content = $_POST["content"];// 前32位是salt 
    $salt = substr($content, 0, 32);echo "salt = " . $salt . "\n";// 剩余的是已加密的內(nèi)容 
    $enContent = substr($content, 32);
    echo "enContent = " . $enContent . "\n";

    $result = Util::decrypt(Util::parseHexStr2Str($enContent), PASSWORD, Util::parseHexStr2Str($salt));
    echo "result = " . $result . "\n";
} else {
    echo "沒有內(nèi)容";
}

參考:
http://blog.csdn.net/u012964281/article/details/40453873
http://stackoverflow.com/questions/31623866/java-aes-class-convert-to-php
http://stackoverflow.com/questions/31499222/unable-to-decrypt-string-in-android-app/31500093#31500093
http://stackoverflow.com/questions/19196728/aes-128-encryption-in-java-decryption-in-php

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寸齐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抄谐,更是在濱河造成了極大的恐慌渺鹦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛹含,死亡現(xiàn)場離奇詭異海铆,居然都是意外死亡,警方通過查閱死者的電腦和手機挣惰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來殴边,“玉大人憎茂,你說我怎么就攤上這事〈赴叮” “怎么了竖幔?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長是偷。 經(jīng)常有香客問我拳氢,道長,這世上最難降的妖魔是什么蛋铆? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任馋评,我火速辦了婚禮,結(jié)果婚禮上刺啦,老公的妹妹穿的比我還像新娘留特。我一直安慰自己,他們只是感情好玛瘸,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布蜕青。 她就那樣靜靜地躺著,像睡著了一般糊渊。 火紅的嫁衣襯著肌膚如雪右核。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天渺绒,我揣著相機與錄音贺喝,去河邊找鬼菱鸥。 笑死,一個胖子當(dāng)著我的面吹牛搜变,可吹牛的內(nèi)容都是我干的采缚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挠他,長吁一口氣:“原來是場噩夢啊……” “哼扳抽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起殖侵,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贸呢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拢军,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楞陷,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年茉唉,在試婚紗的時候發(fā)現(xiàn)自己被綠了固蛾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡度陆,死狀恐怖艾凯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懂傀,我是刑警寧澤趾诗,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站蹬蚁,受9級特大地震影響恃泪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜犀斋,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一贝乎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叽粹,春花似錦糕非、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至持钉,卻和暖如春衡招,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背每强。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工始腾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留州刽,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓浪箭,卻偏偏與公主長得像穗椅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奶栖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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