java 安全加密api(cipher钠乏,signature栖秕,mac...)

[TOC]

前言

本文主要講解常用加密算法,消息摘要晓避,二進(jìn)制字符變換等的java實(shí)現(xiàn)簇捍,對(duì)于加密算法本身的原理只會(huì)做簡(jiǎn)單的介紹,詳細(xì)的原理可百度俏拱。

相關(guān)概念

  • 加密

加密是指將可讀取的明文作為輸入暑塑,通過(guò)特定的變換操作得到不易讀取的輸出(通常是二進(jìn)制序列),目前常用的加密算法包括 對(duì)稱(chēng)加密的AES/DES,非對(duì)稱(chēng)加密的RSA/DSA/EC锅必,加密很重要的一點(diǎn)就是解密梯投,無(wú)論多復(fù)雜的數(shù)學(xué)變換,一定可以通過(guò)相應(yīng)的逆變換得到原始輸入,這是的加密行為才有意義分蓖。

  • hash(哈希變換)

hash值又稱(chēng)散列值或者消息摘要,對(duì)輸入的字符串或者二進(jìn)制序列通過(guò)一定的變換得到固定長(zhǎng)度的輸出,它是一個(gè)不可逆的過(guò)程尔许,理解這個(gè)不可逆的過(guò)程可以從數(shù)學(xué)中的求余函數(shù)理解么鹤,例如:11/10 = 1 ... 1余數(shù)是1,以除以10作為變換味廊,余數(shù)1作為輸出蒸甜,不可能通過(guò)余數(shù)是1得到被除數(shù)是11,因?yàn)橛锌赡苁?1余佛、31柠新、41。辉巡。恨憎。。郊楣。憔恳。等等,同時(shí)和求余類(lèi)似净蚤,hash碰撞指的就是不同的輸入可能得到相同的輸出钥组。當(dāng)然對(duì)于真正的hash變換,不可能像求余過(guò)程如此簡(jiǎn)單今瀑,但是這個(gè)不可逆過(guò)程的原理是類(lèi)似的程梦。常用的hash變換有MD5/SHA1/HmacSHA1/HmacMD5....等,hash變換的目的并不是讓輸入不可讀取,而是讓輸入不可改變橘荠。

  • 字節(jié)變換

文件通常會(huì)分為文本文件和二進(jìn)制文件屿附,文本文件通過(guò)(Unicode/UTF-8/ASCII)編碼之后是可以讀取的,而二進(jìn)制文件是不可讀的砾医,因?yàn)椴糠謹(jǐn)?shù)值沒(méi)有對(duì)應(yīng)的編碼拿撩。但是在開(kāi)發(fā)過(guò)程中,很多時(shí)候需要將不可讀的二進(jìn)制數(shù)據(jù)轉(zhuǎn)成可讀的字符串進(jìn)行傳輸如蚜,因此就有了字節(jié)變換操作压恒,常用的字節(jié)變換操作有Base64,UrlEncoder,還有通過(guò)將二進(jìn)制轉(zhuǎn)成十六進(jìn)制字符進(jìn)行變換错邦,在MD5和SHA1變換中常用探赫。字節(jié)變換最主要的目的是:將不易讀取或者不易傳輸?shù)臄?shù)據(jù)轉(zhuǎn)成易讀取或者易傳輸?shù)淖址?/strong>

相關(guān)api介紹

java中對(duì)于加密的支持api都在java.securityjavax.crypto包下,主要用到的類(lèi)有:

Cipher

主要用于加密行為撬呢,如進(jìn)行AES/DES/RSA等加密行為

  • 初始化對(duì)象static Cipher getInstance(String transformation)

transformation的組成可以概括為algorithm/mode/padding,algorithm用于指定加密的方式伦吠,mode用于指定特定加密方式的變換模式,padding是字節(jié)填充規(guī)則。modepadding可以不寫(xiě),可用的transformation組合有:

//括號(hào)數(shù)值為所需秘鑰的長(zhǎng)度
AES/CBC/NoPadding (128)
AES/CBC/PKCS5Padding (128)
AES/ECB/NoPadding (128)
AES/ECB/PKCS5Padding (128)
DES/CBC/NoPadding (56)
DES/CBC/PKCS5Padding (56)
DES/ECB/NoPadding (56)
DES/ECB/PKCS5Padding (56)
DESede/CBC/NoPadding (168)
DESede/CBC/PKCS5Padding (168)
DESede/ECB/NoPadding (168)
DESede/ECB/PKCS5Padding (168)
RSA/ECB/PKCS1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
  • 初始化參數(shù)void init(int opmode, Key key)

opmode用于指定該對(duì)象是要進(jìn)行加密還是解密毛仪,key是加密所用的秘鑰信息搁嗓。

  • 加密方法byte[] doFinal(byte[] input)

cipher.doFinal(byte[] input)等同于cipher.update(byte[] input); cipher.doFinal();

示例代碼:

  1. AES加解密
@org.junit.Test
public void testCipherAES() throws Exception {
    //指定使用AES加密
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    //使用KeyGenerator生成key,參數(shù)與獲取cipher對(duì)象的algorithm必須相同
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    //指定生成的密鑰長(zhǎng)度為128
    keyGenerator.init(128);
    Key key = keyGenerator.generateKey();
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] bytes = cipher.doFinal("helloworld".getBytes());
    System.out.println("AES加密: " + Base64.getEncoder().encodeToString(bytes));

    //由于AES加密在CBC模式下是需要有一個(gè)初始向量數(shù)組byte[] initializeVector ,
    // 而解密的時(shí)候也需要同樣的初始向量箱靴,因此需要使用加密時(shí)的參數(shù)初始化解密的cipher腺逛,否則會(huì)出錯(cuò)
    byte[] initializeVector = cipher.getIV();
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initializeVector);
    cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
    //上面三步操作可以用此操作代替   cipher.init(Cipher.DECRYPT_MODE, key, cipher.getParameters());
    bytes = cipher.doFinal(bytes);
    System.out.println("AES解密: " + new String(bytes));
}


//輸出
AES加密: pRy4ZbW7qgZ33iWBJ60BDA==
AES加密: helloworld
  1. DES加解密
@org.junit.Test
public void testCipherDES() throws Exception {
    //指定使用DES加密
    Cipher cipher = Cipher.getInstance("DES");
    //使用KeyGenerator生成key,參數(shù)與獲取cipher對(duì)象的algorithm必須相同
    KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
    //DES的秘鑰長(zhǎng)度必須是56位
    keyGenerator.init(56);
    Key key = keyGenerator.generateKey();
    cipher.init(Cipher.ENCRYPT_MODE, key);
    byte[] bytes = cipher.doFinal("helloworld".getBytes());
    System.out.println("DES加密: " + Base64.getEncoder().encodeToString(bytes));
    //與AES不同衡怀,由于DES并不需要初始向量棍矛,因此解密的時(shí)候不需要第三個(gè)參數(shù)
    cipher.init(Cipher.DECRYPT_MODE, key);
    bytes = cipher.doFinal(bytes);
    System.out.println("DES解密: " + new String(bytes));
}

//輸出
DES加密: XoG4lEjZN4VBlZYTXjw6BQ==
DES解密: helloworld
  1. RSA加解密
@org.junit.Test
public void testCipherRSA() throws Exception {
    //獲取cipher對(duì)象
    Cipher cipher = Cipher.getInstance("RSA");
    //通過(guò)KeyPairGenerator來(lái)生成公鑰和私鑰
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();

    PublicKey publicKey = keyPair.getPublic();//公鑰
    PrivateKey privateKey = keyPair.getPrivate();//私鑰

    /*加密*/
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] bytes = cipher.doFinal(TEXT.getBytes());
    final String encryptText = Base64.getEncoder().encodeToString(bytes);
    System.out.println("RSA公鑰加密:" + encryptText);

    /*解密*/
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    bytes = cipher.doFinal(Base64.getDecoder().decode(encryptText));
    System.out.println("RSA解密:" + new String(bytes));
}

//輸出
RSA公鑰加密:bKbbpARpcHcCqcMdGmA/WzvyO2G3eXFJhmrK5F0yFlJsoGohg4XIq5egNc1eBQwP7BRD6m7c12byB/KpYNgWg7J5Y3kupWBahZyhJ7SWWF0YY9CrdWf55zQ/CPyn+KlWQg1ViBnIBnejABFuqjDgBmZ3Q3txT1tD4MIpGPCE+NY=
RSA私鑰解密:helloworld

Mac

該類(lèi)主要用作Hmac運(yùn)算,初始化方法Mac.getInstance(String algorithm)的可用參數(shù)有

HmacMD5
HmacSHA1
HmacSHA224
HmacSHA256
HmacSHA384
HmacSHA512

示例代碼

@org.junit.Test
public void testHmac() throws Exception {
    Mac mac = Mac.getInstance("HmacMD5");
    //第一個(gè)參數(shù)可以是任意字符串,第二個(gè)參數(shù)與獲取Mac對(duì)象的algorithm相同
    SecretKeySpec secretKeySpec = new SecretKeySpec("123456".getBytes(), "HmacMD5");
    mac.init(secretKeySpec);
    byte[] bytes = mac.doFinal("helloworld".getBytes());
    System.out.println("HmacMD5結(jié)果:" + HexUtil.toHexString(bytes));

    mac = Mac.getInstance("HmacSHA1");
    mac.init(new SecretKeySpec("123456".getBytes(), "HmacSHA1"));
    bytes = mac.doFinal("helloworld".getBytes());
    System.out.println("HmacSHA1結(jié)果:" + HexUtil.toHexString(bytes));
}

//輸出
HmacMD5結(jié)果:2449233556af565ecbb2fd6266df853b
HmacSHA1結(jié)果:ef9079b9e2e79c67a962f87e2a87af4f35c2ae37

Signature

signature類(lèi)用于提供數(shù)字簽名,用于保證數(shù)據(jù)的完整性
示例代碼,Signature.getInstance(String algorithm)的可用參數(shù)有

NONEwithRSA
MD2withRSA
MD5withRSA
SHA1withRSA
SHA224withRSA
SHA256withRSA
SHA384withRSA
SHA512withRSA
NONEwithDSA
SHA1withDSA
SHA224withDSA
SHA256withDSA
NONEwithECDSA
SHA1withECDSA
SHA224withECDSA 
SHA256withECDSA
SHA384withECDSA
SHA512withECDSA

示例代碼:

@org.junit.Test
public void testSignature() throws Exception {
   
    Signature signature = Signature.getInstance("NONEwithRSA");

    //KeyPairGenerator生成公鑰和私鑰
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();

    PublicKey publicKey = keyPair.getPublic();
    PrivateKey privateKey = keyPair.getPrivate();

    //用私鑰初始化signature
    signature.initSign(privateKey);
    //更新原始字符串
    signature.update(TEXT.getBytes());
    byte[] bytes = signature.sign();
    String sign = Base64.getEncoder().encodeToString(bytes);
    System.out.println("數(shù)字簽名: " + sign);


    //用公鑰初始化signature
    signature.initVerify(publicKey);
    //更新原始字符串
    signature.update(TEXT.getBytes());
    //校驗(yàn)簽名是否正確
    boolean result = signature.verify(Base64.getDecoder().decode(sign));

    System.out.println("簽名校驗(yàn)結(jié)果: " + result);
}

MessageDigest

MessageDigest主要是做hash變換(也稱(chēng)消息摘要或者散列值)

示例代碼:

 @org.junit.Test
public void testMessageDigest() throws Exception {
    //參數(shù)可以是 MD5,MD2,MD5,SHA-1,SHA-224,SHA-256,SHA-384,SHA-512
    MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    byte[] bytes = messageDigest.digest("helloworld".getBytes());
    //將二進(jìn)制數(shù)組轉(zhuǎn)成16進(jìn)制字符串輸出
    System.out.println("MD5哈希變換:" + HexUtil.toHexString(bytes));


    messageDigest = MessageDigest.getInstance("SHA-1");
    bytes = messageDigest.digest("helloworld".getBytes());
    System.out.println("SHA1哈希變換:" + HexUtil.toHexString(bytes));
}

//HexUtil
public static String toHexString(byte[] data) {
    StringBuilder builder = new StringBuilder();
    int len = data.length;
    String hex;
    for (int i = 0; i < len; i++) {
        hex = Integer.toHexString(data[i] & 0xFF);
        if (hex.length() == 1) {
            builder.append("0");
        }
        builder.append(hex);
    }
    return builder.toString();
}


//輸出 可以通過(guò)標(biāo)準(zhǔn)在線(xiàn)工具檢驗(yàn)輸出結(jié)果的準(zhǔn)確性
MD5哈希變換:fc5e038d38a57032085441e7fe7010b0
SHA1哈希變換:6adfb183a4a2c94a2f92dab5ade762a47889a5a1

KeyGenerator

用于生成秘鑰抛杨, KeyGenerator.getInstance(String algorithm)支持的參數(shù)有

AES (128)
DES (56)
DESede (168)
HmacSHA1
HmacSHA256

示例代碼

@org.junit.Test
public void testKeyGenerator() throws Exception {
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    //初始化方法有多種够委,根據(jù)需要選擇
    keyGenerator.init(128);
//      keyGenerator.init(new SecureRandom("1234567".getBytes()));
    
    SecretKey key = keyGenerator.generateKey();
    //key的二進(jìn)制編碼   將它保存到文件中

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, key);

    byte[] bytes = cipher.doFinal("helloworld".getBytes());

    System.out.println("加密數(shù)據(jù): " + Base64.getEncoder().encodeToString(bytes));

    /*=========保存key的二進(jìn)制編碼=========*/
    byte[] keyBytes = key.getEncoded();
    FileOutputStream fos = new FileOutputStream("F://test/key.txt");
    fos.write(keyBytes);
    fos.flush();
    fos.close();


    /*============從文件中讀取編碼并恢復(fù)key==============*/
    FileInputStream fis = new FileInputStream("F://test/key.txt");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    int len;
    byte[] buffer = new byte[1024];
    while ((len = fis.read(buffer)) > 0) {
        bos.write(buffer, 0, len);
    }
    fis.close();

    /*==============使用SecretKeySpec重新生成key============*/
    SecretKeySpec secretKeySpec = new SecretKeySpec(bos.toByteArray(), "AES");

    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, cipher.getParameters().getParameterSpec(IvParameterSpec.class));
    bytes = cipher.doFinal(bytes);
    System.out.println("解密數(shù)據(jù): " + new String(bytes));
}

//輸出
加密數(shù)據(jù): 0vUaeC2VWEvVpUWeDfgGhg==
解密數(shù)據(jù): helloworld

KeyPairGenerator

KeyPairGenerator用于生成一對(duì)密鑰對(duì),用于做非對(duì)稱(chēng)加密操作怖现。KeyPairGenerator.getInstance(String alorithm)的可用參數(shù)為:

DSA
RSA
EC

代碼生成的密鑰對(duì)通常需要將公鑰和私鑰保存到文件中茁帽,這樣才能夠持久化進(jìn)行操作,下面演示兩種保存的實(shí)現(xiàn)

  1. 分別保存公鑰和私鑰的二進(jìn)制編碼
@org.junit.Test
public void testSaveKeyPair2() throws Exception {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();

    PublicKey oldPbk = keyPair.getPublic();
    PrivateKey oldPrk = keyPair.getPrivate();

    Cipher cipher = Cipher.getInstance("RSA");
    /*============使用原始私鑰加密真竖,重新生成的公鑰解密===============*/
    cipher.init(Cipher.ENCRYPT_MODE, oldPrk);
    byte[] bytes = cipher.doFinal("helloworld".getBytes());
    System.out.println("原始私鑰加密: " + Base64.getEncoder().encodeToString(bytes));

    /*提取公鑰的比特編碼經(jīng)過(guò)Base64轉(zhuǎn)換后保存到文件脐雪,注意公鑰的比特編碼是X.509格式*/
    byte[] pbks = Base64.getEncoder().encode(oldPbk.getEncoded());
    File file = new File("F://test/public.key");
    FileOutputStream fos = new FileOutputStream(file);
    fos.write(pbks);
    fos.flush();
    fos.close();

    /*從文件中提取公鑰比特編碼并恢復(fù)成公鑰*/
    file = new File("F://test/public.key");
    FileInputStream fis = new FileInputStream(file);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    while ((len = fis.read(buffer)) > 0) {
        bos.write(buffer, 0, len);
    }
    pbks = Base64.getDecoder().decode(bos.toByteArray());
    X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(pbks);
    //重新得到公鑰
    PublicKey newPbk = KeyFactory.getInstance("RSA").generatePublic(encodedKeySpec);


    cipher.init(Cipher.DECRYPT_MODE, newPbk);
    bytes = cipher.doFinal(bytes);
    System.out.println("新的公鑰解密: " + new String(bytes));

      /*============使用原始公鑰加密,重新生成的私鑰解密===============*/
    cipher.init(Cipher.ENCRYPT_MODE, oldPbk);
    bytes = cipher.doFinal("helloworld".getBytes());
    System.out.println("原始私鑰加密: " + Base64.getEncoder().encodeToString(bytes));


    /*省略了文件存取操作恢共,與公鑰相同*/

    byte[] prks = oldPrk.getEncoded();
    /*私鑰的比特編碼是pkcs8格式*/
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(prks);
    PrivateKey newPrk = KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
    cipher.init(Cipher.DECRYPT_MODE, newPrk);
    bytes = cipher.doFinal(bytes);
    System.out.println("新的私鑰解密: " + new String(bytes));
}
//輸出
原始私鑰加密: CO7FU1hQsEd8fYV4ZfWXquo/qrktte2n/WakdHJuw001aa9RM/mYl6yC6jLMGlm0fxuYlH92Zv9jA7k/0TVuor8Csvzmbm00RMBhnQCme+aQQbSoZDZEwJj1HtW6aK5MJRI4l/1W+g5X+Fs/6TLlbXpJM0k4epGMKUWwhO6cUiM=
新的公鑰解密: helloworld
原始私鑰加密: ixqqoM3aRig3P6GGPICsSOdH8KXRrlFn9GB1OVIWt46Q9ROsS84BW693fKB9ea8CnLJayc2KU1yhPlHHqq08gU8WOxVYeBQ4Bi3MnoJzUluE/UWNaMYZt/jCB6NZx57XEpNJ6uKG5TUmZJm+eoK0BF7A8sOX96UbPuZlHd4lD0w=
新的私鑰解密: helloworld
  1. 保存密鑰對(duì)的特征值 公鑰(N战秋,e)私鑰(N,d)
 @org.junit.Test
public void testSaveKeyPair() throws Exception {
    final String algorithm = "RSA";
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);

    keyPairGenerator.initialize(1024);

    KeyPair keyPair = keyPairGenerator.generateKeyPair();

    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

    /*特征值N  e   d*/

    BigInteger N = publicKey.getModulus();
    BigInteger e = publicKey.getPublicExponent();
    BigInteger d = privateKey.getPrivateExponent();

    /**/
    String nStr = Base64.getEncoder().encodeToString(N.toByteArray());
    String eStr = Base64.getEncoder().encodeToString(e.toByteArray());
    String dStr = Base64.getEncoder().encodeToString(d.toByteArray());

    /*將這三個(gè)字符串保存到文件或者數(shù)據(jù)庫(kù)讨韭,通常n脂信,e可以保存在客戶(hù)端,而n透硝,d的數(shù)據(jù)必須保存在服務(wù)端*/


    N = new BigInteger(Base64.getDecoder().decode(nStr));
    e = new BigInteger(Base64.getDecoder().decode(eStr));
    d = new BigInteger(Base64.getDecoder().decode(dStr));

     /*根據(jù)N狰闪,e生成公鑰*/
    RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(N, e);
    PublicKey pbk = KeyFactory.getInstance(algorithm).generatePublic(publicKeySpec);

    Cipher cipher = Cipher.getInstance(algorithm);
    cipher.init(Cipher.ENCRYPT_MODE, pbk);
    //bytes 是加密后的數(shù)據(jù)
    byte[] bytes = cipher.doFinal("helloworld".getBytes());
    //用base64轉(zhuǎn)換輸出
    System.out.println("加密數(shù)據(jù):" + Base64.getUrlEncoder().encodeToString(bytes));

     /*根據(jù)N,d生成私鑰*/
    RSAPrivateKeySpec ps = new RSAPrivateKeySpec(N, d);
    PrivateKey prk = KeyFactory.getInstance(algorithm).generatePrivate(ps);

    cipher.init(Cipher.DECRYPT_MODE, prk);
    bytes = cipher.doFinal(bytes);
    System.out.println("解密數(shù)據(jù):" + new String(bytes));
}

//輸出
加密數(shù)據(jù):nVqRtqMDvnm-4pjW0R1Q6sRCRbLpK4WRtG342ydEa8069Kv2OVRGE1Rm3iEFZjFCyh_z_0jlf5liqCgDCkN9I2Ci1qWvrvQo9wZKQG5g86OrxWHs7n1Kg_SXR3rNC-55jPxQAYUXpw-U9XX4ls7aQ85pk2BMZLYoRbwo3ktZAxM=
解密數(shù)據(jù):helloworld

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末濒生,一起剝皮案震驚了整個(gè)濱河市埋泵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罪治,老刑警劉巖丽声,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異觉义,居然都是意外死亡雁社,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)晒骇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)霉撵,“玉大人磺浙,你說(shuō)我怎么就攤上這事⊥狡拢” “怎么了撕氧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)崭参。 經(jīng)常有香客問(wèn)我呵曹,道長(zhǎng),這世上最難降的妖魔是什么何暮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮铐殃,結(jié)果婚禮上海洼,老公的妹妹穿的比我還像新娘。我一直安慰自己富腊,他們只是感情好坏逢,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著赘被,像睡著了一般是整。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上民假,一...
    開(kāi)封第一講書(shū)人閱讀 52,196評(píng)論 1 308
  • 那天浮入,我揣著相機(jī)與錄音,去河邊找鬼羊异。 笑死事秀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的野舶。 我是一名探鬼主播易迹,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼平道!你這毒婦竟也來(lái)了睹欲?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤一屋,失蹤者是張志新(化名)和其女友劉穎窘疮,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體陆淀,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡考余,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了轧苫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楚堤。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疫蔓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出身冬,到底是詐尸還是另有隱情衅胀,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布酥筝,位于F島的核電站滚躯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嘿歌。R本人自食惡果不足惜掸掏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宙帝。 院中可真熱鬧丧凤,春花似錦、人聲如沸步脓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)靴患。三九已至仍侥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸳君,已是汗流浹背农渊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留相嵌,地道東北人腿时。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像饭宾,于是被迫代替她去往敵國(guó)和親批糟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

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

  • 概述 之前一直對(duì)加密相關(guān)的算法知之甚少看铆,只知道類(lèi)似DES徽鼎、RSA等加密算法能對(duì)數(shù)據(jù)傳輸進(jìn)行加密,且各種加密算法各有...
    Henryzhu閱讀 3,023評(píng)論 0 14
  • 介紹 加密和解密都使用同一把秘鑰弹惦,這種加密方法稱(chēng)為對(duì)稱(chēng)加密否淤,也稱(chēng)為單密鑰加密。簡(jiǎn)單理解為:加密解密都是同一把鑰匙 ...
    Blizzard_liu閱讀 817評(píng)論 0 1
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理棠隐,服務(wù)發(fā)現(xiàn)石抡,斷路器,智...
    卡卡羅2017閱讀 134,695評(píng)論 18 139
  • 最近工作忙碌勞累助泽,導(dǎo)致心情極差啰扛,吃的也不是很健康總之老想發(fā)火罵人特別容易情緒激動(dòng)對(duì)同事不滿(mǎn)最終請(qǐng)了兩天假嚎京,第一我在...
    格物11致知閱讀 197評(píng)論 0 0
  • 完成事項(xiàng):2, 未完成事項(xiàng):1隐解,原因:晚上很困鞍帝,把孩子哄睡后快十點(diǎn)了,迷迷糊糊睡著了煞茫,沒(méi)有做復(fù)盤(pán),因?yàn)樵缟嫌凶x書(shū)計(jì)...
    泡沫XY閱讀 86評(píng)論 0 0