1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        每日一例 | java常用的加密算法實(shí)現(xiàn)

        共 25126字,需瀏覽 51分鐘

         ·

        2021-05-14 15:38

        前言

        日常開發(fā)中,傳輸敏感數(shù)據(jù),或者登陸、權(quán)限校驗(yàn)的時(shí)候,我們經(jīng)常要對數(shù)據(jù)進(jìn)行加密解密,今天我們就來看下如何用java來實(shí)現(xiàn)這些常用的加密算法。

        常用的加密算法分為兩種,“對稱式”和“非對稱式”。

        對稱式加密技術(shù)

        對稱式加密就是加密和解密使用同一個(gè)密鑰,通常稱之為“Session Key”這種加密技術(shù)在當(dāng)今被廣泛采用,如美國政府所采用的DES加密標(biāo)準(zhǔn)就是一種典型的“對稱式”加密法,它的Session Key長度為56bits。

        非對稱式加密技術(shù)

        非對稱式加密就是加密和解密所使用的不是同一個(gè)密鑰,通常有兩個(gè)密鑰,稱為“公鑰”和“私鑰”,它們兩個(gè)必需配對使用,否則不能打開加密文件。這里的“公鑰”是指可以對外公布的,“私鑰”則不能,只能由持有人一個(gè)人知道。它的優(yōu)越性就在這里,因?yàn)閷ΨQ式的加密方法如果是在網(wǎng)絡(luò)上傳輸加密文件就很難不把密鑰告訴對方,不管用什么方法都有可能被別竊聽到。而非對稱式的加密方法有兩個(gè)密鑰,且其中的“公鑰”是可以公開的,也就不怕別人知道,收件人解密時(shí)只要用自己的私鑰即可以,這樣就很好地避免了密鑰的傳輸安全性問題。

        我們國家出于信息安全考慮,研發(fā)了國密算法。國密算法,就是國家密碼局認(rèn)定的國產(chǎn)密碼算法,即商用密碼。

        國密算法是國家密碼局制定標(biāo)準(zhǔn)的一系列算法。其中包括了對稱加密算法,橢圓曲線非對稱加密算法,雜湊算法。具體包括SM1,SM2,SM3等。

        有興趣的小伙伴可以去國家密碼管理局(https://www.oscca.gov.cn/sca/index.shtml)了解下,網(wǎng)上也有很多現(xiàn)成的資源,今天我們就不講了。

        常用的算法

        Base64

        嚴(yán)格意義上講,base64只能算一種編碼格式,并不能算加密,因?yàn)槿魏稳四玫?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">base64都可以解碼,但是base64在日常開發(fā)中經(jīng)常被用到,比如參數(shù)編碼之后傳輸、圖片編碼后傳輸

        /**
             * base64加密
             *
             * @param sourcesStr
             * @return
             */

            public String encodeBase64(String sourcesStr) {
                Base64.Encoder encoder = Base64.getEncoder();
                String encodeToString = encoder.encodeToString(sourcesStr.getBytes());
                return encodeToString;
            }

            /**
             * base64解碼
             *
             * @param encodeBase64Str
             * @return
             */

            public String decodeBase64(String encodeBase64Str) {
                Base64.Decoder decoder = Base64.getDecoder();
                byte[] decode = decoder.decode(encodeBase64Str);
                return new String(decode);
            }

        MD5

        md5是一種不可被解密的加密方式,網(wǎng)上提供解密的網(wǎng)站,基本上都是先生成密碼庫(密文和明文的kv),當(dāng)你輸入密文后,檢索對應(yīng)的明文,如果存在就可以被解密,否則是沒法解密的,這種方式就是暴力破解,當(dāng)然如果某一天進(jìn)入了量子時(shí)代,那秒破md5也是可以的,但以目前的計(jì)算機(jī)算力,暴力破解一個(gè)超長的md5密文,那是相當(dāng)難的

        /**
             * md5加密
             * @param sourcesStr
             * @return
             */

            public String md5Encode(String sourcesStr) {
                    byte[] secretBytes = null;
                    try {
                        secretBytes = MessageDigest.getInstance("md5").digest(
                                sourcesStr.getBytes());
                    } catch (NoSuchAlgorithmException e) {
                        throw new RuntimeException("沒有這個(gè)md5算法!");
                    }
                    String md5code = new BigInteger(1, secretBytes).toString(16);
                    for (int i = 0; i < 32 - md5code.length(); i++) {
                        md5code = "0" + md5code;
                    }
                    return md5code;
            }

        RSA

        非對稱加密算法的代表,RSA是被研究得最廣泛的公鑰算法,從提出到現(xiàn)在已近三十年,經(jīng)歷了各種攻擊的考驗(yàn),逐漸為人們接受,普遍認(rèn)為是目前最優(yōu)秀的公鑰方案之一。1983年麻省理工學(xué)院在美國為RSA算法申請了專利。

        RSA允許你選擇公鑰的大小。512位的密鑰被視為不安全的;768位的密鑰不用擔(dān)心受到除了國家安全管理(NSA)外的其他事物的危害;1024位的密鑰幾乎是安全的。RSA在一些主要產(chǎn)品內(nèi)部都有嵌入,像 Windows、網(wǎng)景 Navigator、 QuickenLotus Notes

        import java.security.KeyFactory;
        import java.security.KeyPair;
        import java.security.KeyPairGenerator;
        import java.security.PrivateKey;
        import java.security.PublicKey;
        import java.security.SecureRandom;
        import java.security.Signature;
        import java.security.spec.PKCS8EncodedKeySpec;
        import java.security.spec.X509EncodedKeySpec;
        import java.util.HashMap;
        import java.util.Map;

        import javax.crypto.Cipher;

        import org.apache.commons.codec.binary.Hex;

         
        public class RSATest {
         // 數(shù)字簽名,密鑰算法
         private static final String RSA_KEY_ALGORITHM = "RSA";
         
         // 數(shù)字簽名簽名/驗(yàn)證算法
         private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
         
         // RSA密鑰長度
         private static final int KEY_SIZE = 1024;
         
         public static final String PUBLIC_KEY = "publicKey";
         public static final String PRIVATE_KEY = "privateKey";
         
         /**
          * 初始化RSA密鑰對
          * @return RSA密鑰對
          * @throws Exception 拋出異常
          */

         public static Map<String, String> initKey() throws Exception {
          KeyPairGenerator keygen = KeyPairGenerator
            .getInstance(RSA_KEY_ALGORITHM);
          SecureRandom secrand = new SecureRandom();
          secrand.setSeed("hahaha".getBytes());// 初始化隨機(jī)產(chǎn)生器
          keygen.initialize(KEY_SIZE, secrand); // 初始化密鑰生成器
          KeyPair keys = keygen.genKeyPair();
          String pub_key = new String(Hex.encodeHex(keys.getPublic().getEncoded()));
          String pri_key = new String(Hex.encodeHex(keys.getPrivate().getEncoded()));
          Map<String, String> keyMap = new HashMap<String, String>();
          keyMap.put(PUBLIC_KEY, pub_key);
          keyMap.put(PRIVATE_KEY, pri_key);
          System.out.println("公鑰:" + pub_key);
          System.out.println("私鑰:" + pri_key);
          return keyMap;
         }
         
            /**
             * 得到公鑰
             * @param keyMap RSA密鑰對
             * @return 公鑰
             * @throws Exception 拋出異常
             */

         public static String getPublicKey(Map<String, String> keyMap) throws Exception{
          return keyMap.get(PUBLIC_KEY);
         }
         
         /**
          * 得到私鑰
          * @param keyMap RSA密鑰對
          * @return 私鑰
          * @throws Exception 拋出異常
          */

         public static String getPrivateKey(Map<String, String> keyMap) throws Exception{
          return keyMap.get(PRIVATE_KEY);
         }
         
         /**
          * 數(shù)字簽名
          * @param data 待簽名數(shù)據(jù)
          * @param pri_key 私鑰
          * @return 簽名
          * @throws Exception 拋出異常
          */

         public static String sign(byte[] data, String pri_key) throws Exception {
          // 取得私鑰
          byte[] pri_key_bytes = Hex.decodeHex(pri_key);
          PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key_bytes);
          KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
          // 生成私鑰
          PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
          // 實(shí)例化Signature
          Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
          // 初始化Signature
          signature.initSign(priKey);
          // 更新
          signature.update(data);
          return new String(Hex.encodeHex(signature.sign()));
         }
         
         /**
          * RSA校驗(yàn)數(shù)字簽名
          * @param data 數(shù)據(jù)
          * @param sign 簽名
          * @param pub_key 公鑰
          * @return 校驗(yàn)結(jié)果,成功為true,失敗為false
          * @throws Exception 拋出異常
          */

         public static boolean verify(byte[] data, byte[] sign, String pub_key) throws Exception {
          // 轉(zhuǎn)換公鑰材料
          // 實(shí)例化密鑰工廠
          byte[] pub_key_bytes = Hex.decodeHex(pub_key.toCharArray());
          KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
          // 初始化公鑰
          // 密鑰材料轉(zhuǎn)換
          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key_bytes);
          // 產(chǎn)生公鑰
          PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
          // 實(shí)例化Signature
          Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
          // 初始化Signature
          signature.initVerify(pubKey);
          // 更新
          signature.update(data);
          // 驗(yàn)證
          return signature.verify(sign);
         }
         
         /**
          * 公鑰加密
          * @param data 待加密數(shù)據(jù)
          * @param pub_key 公鑰
          * @return 密文
          * @throws Exception 拋出異常
          */

         private static byte[] encryptByPubKey(byte[] data, byte[] pub_key) throws Exception {
          // 取得公鑰
          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key);
          KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
          PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
          // 對數(shù)據(jù)加密
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.ENCRYPT_MODE, publicKey);
          return cipher.doFinal(data);
         }
         
         /**
          * 公鑰加密
          * @param data 待加密數(shù)據(jù)
          * @param pub_key 公鑰
          * @return 密文
          * @throws Exception 拋出異常
          */

         public static String encryptByPubKey(String data, String pub_key) throws Exception {
          // 私匙加密
          byte[] pub_key_bytes = Hex.decodeHex(pub_key.toCharArray());
          byte[] enSign = encryptByPubKey(data.getBytes(), pub_key_bytes);
          return new String(Hex.encodeHex(enSign));
         }
         
         /**
          * 私鑰加密
          * @param data 待加密數(shù)據(jù)
          * @param pri_key 私鑰
          * @return 密文
          * @throws Exception 拋出異常
          */

         private static byte[] encryptByPriKey(byte[] data, byte[] pri_key) throws Exception {
          // 取得私鑰
          PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key);
          KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
          PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
          // 對數(shù)據(jù)加密
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.ENCRYPT_MODE, privateKey);
          return cipher.doFinal(data);
         }
         
         /**
          * 私鑰加密
          * @param data 待加密數(shù)據(jù)
          * @param pri_key 私鑰
          * @return 密文
          * @throws Exception 拋出異常
          */

         public static String encryptByPriKey(String data, String pri_key) throws Exception {
          // 私匙加密
          byte[] pri_key_bytes = Hex.decodeHex(pri_key.toCharArray());
          byte[] enSign = encryptByPriKey(data.getBytes(), pri_key_bytes);
          return new String(Hex.encodeHex(enSign));
         }
         
         /**
          * 公鑰解密
          * @param data 待解密數(shù)據(jù)
          * @param pub_key 公鑰
          * @return 明文
          * @throws Exception 拋出異常
          */

         private static byte[] decryptByPubKey(byte[] data, byte[] pub_key) throws Exception {
          // 取得公鑰
          X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub_key);
          KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
          PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
          // 對數(shù)據(jù)解密
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.DECRYPT_MODE, publicKey);
          return cipher.doFinal(data);
         }
         
         /**
          * 公鑰解密
          * @param data 待解密數(shù)據(jù)
          * @param pub_key 公鑰
          * @return 明文
          * @throws Exception 拋出異常
          */

         public static String decryptByPubKey(String data, String pub_key) throws Exception {
          // 公匙解密
          byte[] pub_key_bytes = Hex.decodeHex(pub_key.toCharArray());
          byte[] design = decryptByPubKey(Hex.decodeHex(data.toCharArray()), pub_key_bytes);
          return new String(design);
         }
         
         /**
          * 私鑰解密
          * @param data 待解密數(shù)據(jù)
          * @param pri_key 私鑰
          * @return 明文
          * @throws Exception 拋出異常
          */

         private static byte[] decryptByPriKey(byte[] data, byte[] pri_key) throws Exception {
          // 取得私鑰
          PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri_key);
          KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
          PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
          // 對數(shù)據(jù)解密
          Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
          cipher.init(Cipher.DECRYPT_MODE, privateKey);
          return cipher.doFinal(data);
         }
         
         /**
          * 私鑰解密
          * @param data 待解密數(shù)據(jù)
          * @param pri_key 私鑰
          * @return 明文
          * @throws Exception 拋出異常
          */

         public static String decryptByPriKey(String data, String pri_key) throws Exception {
          // 私匙解密
          byte[] pri_key_bytes = Hex.decodeHex(pri_key.toCharArray());
          byte[] design = decryptByPriKey(Hex.decodeHex(data.toCharArray()), pri_key_bytes);
          return new String(design);
         }
         
         /**
          * @param args
          */

         @SuppressWarnings("static-access")
         public static void main(String[] args) throws Exception {
         
          RSATest das = new RSATest();
         
          String datastr = "天街小雨潤如酥,草色遙看近卻無。最是一年春好處,絕勝煙柳滿皇都。";
          System.out.println("待加密數(shù)據(jù):\n" + datastr);
          //獲取密鑰對
          Map<String, String> keyMap = new HashMap<String, String>();
          keyMap = das.initKey();
          String pub_key = (String) keyMap.get(PUBLIC_KEY);
          String pri_key = (String) keyMap.get(PRIVATE_KEY);
          // 公匙加密
          String pubKeyStr = RSATest.encryptByPubKey(datastr, pub_key);
          System.out.println("公匙加密結(jié)果:\n" + pubKeyStr);
          // 私匙解密
          String priKeyStr = RSATest.decryptByPriKey(pubKeyStr, pri_key);
          System.out.println("私匙解密結(jié)果:\n" + priKeyStr);
         
          //換行
          System.out.println();
          
          // 數(shù)字簽名
          String str1 = "123";
          String str2 = "123er";
          System.out.println("正確的簽名:" + str1 + "\n錯(cuò)誤的簽名:" + str2);
          String sign = RSATest.sign(str1.getBytes(), pri_key);
          System.out.println("數(shù)字簽名:\n" + sign);
          System.out.println("簽名長度:" + sign.length());
          boolean vflag1 = das.verify(str1.getBytes(), Hex.decodeHex(sign.toCharArray()), pub_key);
          System.out.println("數(shù)字簽名驗(yàn)證結(jié)果1:\n" + vflag1);
          boolean vflag2 = das.verify(str2.getBytes(), Hex.decodeHex(sign.toCharArray()), pub_key);
          System.out.println("數(shù)字簽名驗(yàn)證結(jié)果2:\n" + vflag2);
         }
        }

        另外兩種rsa加密算法——MD5withRSASHA1withRSA

        import java.security.KeyPair;
        import java.security.KeyPairGenerator;
        import java.security.PrivateKey;
        import java.security.PublicKey;
        import java.security.Signature;

        import client.util.HEX2Byte;

        public class DigitalSignatureMain {
         public static void main(String[] args) throws Exception {
          String content = "study hard and make progress everyday";
          System.out.println("content :" + content);

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

          String md5Sign = getMd5Sign(content, privateKey);
          System.out.println("sign with md5 and rsa :" + md5Sign);
          boolean md5Verifty = verifyWhenMd5Sign(content, md5Sign, publicKey);
          System.out.println("verify sign with md5 and rsa :" + md5Verifty);

          String sha1Sign = getSha1Sign(content, privateKey);
          System.out.println("簽名長度:" + sha1Sign.length());
          System.out.println("sign with sha1 and rsa :" + sha1Sign);
          boolean sha1Verifty = verifyWhenSha1Sign(content, sha1Sign, publicKey);
          System.out.println("verify sign with sha1 and rsa :" + sha1Verifty);

         }

         // 生成密鑰對
         private static KeyPair getKeyPair() throws Exception {
          KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
          keyGen.initialize(512); // 可以理解為:加密后的密文長度,實(shí)際原文要小些 越大 加密解密越慢
          KeyPair keyPair = keyGen.generateKeyPair();
          return keyPair;
         }

         // 用md5生成內(nèi)容摘要,再用RSA的私鑰加密,進(jìn)而生成數(shù)字簽名
         public static String getMd5Sign(String content, PrivateKey privateKey)
           throws Exception 
        {
          byte[] contentBytes = content.getBytes("utf-8");
          Signature signature = Signature.getInstance("MD5withRSA");
          signature.initSign(privateKey);
          signature.update(contentBytes);
          byte[] signs = signature.sign();
          return HEX2Byte.bytesToHex(signs);
         }

         // 對用md5和RSA私鑰生成的數(shù)字簽名進(jìn)行驗(yàn)證
         public static boolean verifyWhenMd5Sign(String content, String sign,
           PublicKey publicKey)
         throws Exception 
        {
          byte[] contentBytes = content.getBytes("utf-8");
          Signature signature = Signature.getInstance("MD5withRSA");
          signature.initVerify(publicKey);
          signature.update(contentBytes);
          return signature.verify(HEX2Byte.hexToByteArray(sign));
         }

         // 用sha1生成內(nèi)容摘要,再用RSA的私鑰加密,進(jìn)而生成數(shù)字簽名
         public static String getSha1Sign(String content, PrivateKey privateKey)
           throws Exception 
        {
          byte[] contentBytes = content.getBytes("utf-8");
          Signature signature = Signature.getInstance("SHA1withRSA");
          signature.initSign(privateKey);
          signature.update(contentBytes);
          byte[] signs = signature.sign();
          return HEX2Byte.bytesToHex(signs);
         }

         // 對用md5和RSA私鑰生成的數(shù)字簽名進(jìn)行驗(yàn)證
         public static boolean verifyWhenSha1Sign(String content, String sign,
           PublicKey publicKey)
         throws Exception 
        {
          byte[] contentBytes = content.getBytes("utf-8");
          Signature signature = Signature.getInstance("SHA1withRSA");
          signature.initVerify(publicKey);
          signature.update(contentBytes);
          
          return signature.verify(HEX2Byte.hexToByteArray(sign));
         }
        }

        工具類

        package client.util;

        public class HEX2Byte {
         /**
          * hex字符串轉(zhuǎn)byte數(shù)組
          * 
          * @param inHex
          *            待轉(zhuǎn)換的Hex字符串
          * @return 轉(zhuǎn)換后的byte數(shù)組結(jié)果
          */

         public static byte[] hexToByteArray(String inHex) {
          int hexlen = inHex.length();
          byte[] result;
          if (hexlen % 2 == 1) {
           // 奇數(shù)
           hexlen++;
           result = new byte[(hexlen / 2)];
           inHex = "0" + inHex;
          } else {
           // 偶數(shù)
           result = new byte[(hexlen / 2)];
          }
          int j = 0;
          for (int i = 0; i < hexlen; i += 2) {
           result[j] = hexToByte(inHex.substring(i, i + 2));
           j++;
          }

          return result;
         }

         /**
          * Hex字符串轉(zhuǎn)byte
          * 
          * @param inHex
          *            待轉(zhuǎn)換的Hex字符串
          * @return 轉(zhuǎn)換后的byte
          */

         public static byte hexToByte(String inHex) {
          return (byte) Integer.parseInt(inHex, 16);
         }

         /**
          * 字節(jié)數(shù)組轉(zhuǎn)16進(jìn)制
          * 
          * @param bytes
          *            需要轉(zhuǎn)換的byte數(shù)組
          * @return 轉(zhuǎn)換后的Hex字符串
          */

         public static String bytesToHex(byte[] bytes) {
          StringBuffer sb = new StringBuffer();
          for (int i = 0; i < bytes.length; i++) {
           String hex = Integer.toHexString(bytes[i] & 0xFF);
           if (hex.length() < 2) {
            sb.append(0);
           }
           sb.append(hex);
          }
          return sb.toString();
         }

        }

        總結(jié)

        加密算法這塊其實(shí)沒什么好總結(jié)的,畢竟算法大佬已經(jīng)幫你實(shí)現(xiàn)好了,你要做的就是把它改造成你需要的樣子。個(gè)人覺得,現(xiàn)在做軟件開發(fā),讓完全勝任自己的工作,有一個(gè)能力特別重要,也特別基礎(chǔ),就是改造輪子的能力,畢竟現(xiàn)在開發(fā)程序不可能任何需求都從零開始,那太影響效率了,而且你造的輪子性能也不見得好。這也就是說,你要有看透輪子本質(zhì)的火眼金睛,要知道輪子解決了什么問題,是否滿足你的需求,但這還是要回到造輪子上,只是功夫要花在平時(shí)學(xué)習(xí)的時(shí)候,這是一個(gè)需要長期投入的事,當(dāng)然對你的成長也是特別有助益的。好了,今天就到這里吧!

        項(xiàng)目路徑:

        https://github.com/Syske/example-everyday

        本項(xiàng)目會每日更新,讓我們一起學(xué)習(xí),一起進(jìn)步,遇見更好的自己,加油呀

        - END -


        瀏覽 35
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久久久噜噜噜久久熟女av | 蜜桃av秘 无码一区二区三 | 日韩无码网 | 性爱动态视频 | 3p两男一女被两根一起进漫画 | 午夜国产小视频 | 色婷婷国产亚洲精品色窝窝 | 青青艹在线视频 | 高清无码靠逼视频 | 九九热国产在线 |