一、对称加密与非对称加密

1、对称加密

对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥加密,这种方法在密码学中叫做对称加密算法,对称加密算法使用起来简单快捷,密钥较短,且破译困难,除了数据加密标准(DES),另一个对称密钥加密系统是国际数据加密算法(IDEA),它比DES的加密性好,而且对计算机功能要求也没有那么高。

常见的对称加密算法有DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES

2、非对称加密

非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

3、对称加密与非对称加密的区别

  • 1、加密和解密过程不同
    对称加密的加密过程和解密过程使用的同一个密钥,加密过程相当于用原文+密钥可以传输出密文,同时解密过程用密文-密钥可以推导出原文。
    但非对称加密采用了两个密钥,一般使用公钥进行加密,使用私钥进行解密。

  • 2、加密解密速度不同
    对称加密解密的速度比较快,适合数据比较长时的使用。
    非对称加密和解密花费的时间长、速度相对较慢,只适合对少量数据的使用。

  • 3、传输的安全性不同
    对称加密的过程中无法确保密钥被安全传递,密文在传输过程中是可能被第三方截获的,如果密码本也被第三方截获,则传输的密码信息将被第三方破获,安全性相对较低。
    非对称加密算法中私钥是基于不同的算法生成不同的随机数,私钥通过一定的加密算法推导出公钥,但私钥到公钥的推导过程是单向的,也就是说公钥无法反推导出私钥。所以安全性较高。

二、加密算法实例

1、MD5加密单向加密

  • MD5是一种单向加密算法,只能加密不能解密
  • MD5 主要用做数据一致性验证、数字签名和安全访问认证,而不是用作加密。
package com.example.demo.password;import org.springframework.util.DigestUtils;import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class MD5Util {/*** java自带jar工具 java.security.MessageDigest 实现** @param text  要加密的字符串* @param rad   进制:比如 16、32* @param isUpp 是否转换为大写* @return*/public static String strToMD5(String text, int rad, boolean isUpp) {MessageDigest messageDigest = null;try {//通过MessageDigest类来的静态方法getInstance获取MessageDigest对象messageDigest = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}// 4、获取明文字符串对应的字节数组byte[] input = text.getBytes();// 5、执行加密messageDigest.update(input);//这里也可以直接使用byte[] output = messageDigest.digest(input)方法来进行加密,就省略了上面的update方法了byte[] output = messageDigest.digest();// 6、创建BigInteger对象// signum为1表示正数、-1表示负数、0表示0。不写默认表示正数int signum = 1;BigInteger bigInteger = new BigInteger(signum, output);// 7、按照16进制(或32进制)将bigInteger转为字符串return isUpp ? bigInteger.toString(rad).toUpperCase() : bigInteger.toString(rad);}/*** spring自带的工具 org.springframework.util.DigestUtils 实现** @param text* @return 16进制*/public static String _strToMD5(String text) {return DigestUtils.md5DigestAsHex(text.getBytes());}public static void main(String[] args) {String str = "hello";System.out.println(strToMD5(str, 16, true));System.out.println(_strToMD5(str));System.out.println(strToMD5(str, 16, false).equals(_strToMD5(str)));}
}

2、Base64加密解密

Java 8 内置了 Base64 编码的编码器和解码器。
Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:

  • 基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
  • URL:输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。
  • MIME:输出隐射到MIME友好格式。输出每行不超过76字符,并且使用’\r’并跟随’\n’作为分割。编码输出最后没有行分割。

static class Base64.Decoder:该类实现一个解码器用于,使用 Base64 编码来解码字节数据。
static class Base64.Encoder:该类实现一个编码器,使用 Base64 编码来编码字节数据。

package com.example.demo.password;import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.UUID;public class Base64Util {public static void main(String[] args) throws Exception {String text = "hello";try {/*** static Base64.Encoder getEncoder()* 返回一个 Base64.Encoder ,编码使用基本型 base64 编码方案。*/String base64encodedString = Base64.getEncoder().encodeToString(text.getBytes("utf-8"));System.out.println("Base64 编码字符串 (基本) :" + base64encodedString);/*** static Base64.Decoder getDecoder()* 返回一个 Base64.Decoder ,解码使用基本型 base64 编码方案。*/byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);System.out.println("原始字符串: " + new String(base64decodedBytes, "utf-8"));/*** static Base64.Encoder getUrlEncoder()* 返回一个 Base64.Encoder ,编码使用 URL 和文件名安全型 base64 编码方案。*/base64encodedString = Base64.getUrlEncoder().encodeToString(text.getBytes("utf-8"));System.out.println("Base64 编码字符串 (URL) :" + base64encodedString);/*** static Base64.Decoder getUrlDecoder()* 返回一个 Base64.Decoder ,解码使用 URL 和文件名安全型 base64 编码方案。*/byte[] base64decodedBytes2 = Base64.getUrlDecoder().decode(base64encodedString);System.out.println("原始字符串: " + new String(base64decodedBytes2, "utf-8"));StringBuilder stringBuilder = new StringBuilder();for (int i = 0; i < 10; ++i) {stringBuilder.append(UUID.randomUUID().toString());}byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);System.out.println("Base64 编码字符串 (MIME) :" + mimeEncodedString);}catch(UnsupportedEncodingException e){System.out.println("Error :" + e.getMessage());}}
}

Base 64主要用途不是加密,而是把一些二进制数转成普通字符,方便在网络上传输。 由于一些二进制字符在传输协议中属于控制字符,不能直接传送,所以需要转换一下才可以。由于某些系统中只能使用ASCII字符,Base64就是用来将非ASCII字符的数据转换成ASCII字符的一种方法,Base64特别适合在http,mime协议下快速传输数据。比如网络中图片的传输。

package com.example.demo.password;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;public class ImgToBase64String {/*** 图片转base64* @param filePath 图片文件路径* @return*/public static String toBase64String(String filePath){if (null == filePath || 0 == filePath.length()){throw new RuntimeException("图片路径不能为空!!");}InputStream in = null;byte[] data = null;try {//读取图片字节数组in = new FileInputStream(filePath);data = new byte[in.available()];in.read(data);in.close();}catch (IOException e){e.printStackTrace();}StringBuilder sb = new StringBuilder();sb.append("data:image/jpg;base64,");sb.append(Base64.getEncoder().encodeToString(data));//对字节数组Base64编码,返回Base64编码过的字节数组字符串return sb.toString();}public static void main(String[] args) {System.out.println(toBase64String("D:\\下载\\desktop.png"));}
}

3、DES对称加密解密

因jdk1.8自带的base64有所不同,使用jdk其他版本是可适当自行修改。

package com.example.demo.password;import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;public class DESUtil {public static Key setKey(String strKey) {Key key = null;try {KeyGenerator generator = KeyGenerator.getInstance("DES");generator.init(new SecureRandom(strKey.getBytes())); // 根据参数生成keykey = generator.generateKey();} catch (Exception e) {e.printStackTrace();}return key;}/*** @param source 编码内容* @param key 密钥* @param charSet 编码格式* @return*/public static String encrypt(String source, String key, String charSet) {String encrypt = null;try {byte[] ret = encrypt(source.getBytes(charSet), key);encrypt = new String(Base64.getEncoder().encode(ret));} catch (Exception e) {e.printStackTrace();encrypt = null;}return encrypt;}/*** @param encryptedData 解码内容* @param key 密钥* @param charSet 编码格式* @return*/public static String decrypt(String encryptedData, String key, String charSet) {String descryptedData = null;try {byte[] ret = descrypt(Base64.getDecoder().decode(encryptedData.getBytes()), key);descryptedData = new String(ret, charSet);} catch (Exception e) {e.printStackTrace();descryptedData = null;}return descryptedData;}private static byte[] encrypt(byte[] primaryData, String key) {Key desKey = setKey(key);try {Cipher cipher = Cipher.getInstance("DES"); // Cipher对象实际完成加密操作cipher.init(Cipher.ENCRYPT_MODE, desKey); // 用密钥初始化Cipher对象(加密)return cipher.doFinal(primaryData);} catch (Exception e) {e.printStackTrace();return null;}}private static byte[] descrypt(byte[] encryptedData, String key) {Key desKey = setKey(key);try {Cipher cipher = Cipher.getInstance("DES"); // Cipher对象实际完成解密操作cipher.init(Cipher.DECRYPT_MODE, desKey); // 用密钥初始化Cipher对象(解密)return cipher.doFinal(encryptedData);} catch (Exception e) {e.printStackTrace();return null;}}public static void main(String[] args) {String code = "hello world";String key = "thisisakey";String unicode = "utf-8";String encrypt = encrypt(code, key, unicode);String decrypt = decrypt(encrypt, key, unicode);System.out.println("原内容:" + code);System.out.println("加密:" + encrypt);System.out.println("解密:" + decrypt);}
}

4、AES对称加密解密

AES 与 DES 一样,一共有四种加密模式:电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)。

package com.example.demo.password;import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;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;public class AESUtil {//指定为AES算法,不区分大小写private static final String KEY_ALGORITHM = "AES";private static final String CHARSET_NAME = "utf-8";/** 加密 1.构造密钥生成器 2.根据ecnodeRules规则初始化密钥生成器 3.产生密钥 4.创建和初始化密码器 5.内容加密 6.返回字符串*/public static String AESEncode(String encodeRules, String content) {try {// 1.构造密钥生成器,指定为AES算法,不区分大小写KeyGenerator keygen = KeyGenerator.getInstance(KEY_ALGORITHM);// 2.根据ecnodeRules规则初始化密钥生成器// 生成一个128位的随机源,根据传入的字节数组//keygen.init(128, new SecureRandom(encodeRules.getBytes()));SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(encodeRules.getBytes());keygen.init(128, secureRandom);// 3.产生原始对称密钥SecretKey original_key = keygen.generateKey();// 4.获得原始对称密钥的字节数组byte[] raw = original_key.getEncoded();// 5.根据字节数组生成AES密钥SecretKey key = new SecretKeySpec(raw, KEY_ALGORITHM);// 6.根据指定算法AES自成密码器Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);// 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEYcipher.init(Cipher.ENCRYPT_MODE, key);// 8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码byte[] byte_encode = content.getBytes(CHARSET_NAME);// 9.根据密码器的初始化方式--加密:将数据加密byte[] byte_AES = cipher.doFinal(byte_encode);// 10.将加密后的数据转换为字符串// 这里用Base64Encoder中会找不到包// 解决办法:// 在项目的Build path中先移除JRE System Library,再添加库JRE System Library,重新编译后就一切正常了。String AES_encode = new String(Base64.getEncoder().encodeToString(byte_AES));// 11.将字符串返回return AES_encode;} 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();} catch (UnsupportedEncodingException e) {e.printStackTrace();}// 如果有错就返加nulllreturn null;}/** 解密 解密过程: 1.同加密1-4步 2.将加密后的字符串反纺成byte[]数组 3.将加密内容解密*/public static String AESDncode(String encodeRules, String content) {try {// 1.构造密钥生成器,指定为AES算法,不区分大小写KeyGenerator keygen = KeyGenerator.getInstance(KEY_ALGORITHM);// 2.根据ecnodeRules规则初始化密钥生成器// 生成一个128位的随机源,根据传入的字节数组//keygen.init(128, new SecureRandom(encodeRules.getBytes()));SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");secureRandom.setSeed(encodeRules.getBytes());keygen.init(128, secureRandom);// 3.产生原始对称密钥SecretKey original_key = keygen.generateKey();// 4.获得原始对称密钥的字节数组byte[] raw = original_key.getEncoded();// 5.根据字节数组生成AES密钥SecretKey key = new SecretKeySpec(raw, KEY_ALGORITHM);// 6.根据指定算法AES自成密码器Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);// 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEYcipher.init(Cipher.DECRYPT_MODE, key);// 8.将加密并编码后的内容解码成字节数组byte[] byte_content = Base64.getDecoder().decode(content);/** 解密*/byte[] byte_decode = cipher.doFinal(byte_content);String AES_decode = new String(byte_decode, CHARSET_NAME);return AES_decode;} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}// 如果有错就返加nulllreturn null;}public static void main(String[] args) {String encodeRules = "thisisrule";String text = "hello word";String encodeText = AESEncode(encodeRules, text);System.out.println("加密后的密文是:" + encodeText);System.out.println("解密后的内容是:" + AESDncode(encodeRules, encodeText));}
}

5、非对称加密——RSA

RSA密钥对生成:http://web.chacuo.net/netrsakeypair
在线加密解密:http://encode.chahuo.com/
RSA算法是一种非对称加密算法,RSA 加密主要有这么几步:生成密钥对、公开公钥、公钥加密私钥解密、私钥加密公钥解密。

package com.example.demo.password;import org.apache.commons.codec.binary.Base64;import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;public class RSAUtil {private static final String CHARSET_NAME = "utf-8";private static final String TYPE = "RSA";/*** RSA公钥加密** @param str       加密字符串* @param publicKey 公钥* @return 密文* @throws Exception 加密过程中的异常信息*/public static String encrypt(String str, String publicKey) throws Exception {//base64编码的公钥byte[] decoded = Base64.decodeBase64(publicKey);RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(TYPE).generatePublic(new X509EncodedKeySpec(decoded));//RSA加密Cipher cipher = Cipher.getInstance(TYPE);cipher.init(Cipher.ENCRYPT_MODE, pubKey);String outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(CHARSET_NAME)));return outStr;}/*** RSA私钥解密** @param str        加密字符串* @param privateKey 私钥* @return 铭文* @throws Exception 解密过程中的异常信息*/public static String decrypt(String str, String privateKey) throws Exception {//64位解码加密后的字符串byte[] inputByte = Base64.decodeBase64(str.getBytes(CHARSET_NAME));//base64编码的私钥byte[] decoded = Base64.decodeBase64(privateKey);RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(TYPE).generatePrivate(new PKCS8EncodedKeySpec(decoded));//RSA解密Cipher cipher = Cipher.getInstance(TYPE);cipher.init(Cipher.DECRYPT_MODE, priKey);String outStr = new String(cipher.doFinal(inputByte));return outStr;}public static void main(String[] args) throws Exception {String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKalqxfHXrZ0JZdLd2+BLhNS6bZxVyCOXvzFd0xCyX4oX/IbglKp9BGxQYaNl7stlHkQmMYBTAkIj0mAQzOVkqisYDevxKA5Yeitnim8R+N+a1SYaoQCfHLbCmMg4ZP0xaC30rA3DSMbEWQTD7p/g6v3sZevQUDVUcge9oaif9AQIDAQAB";String privateKey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMpqWrF8detnQll0t3b4EuE1LptnFXII5e/MV3TELJfihf8huCUqn0EbFBho2Xuy2UeRCYxgFMCQiPSYBDM5WSqKxgN6/EoDlh6K2eKbxH435rVJhqhAJ8ctsKYyDhk/TFoLfSsDcNIxsRZBMPun+Dq/exl69BQNVRyB72hqJ/0BAgMBAAECgYEAwOZKOArcddKaMJZCoWYY1/bOy9qZXWuNddHPJsAtnzGJcXK5AvJzgqBDrl99o5z15HYcG2MVY85aNn8IwahNh8CpFF8At7O2hVz1sTER2MPeiV5324BGOCPUkT4lY2iT2Dq6hXraZDI9sovit4FnfFlWH9nMOV5ckBvm5ypcCoECQQD/YLgSqXEERuu5qjU+PBCBKqbtOq5+EBNwLb9isxTPjRPoQ98sEzWsbyeLrc73Cjql5vU1io9rsG3IiYdEvFn9AkEAyuiaK95pbILOqK096d3Gt9oz0fqc5K4c9V44anaFzkEOysZlO3o1iZxqjfHdBlJiE4j0fq52+s+L9riqFbNMVQJATL3V0tXUPoLJZ3u8kD0ggJA+pV9S/FL8ZGN69b/26v/sEYoD0IzdPjoQ2iqa3SXXxe8HlNVUj/nuo6qgWYl4SQJBAJsXsYfoh7JeRXHegV15m8O5sDRGl5efkhjmfL67e0kMpy7M+GG+5p8ZhMScYzHK1JZT73XJCr5o13Ws7qyJkMUCQQD2EaVPOG+5M0VbzGGG820NRk9omSwO3GdSf4HZ6JWmeGk0FJN4NfAHnD8nA5L/HP+muqCdYQtYD068oZrNSabP";String text = "hello world";String encodeText = encrypt(text, publicKey);System.out.println("加密后:" + encodeText);System.out.println("解密后:" + decrypt(encodeText, privateKey));}
}

Java中常用的加密与解密相关推荐

  1. java中常用的加密工具

    java中常用的加密工具 1. md5加密工具类 public class MD5Utils {private static final String hexDigIts[] = {"0&q ...

  2. java中md5加密和解密_如何在java中实现md5加密和解密

    如何在java中实现md5加密和解密 关注:273  答案:1  mip版 解决时间 2021-01-19 20:37 提问者精神疯裂 2021-01-19 05:36 如何在java中实现md5加密 ...

  3. Java中的AES加密和解密(CBC模式)

    通过有线方式传输诸如纯文本密码之类的机密数据总是容易受到安全性的影响,始终建议对此类信息进行加密并使用SSL传输这些机密数据.Java为此提供了多种加密算法.在本文中,我们将讨论Java中具有CBC模 ...

  4. Java中常用的加密方法(JDK)

    加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容.大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些 ...

  5. Java中常用的加密方式

    一.Java常用加密方式 Base64加密算法(编码方式) MD5加密(消息摘要算法,验证信息完整性) 对称加密算法 非对称加密算法 数字签名算法 数字证书 二.分类 按加密算法是否需要key被分为两 ...

  6. java中常用的加密方法_java中常用的数据加密算法

    [项目中第一次深入地了解到加密算法的使用,现第一阶段结束,将使用到的加密算法和大家分享一下:首先还是先给大家普及一下常用加密算法的基础知识基本的单向加密算法BASE6 以下为加密的工具类: impor ...

  7. java中常用的加密工具類

    1.項目中引入jar包 javabase64-1.3.1.jar 2.如果是springboot項目,若在maven中不知道遠程路徑,可以按照如下方式操作: 2.1可以直接下載jar, 2.2在項目的 ...

  8. Java中对图片进行简单加密和解密

    import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io ...

  9. Android+Java中使用RSA加密实现接口调用时的校验功能

    场景 RSA加密 RSA算法是一种非对称加密算法,那么何为非对称加密算法呢? 一般我们理解上的加密是这样子进行的:原文经过了一把钥匙(密钥)加密后变成了密文,然后将密文传递给接收方,接收方再用这把钥匙 ...

最新文章

  1. 使用微软提供的Office Online实现Office文档的在线查看,编辑等功能
  2. 算法-----------数组------------只出现一次的数字
  3. 乘风破浪:LeetCode真题_007_Reverse Integer
  4. BUUCTF-WEB:[HCTF 2018]WarmUp
  5. static_cast、dynamic_cast、const_cast和reinterpret_cast总结
  6. Keepalived高可用集群来实现web服务器负载均衡集群
  7. 查看网络端口使用情况
  8. LiveVideoStackCon 2021上海站 售票通道关闭倒计时24h
  9. 创建一个安全的Spring REST API
  10. pb 执行存储过程带参数_PB级海量数据服务平台架构设计实践
  11. java 屏蔽邮箱_使用javamail发送邮件的时候如何阻止附件内容输出到控制台
  12. Linux下使用curl
  13. 7.边缘检测:2D运算——Canny的不同结果、单个2D边缘检测滤波器、实现边缘3种方法Matlab实战_3
  14. 抽象函数和虚函数有什么区别?
  15. 魔力岛服务器稳定吗,魔力岛《飘渺仙剑》寻找GM你愉我乐线上活动
  16. 【汇编语言】第三章 寄存器(内存访问)
  17. 生成树协议STP 网络冗余技术
  18. 新唐n76e003单片机遥控PWM信号检测控制航灯系统
  19. 【5G核心网】 NGAP 消息
  20. 资源网址合集的合集,上千个链接!

热门文章

  1. Sping的常用注解
  2. sso登录统一账号体系和集中认证授权,实现用户快速访问应用-哇谷云
  3. css 图片平铺和不平铺
  4. springboot整合qq登录<1.前置要求和授权登录原理>
  5. 高恪一键管控之封杀随身wifi与电视盒子
  6. 关于使用jenv安装管理不同jdk版本
  7. 【致远FAQ】V5V8.0sp1_致信客户端支持国产化PC吗?
  8. windows10 下映射一个新的盘Z
  9. php://filter协议的另一个姿势
  10. apache的url_rewrite地址重写中得到问号后面的参数