JAVA安全與加密

一. 隨機(jī)數(shù)

隨機(jī)算法的起源數(shù)字稱(chēng)為種子數(shù)(seed),在種子數(shù)的基礎(chǔ)上進(jìn)行一定的變換,從而產(chǎn)生需要的隨機(jī)數(shù)字朝聋。

Random類(lèi)中實(shí)現(xiàn)的隨機(jī)是偽隨機(jī)激蹲,也就是有規(guī)則的隨機(jī),因?yàn)樗姆N子是System.currentTimeMillis()谒臼,所以它的隨機(jī)數(shù)都是可預(yù)測(cè)的。相同種子數(shù)的Random對(duì)象,相同次數(shù)生成的隨機(jī)數(shù)字是完全相同的茴晋。所以在需要頻繁生成隨機(jī)數(shù),或者安全要求較高的時(shí)候回窘,不要使用Random诺擅。

SecureRandom類(lèi)提供加密的強(qiáng)隨機(jī)數(shù)生成器 (RNG)。當(dāng)然啡直,它的許多實(shí)現(xiàn)都是偽隨機(jī)數(shù)生成器 (PRNG) 形式烁涌,這意味著它們將使用確定的算法根據(jù)實(shí)際的隨機(jī)種子生成偽隨機(jī)序列,也有其他實(shí)現(xiàn)可以生成實(shí)際的隨機(jī)數(shù)酒觅,還有另一些實(shí)現(xiàn)則可能結(jié)合使用這兩項(xiàng)技術(shù)撮执。

SecureRandom和Random如果種子一樣,產(chǎn)生的隨機(jī)數(shù)也一樣: 因?yàn)榉N子確定舷丹,隨機(jī)數(shù)算法也確定二打,因此輸出是確定的。只是說(shuō)掂榔,SecureRandom類(lèi)收集了一些隨機(jī)事件继效,比如鼠標(biāo)點(diǎn)擊,鍵盤(pán)點(diǎn)擊等等装获,SecureRandom 使用這些隨機(jī)事件作為種子瑞信,因此種子是不可預(yù)測(cè)的,而不像Random默認(rèn)使用系統(tǒng)當(dāng)前時(shí)間的毫秒數(shù)作為種子穴豫,有規(guī)律可尋凡简。

1. 創(chuàng)建SecureRandom

內(nèi)置兩種隨機(jī)數(shù)算法逼友,NativePRNG和SHA1PRNG。

(1) new

通過(guò)new來(lái)初始化秤涩,默認(rèn)會(huì)使用NativePRNG算法生成隨機(jī)數(shù)帜乞。
SecureRandom secureRandom = new SecureRandom()

(2) getInstance

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG")//傳算法名,如果不存在算法會(huì)拋出異常

2. SecureRandom的使用

SecureRandom繼承自Random筐眷,所以也有nextInt之類(lèi)的方法黎烈。

  • nextBytes(byte[] bytes) void //獲取隨機(jī)的一個(gè)byte數(shù)組,傳入瓶子(產(chǎn)生的隨機(jī)數(shù)放入了入?yún)ytes)
  • generateSeed(int numBytes) byte[] //獲取一個(gè)隨機(jī)的byte數(shù)組匀谣,這個(gè)數(shù)組中的數(shù)通痴掌澹可以用來(lái)做其他隨機(jī)生成器的種子
  • SecureRandom.getSeed(int numBytes) byte[] //直接獲得隨機(jī)數(shù),本質(zhì)是包含了創(chuàng)建和使用兩步
  • setSeed(byte[] seed) void //設(shè)置種子數(shù)
  • nextInt(int bound) int //生成[0,bound)之間的隨機(jī)數(shù)

3. 實(shí)例

  /**
     * 生成一個(gè)隨機(jī)數(shù)矩陣
     *
     * @param num        行數(shù)
     * @param rowLen     列數(shù)
     * @param seedLength 種子數(shù)長(zhǎng)度
     * @author yaohuix
     * @time 2018/3/30 16:02
     */
    private List<List<Integer>> generateCakes(int num, int seedLength, int rowLen) {
        SecureRandom random = new SecureRandom();
        byte[] seeds = SecureRandom.getSeed(seedLength); //獲取隨機(jī)的byte數(shù)組武翎,用來(lái)后續(xù)作為種子
        int counter = 0;
        int tmprows = 0;
        List<List<Integer>> CakesList = new ArrayList<List<Integer>>();
        while (num > tmprows) {
            List<Integer> list = new ArrayList<Integer>();
            while (counter < rowLen) {
                random.setSeed(seeds); //設(shè)置種子
                int cake = random.nextInt(38); //隨機(jī)生成0-37的數(shù)字
                if (!list.contains(cake) && 0 != cake) {
                    list.add(cake);
                    counter++;
                }
                random.nextBytes(seeds); //隨機(jī)獲取新的byte數(shù)組用以作為下次的種子烈炭,不斷循環(huán)
            }
            Collections.sort(list);
            tmprows++;
            counter = 0;
            CakesList.add(list);
        }
        return CakesList;
    }

4. 關(guān)于種子seed獲取思路

產(chǎn)生高強(qiáng)度的隨機(jī)數(shù),有兩個(gè)重要的因素:種子和算法宝恶。當(dāng)然算法是可以有很多的符隙,但是如何選擇種子是非常關(guān)鍵的因素。那么如何得到一個(gè)近似隨機(jī)的種子垫毙?這里有一個(gè)思路:收集計(jì)算機(jī)的各種信息膏执,如鍵盤(pán)輸入時(shí)間,CPU時(shí)鐘露久,內(nèi)存使用狀態(tài),硬盤(pán)空閑空間欺栗,IO延時(shí)毫痕,進(jìn)程數(shù)量,線(xiàn)程數(shù)量等信息迟几,來(lái)得到一個(gè)近似隨機(jī)的種子消请。這樣的話(huà),除了理論上有破解的可能类腮,實(shí)際上基本沒(méi)有被破解的可能臊泰。而事實(shí)上,現(xiàn)在的高強(qiáng)度的隨機(jī)數(shù)生成器都是這樣實(shí)現(xiàn)的

二. 散列算法

散列是信息的提煉蚜枢,通常其長(zhǎng)度要比信息小得多缸逃,且為一個(gè)固定長(zhǎng)度。加密性強(qiáng)的散列一定是不可逆的厂抽,這就意味著通過(guò)散列結(jié)果需频,無(wú)法推出任何部分的原始信息。任何輸入信息的變化筷凤,哪怕僅一位昭殉,都將導(dǎo)致散列結(jié)果的明顯變化苞七,這稱(chēng)之為雪崩效應(yīng)。散列還應(yīng)該是防沖突的挪丢,即找不出具有相同散列結(jié)果的兩條信息蹂风。具有這些特性的散列結(jié)果就可以用于驗(yàn)證信息是否被修改

散列算法可以用來(lái)加密token生成簽名乾蓬, 以便token信息不暴露在網(wǎng)絡(luò)同時(shí)還能驗(yàn)證登錄的有效性惠啄。

1. MD5

全寫(xiě): Message Digest Algorithm MD5(消息摘要算法第五版)
輸出: 128bit

特點(diǎn)
a) 壓縮性:任意長(zhǎng)度的數(shù)據(jù),算出的MD5值長(zhǎng)度都是固定的巢块。
b) 容易計(jì)算:從原數(shù)據(jù)計(jì)算出MD5值很容易礁阁。
c) 抗修改性:對(duì)原數(shù)據(jù)進(jìn)行任何改動(dòng),哪怕只修改1個(gè)字節(jié)族奢,所得到的MD5值都有很大區(qū)別姥闭。
d) 弱抗碰撞:已知原數(shù)據(jù)和其MD5值,想找到一個(gè)具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的越走。
e) 強(qiáng)抗碰撞:想找到兩個(gè)不同的數(shù)據(jù)棚品,使它們具有相同的MD5值,是非常困難的廊敌。

缺陷
Md5一度被認(rèn)為十分靠譜铜跑。2009年,馮登國(guó)骡澈、謝濤二人利用差分攻擊锅纺,將MD5的碰撞算法復(fù)雜度降低到221,極端情況下甚至可以降低至210肋殴。僅僅2^21的復(fù)雜度意味著即便是在2008年的計(jì)算機(jī)上囤锉,也只要幾秒便可以找到一對(duì)碰撞。MD5已老护锤, 在安全性要求較高的場(chǎng)合官地,不建議使用。

應(yīng)用場(chǎng)景
一致性驗(yàn)證
數(shù)字簽名
安全訪(fǎng)問(wèn)認(rèn)證

(1) 算法實(shí)現(xiàn)
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(string.getBytes());

或者

InputStream in = new FileInputStream(file);
while ((len = in.read(buffer)) != -1) {
    md5.update(buffer, 0, len);
}
byte[] bytes = md5.digest();
(2) MD5加密安全性探討

雖然說(shuō)MD5加密本身是不可逆的烙懦,但并不是不可破譯的驱入,網(wǎng)上有關(guān)MD5解密的網(wǎng)站數(shù)不勝數(shù),破解機(jī)制采用窮舉法氯析,就是我們平時(shí)說(shuō)的跑字典亏较。所以如何才能加大MD5破解的難度呢?

i) 對(duì)字符串多次MD5加密
public static String md5(String string, int times) {
    if (TextUtils.isEmpty(string)) {
        return "";
    }
    String md5 = md5(string);
    for (int i = 0; i < times - 1; i++) {
        md5 = md5(md5);
    }
    return md5(md5);
}
ii) MD5加鹽

所謂加鹽掩缓, 就是在原本需要加密的信息基礎(chǔ)上宴杀,糅入其它內(nèi)容salt:string+key(鹽值key)然后進(jìn)行MD5加密,加鹽的方式也是多種多樣拾因。

  • 用string明文的hashcode作為鹽旺罢,然后進(jìn)行MD5加密
  • 隨機(jī)生成一串字符串作為鹽旷余,然后進(jìn)行MD5加密
public static String md5(String string, String slat) {
    if (TextUtils.isEmpty(string)) {
        return "";
    }
    MessageDigest md5 = null;
    try {
        md5 = MessageDigest.getInstance("MD5");
        byte[] bytes = md5.digest((string + slat).getBytes());
        String result = "";
        for (byte b : bytes) {
            String temp = Integer.toHexString(b & 0xff);
            if (temp.length() == 1) {
                temp = "0" + temp;
            }
            result += temp;
        }
        return result;
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "";
}

2. SHA1

全名:安全哈希算法(Secure Hash Algorithm)
輸出:160bit

(1) 與MD5比較

相同點(diǎn)
因?yàn)槎呔蒑D4導(dǎo)出,SHA-1和MD5彼此很相似扁达。相應(yīng)的正卧,他們的強(qiáng)度和其他特性也是相似。

不同點(diǎn)
a) 對(duì)強(qiáng)行攻擊的安全性:最顯著和最重要的區(qū)別是SHA-1摘要比MD5摘要長(zhǎng)32 位跪解。使用強(qiáng)行技術(shù)炉旷,產(chǎn)生任何一個(gè)報(bào)文使其摘要等于給定報(bào)摘要的難度對(duì)MD5是2128數(shù)量級(jí)的操作,而對(duì)SHA-1則是2160數(shù)量級(jí)的操作叉讥。這樣窘行,SHA-1對(duì)強(qiáng)行攻擊有更大的強(qiáng)度。
b) 對(duì)密碼分析的安全性:由于MD5的設(shè)計(jì)图仓,易受密碼分析的攻擊罐盔,SHA-1顯得不易受這樣的攻擊。
c) 速度:在相同的硬件上救崔,SHA-1的運(yùn)行速度比MD5慢惶看。

三. 對(duì)稱(chēng)加密

1. AES加密

高級(jí)加密標(biāo)準(zhǔn)(Advanced Encryption Standard,縮寫(xiě):AES)六孵,在密碼學(xué)中又稱(chēng)Rijndael加密法纬黎,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES劫窒,已經(jīng)被多方分析且廣為全世界所使用本今。

接下來(lái)我們來(lái)實(shí)際看下具體怎么實(shí)現(xiàn):

(1) 獲取密鑰生成器

KeyGenerator kg = KeyGenerator.getInstance("DESede")
分析:KeyGenerator類(lèi)中提供了創(chuàng)建對(duì)稱(chēng)密鑰的方法。getInstance(String algorithm)的參數(shù)指定加密算法的名稱(chēng)主巍,可以是 “AES”冠息、“DES”、“DESede”等煤禽。這些算法都可以實(shí)現(xiàn)加密。其中“DES”是目前最常用的對(duì)稱(chēng)加密算法岖赋,但安全性較差檬果。“AES”是一種替代DES算法的新算法唐断,可提供很好的安全性选脊。

(2) 初始化密鑰生成器

kg.init(168)init(int keysize, SecureRandom random)
分析:該步驟一般指定密鑰的長(zhǎng)度。如果該步驟省略的話(huà)脸甘,會(huì)根據(jù)算法自動(dòng)使用默認(rèn)的密鑰長(zhǎng)度恳啥。指定長(zhǎng)度時(shí),若第一步密鑰生成器使用的是“DES”算法丹诀,則密鑰長(zhǎng)度必須是56位钝的;若是“DESede”翁垂,則可以是112或168位,其中112位有效硝桩;若是“AES”沿猜,可以是128, 192或256位。

(3) 生成密鑰

SecretKey k = kg.generateKey( )
分析:使用第一步獲得的KeyGenerator類(lèi)型的對(duì)象中g(shù)enerateKey()方法可以獲得密鑰碗脊。其類(lèi)型為SecretKey類(lèi)型啼肩,可用于以后的加密和解密。

i) 通過(guò)對(duì)象序列化方式將密鑰保存在文件中
FileOutputStream  f = new FileOutputStream("key1.dat");
ObjectOutputStream b = new  ObjectOutputStream(f);
b.writeObject(k);

分析:ObjectOutputStream類(lèi)中提供的writeObject方法可以將對(duì)象序列化衙伶,以流的方式進(jìn)行處理祈坠。這里將文件輸出流作為參數(shù)傳遞給ObjectOutputStream類(lèi)的構(gòu)造器,這樣創(chuàng)建好的密鑰將保存在文件key1.dat中矢劲。

代碼與分析:

public static void main(String args[])
            throws Exception {
        KeyGenerator kg = KeyGenerator.getInstance("DESede");
        kg.init(168);
        SecretKey k = kg.generateKey();
        FileOutputStream f = new FileOutputStream("key1.dat");
        ObjectOutputStream b = new ObjectOutputStream(f);
        b.writeObject(k);
    }
ii) 以字節(jié)保存對(duì)稱(chēng)密鑰

★ 編程思路:
Java中所有的密鑰類(lèi)都有一個(gè)getEncoded( )方法赦拘,通過(guò)它可以從密鑰對(duì)象中獲取主要編碼格式,其返回值是字節(jié)數(shù)組卧须。其主要步驟為:

  • 獲取主要編碼格式
    byte[] kb=k.getEncoded()
    分析:執(zhí)行SecretKey類(lèi)型的對(duì)象k的getEncoded( )方法另绩,返回的編碼放在byte類(lèi)型的數(shù)組中。
  • 保存密鑰編碼格式
FileOutputStream  f2=new FileOutputStream("keykb1.dat");
f2.write(kb);
(4) 轉(zhuǎn)換為AES專(zhuān)用密鑰

SecretKeySpec secretKeyspec = new SecretKeySpec(secretKey.getEncoded(), "AES")

(5) 創(chuàng)建密碼器
//實(shí)例化
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
//使用密鑰初始化花嘶,設(shè)置為加密模式/解密模式(Cipher.DECRYPT_MODE)
cipher.init(Cipher.ENCRYPT_MODE, secretKeyspec);
(6) 加密/解密

byte[] doFinal(byte[] input)

實(shí)例:

    //Cipher密碼  encrypt加密 decrypt解密 crypto秘密
    private final static String HEX = "0123456789ABCDEF";
    //AES是加密方式 CBC是工作模式 PKCS5Padding是填充模式
    private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
    private static final String AES = "AES";//AES 加密
    private static final String SHA1PRNG = "SHA1PRNG";//// SHA1PRNG 強(qiáng)隨機(jī)種子算法, 要區(qū)別4.2以上版本的調(diào)用方法

    /*
     * 生成隨機(jī)數(shù)笋籽,可以當(dāng)做動(dòng)態(tài)的密鑰 加密和解密的密鑰必須一致,不然將不能解密
     */
    public static String generateKey() {
        try {
            SecureRandom localSecureRandom = SecureRandom.getInstance(SHA1PRNG);
            byte[] bytes_key = new byte[20];
            localSecureRandom.nextBytes(bytes_key);
            String str_key = toHex(bytes_key);
            return str_key;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 對(duì)密鑰進(jìn)行處理
    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance(AES);
        //for android
        SecureRandom sr = null;
        // 在4.2以上版本中椭员,SecureRandom獲取方式發(fā)生了改變
         if (android.os.Build.VERSION.SDK_INT >= 17) {
             sr = SecureRandom.getInstance(SHA1PRNG, "Crypto");
         } else {
            sr = SecureRandom.getInstance(SHA1PRNG);
         }
        // for Java
        // secureRandom = SecureRandom.getInstance(SHA1PRNG);
        sr.setSeed(seed);
        kgen.init(128, sr); //256 bits or 128 bits,192bits
        //AES中128位密鑰版本有10個(gè)加密循環(huán)车海,192比特密鑰版本有12個(gè)加密循環(huán),256比特密鑰版本則有14個(gè)加密循環(huán)隘击。
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }

    /*
     * 加密
     */
    public static String encrypt(String key, String cleartext) {
        if (TextUtils.isEmpty(cleartext)) {
            return cleartext;
        }
        try {
            byte[] result = encrypt(key, cleartext.getBytes());
            return Base64.encode(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
    * 加密
    */
    private static byte[] encrypt(String key, byte[] clear) throws Exception {
        byte[] raw = getRawKey(key.getBytes());
        SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
        Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
        byte[] encrypted = cipher.doFinal(clear);
        return encrypted;
    }

    /*
    * 解密
    */
    public static String decrypt(String key, String encrypted) {
        if (TextUtils.isEmpty(encrypted)) {
            return encrypted;
        }
        try {
            byte[] enc = Base64.decodeToBytes(encrypted);
            byte[] result = decrypt(key, enc);
            return new String(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     * 解密
     */
    private static byte[] decrypt(String key, byte[] encrypted) throws Exception {
        byte[] raw = getRawKey(key.getBytes());
        SecretKeySpec skeySpec = new SecretKeySpec(raw, AES);
        Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }


    //二進(jìn)制轉(zhuǎn)字符
    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }


    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末侍芝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子埋同,更是在濱河造成了極大的恐慌州叠,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凶赁,死亡現(xiàn)場(chǎng)離奇詭異咧栗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)虱肄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)致板,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人咏窿,你說(shuō)我怎么就攤上這事斟或。” “怎么了集嵌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵萝挤,是天一觀(guān)的道長(zhǎng)御毅。 經(jīng)常有香客問(wèn)我,道長(zhǎng)平斩,這世上最難降的妖魔是什么亚享? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮绘面,結(jié)果婚禮上欺税,老公的妹妹穿的比我還像新娘。我一直安慰自己揭璃,他們只是感情好晚凿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瘦馍,像睡著了一般歼秽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上情组,一...
    開(kāi)封第一講書(shū)人閱讀 48,954評(píng)論 1 283
  • 那天燥筷,我揣著相機(jī)與錄音,去河邊找鬼院崇。 笑死肆氓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的底瓣。 我是一名探鬼主播谢揪,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捐凭!你這毒婦竟也來(lái)了拨扶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤茁肠,失蹤者是張志新(化名)和其女友劉穎患民,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體垦梆,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匹颤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奶赔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惋嚎。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杠氢,死狀恐怖站刑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鼻百,我是刑警寧澤绞旅,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布摆尝,位于F島的核電站,受9級(jí)特大地震影響因悲,放射性物質(zhì)發(fā)生泄漏堕汞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一晃琳、第九天 我趴在偏房一處隱蔽的房頂上張望讯检。 院中可真熱鬧,春花似錦卫旱、人聲如沸人灼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)投放。三九已至,卻和暖如春适贸,著一層夾襖步出監(jiān)牢的瞬間灸芳,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工拜姿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烙样,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓砾隅,卻偏偏與公主長(zhǎng)得像误阻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晴埂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

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

  • 概述 之前一直對(duì)加密相關(guān)的算法知之甚少究反,只知道類(lèi)似DES、RSA等加密算法能對(duì)數(shù)據(jù)傳輸進(jìn)行加密儒洛,且各種加密算法各有...
    Henryzhu閱讀 3,008評(píng)論 0 14
  • 本文主要介紹移動(dòng)端的加解密算法的分類(lèi)精耐、其優(yōu)缺點(diǎn)特性及應(yīng)用,幫助讀者由淺入深地了解和選擇加解密算法琅锻。文中會(huì)包含算法的...
    蘋(píng)果粉閱讀 11,459評(píng)論 5 29
  • 又是一年生日卦停,第一次記得這么清晰。 23年了恼蓬,原來(lái)已經(jīng)過(guò)了22個(gè)生日了惊完,只是,這也只是一個(gè)模糊冰冷的數(shù)字处硬。 很久之...
    嵐風(fēng)的葉子閱讀 326評(píng)論 0 0
  • 如果不是我媽問(wèn)我吃了湯圓沒(méi)小槐,我不會(huì)太在意今天是元宵節(jié)。對(duì)于大多數(shù)上班的人來(lái)說(shuō),年凿跳,止于初七件豌。不知道是現(xiàn)在的人太忙了...
    龍江石閱讀 7,205評(píng)論 0 10
  • 濕身相遇 昨晚下雨了茧彤。 這本不是什么特別的事情,在這個(gè)多雨的季節(jié)里疆栏,在這座多雨的城市中曾掂,雨是再平常不過(guò)的事了。 然...
    靜諾閱讀 421評(píng)論 4 1