<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      對接服務(wù)升級后僅支持tls1.2,jdk1.7默認使用tls1.0,導(dǎo)致調(diào)用失敗

      背景

      如標題所說,我手里維護了一個重要的老項目,使用jdk1.7,里面對接了很多個第三方服務(wù),協(xié)議多種多樣,其中涉及http/https的,調(diào)用方式也是五花八門,比如:commons-httpclient、apache httpclient、原生的url.openConnection()等。

          <dependency>
              <groupId>commons-httpclient</groupId>
              <artifactId>commons-httpclient</artifactId>
              <version>3.0</version>
          </dependency>
          
          <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
          </dependency>
      
      

      最近,其中一個服務(wù)方,因為網(wǎng)絡(luò)設(shè)備要加固、網(wǎng)絡(luò)安全等原因,準備不再支持https的sslv3、tls1.0、tls1.1了,只支持tls1.2和tls1.3.

      這邊服務(wù)方也比較猛,直接就升級了,升級后沒一會,他觀察影響到我們這邊的調(diào)用了,又回退了。

      目前就是希望我們這邊,作為客戶端,先升級到tls1.2,即:調(diào)用他們服務(wù)的時候,使用tls1.2去調(diào)用。

      本來我也不想動,你個服務(wù)端,安安心心地兼容下tls1.0、tls1.1,不是簡單的很嗎,最終拉扯了一頓,行吧,那就我們先研究下,看看好不好升級到tls1.2。如果實在不好弄,到時候直接改成http調(diào)用得了,搞啥https?

      研究下來的方案,感覺還湊合,然后就改了,已經(jīng)提交測試了,今天就先記錄一下。

      報錯現(xiàn)象

      我在網(wǎng)上找了個工具,可以測試目標https網(wǎng)站,支持哪幾個版本的tls,如下所示,-p指定端口,后面的www.baidu.com就是目標ip或者域名。

      https://nmap.org/

      nmap --script ssl-enum-ciphers -p 443 www.baidu.com
      

      image-20250309102248600

      比如上圖的百度,就還在兼容老版本。

      我在網(wǎng)上又試了幾個域名,找到了一個只支持tls1.2的。

      blog.csdn.net
      

      image-20250309102406796

      下面,我們就拿blog.csdn.net舉例,看看用tls1.0發(fā)送請求,會報什么錯:

      image-20250309102601077

      可以看到,當(dāng)我們?nèi)挝帐滞瓿桑l(fā)送了第一個ssl握手消息(client hello,版本為tlsv1)后,對方(blog.csdn.net)直接來了個Alert,然后服務(wù)端就主動斷開socket了。這,連接都建不起來,還怎么消息交互呢,自然是所有調(diào)用全部失敗。

      報錯代碼debug

      sslcontext獲取

      給大家看下我們這邊調(diào)用發(fā)起的代碼,這個代碼就是用的上面說的那個commons-httpclient包,這個包算是apache早期維護的http調(diào)用工具,后來慢慢就重心不在這里了,轉(zhuǎn)到了apache httpclient。

      https://hc.apache.org/httpclient-legacy/

      image-20250309104109886

      HttpClient httpClient = new HttpClient();
      
      httpClient.getParams().setContentCharset(charset);
      httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));
      // 1 根據(jù)url,生成要調(diào)用的http method
      PostMethod httpMethod = new PostMethod(urlPath);
      
      try
      {
          long t1 = System.currentTimeMillis();
          // 2 實際發(fā)起調(diào)用
          int statusCode = httpClient.executeMethod(httpMethod);
          long spendTime = System.currentTimeMillis() - t1;
          ...
      }    
      

      從前面報錯的原因看來也是挺清晰的,那就是看怎么改了。我也在網(wǎng)上查了查,很多就說,設(shè)置個system property就行了。

      System.setProperty("https.protocols", "TLSv1.2");
      或者
      虛擬機參數(shù)設(shè)置 -Dhttps.protocols=TLSv1.2
      

      結(jié)果,我設(shè)置后,發(fā)現(xiàn)沒什么效果。沒效果的話,我一般會先debug試試,看看為什么發(fā)出去的報文是tls1.0.

      從如下地方開始debug代碼,因為實際執(zhí)行連接是在這里:

      int statusCode = httpClient.executeMethod(httpMethod);
      

      image-20250309105125234

      然后進入下圖,交給一個叫HttpMethodDirector的類執(zhí)行,這個類的注釋是說:負責(zé)執(zhí)行,及一些認證、重定向、報錯重試等相關(guān)事情

      image-20250309105356010

      后續(xù)會進入到:org.apache.commons.httpclient.HttpMethodDirector#executeWithRetry

      這里要先打開socket連接:

      image-20250309110157752

      這個conn.open比較重要:

      下面1處,判斷是否是https調(diào)用,且未使用代理,如果是的話,最終就是要走ssl握手那一套,構(gòu)造的socket也不一樣,如javax.net.ssl.SSLSocket

      2處,如果是https調(diào)用但使用了代理,這里就用普通http(不知道為啥),但反正我們沒使用代理,不涉及。

      3處,就是我們會進入的分支,獲取對應(yīng)的ProtocolSocketFactory(org.apache.commons.httpclient.protocol.ProtocolSocketFactory,該框架中的一個接口,反正是負責(zé)創(chuàng)建socket的)

      4處,創(chuàng)建socket

      org.apache.commons.httpclient.HttpConnection#open
          
      public void open() throws IOException {
              LOG.trace("enter HttpConnection.open()");
      
              final String host = (proxyHostName == null) ? hostName : proxyHostName;
              final int port = (proxyHostName == null) ? portNumber : proxyPortNumber;
              
              try {
                  if (this.socket == null) {
                      // 1 
                      usingSecureSocket = isSecure() && !isProxied();
                      ProtocolSocketFactory socketFactory = null;
                      // 2 
                      if (isSecure() && isProxied()) {
                          Protocol defaultprotocol = Protocol.getProtocol("http");
                          socketFactory = defaultprotocol.getSocketFactory();
                      } else {
                          // 3
                          socketFactory = this.protocolInUse.getSocketFactory();
                      }
                      // 4
                      this.socket = socketFactory.createSocket(
                                  host, port, 
                                  localAddress, 0,
                                  this.params);
                  }
      
                  socket.setTcpNoDelay(this.params.getTcpNoDelay());
                  socket.setSoTimeout(this.params.getSoTimeout());
                  
                  inputStream = new BufferedInputStream(socket.getInputStream(), inbuffersize);
                  outputStream = new BufferedOutputStream(socket.getOutputStream(), outbuffersize);
                  isOpen = true;
              } catch (IOException e) {
                  throw e;
              }
          }
      

      這里,我們默認會走到上面3處,工廠類型為:org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory,這個是默認的工廠。

      其中,我們來看看是如何createSocket的:

      這里會調(diào)用javax.net.ssl.SSLSocketFactory#getDefault,可以從包名看到,已經(jīng)開始和jdk中ssl部分的類交互了:

      image-20250309111329768

      在jdk 1.7的javax.net.ssl.SSLSocketFactory中,有一個static的全局變量,theFactory。

      image-20250309111533665

      我們看看這個getdefault的邏輯:

      1處,如果static field不為空,直接返回這個field。

      2處,如果自己指定了ssl.SocketFactory.provider,也可以用我們自定義的,我沒用這種方法,跳過

      3處,SSLContext.getDefault()獲取到一個SSLContext,然后調(diào)用javax.net.ssl.SSLContext#getSocketFactory來獲取一個factory。

      public static synchronized SocketFactory getDefault() {
              if (theFactory != null) {
                  // 1
                  return theFactory;
              } else {
                  if (!propertyChecked) {
                      propertyChecked = true;
                      // 2
                      String var0 = getSecurityProperty("ssl.SocketFactory.provider");
                      if (var0 != null) {
                          ...
                          Class var1 = = Class.forName(var0);
      
                          SSLSocketFactory var2 = (SSLSocketFactory)var1.newInstance();
      					// 2.1 設(shè)置theFactory
                          theFactory = var2;
                          return var2;
                      }
                  }
      
                  try {
                      // 3
                      return SSLContext.getDefault().getSocketFactory();
                  } catch (NoSuchAlgorithmException var4) {
                      return new DefaultSSLSocketFactory(var4);
                  }
              }
          }
      

      接下來,我們重點看看3處:

      image-20250309112541440

      這里會獲取靜態(tài)字段SSLContext defaultContext,如果為null就先初始化:

      private static SSLContext defaultContext;
      

      初始化的邏輯,就是傳個Default進去,那出來的是啥呢:

      下面這個地方可以簡述一下,大家看到SSLContextSpi.class了,Spi什么意思,ServiceProviderInterface,反正就是java官方負責(zé)定接口,廠商負責(zé)提供實現(xiàn)類,然后通過在某個配置文件中指定要使用的實現(xiàn)類來實現(xiàn)動態(tài)切換實現(xiàn)的效果。

      public static SSLContext getInstance(String var0) throws NoSuchAlgorithmException {
          Instance var1 = GetInstance.getInstance("SSLContext", SSLContextSpi.class, var0);
          return new SSLContext((SSLContextSpi)var1.impl, var1.provider, var0);
      }
      

      大家看看:SSLContextSpi是在javax.net.ssl包下面,而其實現(xiàn),則是在sun包下了。

      image-20250309113812979

      那,這里前面?zhèn)髁藗€“Default”進來,會獲取到哪一種SSLContext呢,我們看到實現(xiàn)類有這么多:

      image-20250309114403382

      結(jié)果,取到的就是:sun.security.ssl.SSLContextImpl.DefaultSSLContext#DefaultSSLContext

      image-20250309114543893

      這里只說是默認,默認是什么意思,咱們也不知道,但是,有經(jīng)驗的,對這塊代碼熟悉的,可能知道,大概問題就在這附近了,如果這里能拿到sun.security.ssl.SSLContextImpl.TLS12Context,說不定,問題就解決了。

      DefaultSSLContext

      這個DefaultSSLContext繼承了ConservativeSSLContext:

      public static final class DefaultSSLContext extends SSLContextImpl.ConservativeSSLContext
      

      在ConservativeSSLContext中,有如下的幾個field,其中defaultClientSSLParams對我們來說,最重要:

      private static class ConservativeSSLContext extends SSLContextImpl {
          private static final SSLParameters defaultServerSSLParams;
          // 重要
          private static final SSLParameters defaultClientSSLParams;
          private static final SSLParameters supportedSSLParams = new SSLParameters();
      
      

      下圖這里可以看到,defaultClientSSLParams最終被設(shè)置為從var1(tlsv1、sslv3)中獲取getAvailableProtocols,而這getAvailableProtocols會排除掉sslv3,只剩下tls v1。

      image-20250309115301475

      image-20250309115546186

      如果我們此時看看tlsv2對應(yīng)的sun.security.ssl.SSLContextImpl.TLS12Context:

      image-20250309115749299

      人家這里就支持的多了去了:sslv3 tls1.0 tls1.1 tls1.2

      SSLContext#getSocketFactory

      我們此時完成了SSLContext的構(gòu)建,然后看看怎么構(gòu)造socketFactory。

      實際上,構(gòu)造socketFactory沒做啥事,只是new了一個sun.security.ssl.SSLSocketFactoryImpl,然后把context包裝了下。

      image-20250309120255615

      createSocket

      public Socket createSocket(String var1, int var2, InetAddress var3, int var4) throws IOException {
          return new SSLSocketImpl(this.context, var1, var2, var3, var4);
      }
      

      image-20250309120531768

      這個init,也比較重要,就用到了我們前面的defaultClientSSLParams:

      image-20250309120721222

      最終,就導(dǎo)致:sun.security.ssl.SSLContextImpl#defaultClientProtocolList也變成了僅包含tlsv1

      image-20250309120829194

      然后呢,sun.security.ssl.SSLSocketImpl#enabledProtocols也就變成了tlsv1

      image-20250309121012120

      接下來,開始三次握手(如下的:super.connect),

      image-20250309121149202

      image-20250309121252395

      然后,在三次握手后,初始化ssl握手:

         void doneConnect() throws IOException {
              if (this.self == this) {
                  this.sockInput = super.getInputStream();
                  this.sockOutput = super.getOutputStream();
              } else {
                  this.sockInput = this.self.getInputStream();
                  this.sockOutput = this.self.getOutputStream();
              }
      		// 
              this.initHandshaker();
          }
      

      初始化握手對象

      private void initHandshaker() {
              switch(this.connectionState) {
              case 0:
              case 2:
                  this.handshaker = new ClientHandshaker(this, this.sslContext, this.enabledProtocols, this.protocolVersion, this.connectionState == 1, this.secureRenegotiation, this.clientVerifyData, this.serverVerifyData);
                      
                  this.handshaker.setEnabledCipherSuites(this.enabledCipherSuites);
                  this.handshaker.setEnableSessionCreation(this.enableSessionCreation);
                  return;
      

      image-20250309121554347

      此時,把版本繼續(xù)傳遞給了handshaker:

      image-20250309121702474

      至此,createSocket這個方法就完成了,但是,我們現(xiàn)在只是完成了三次握手,ssl中的clienthello消息還沒開始發(fā)送呢。

      httpclient.HttpMethod#execute

      我們一路回到了org.apache.commons.httpclient,開始執(zhí)行如下的execute:

      image-20250309121932050

      image-20250309122112058

      image-20250309122233881

      接下來,看到sslSocketImpl在寫消息的時候,要先進行ssl握手:

      image-20250309122349583

      handshaker.activate

      注意,如下這處,取了activeProtols中的最大的那個協(xié)議,而我們目前activeProtols這個list中,只有tlsv1,所以取到的自然就是tlsv1,然后賦值給了this.protocolVersion:

      image-20250309124107663

      接下來,又使用了this.protocolVersion:

      image-20250309124631000

      handshaker.kickstart

      image-20250309122446296

      接下來,在構(gòu)造消息時,還是使用了this.protocolVersion:

      這里有點意思的是,紅框處,是將this.protocolVersion賦值給了this.maxProtocolVersion,說明我們握手消息里的那個version,其實指的是客戶端支持的最大版本:

      image-20250309124916916

      基于這個,我在網(wǎng)上查找了一下,確實是這樣:

      tls1.0:

      https://www.ietf.org/rfc/rfc2246.txt

      image-20250309125248914

      tls1.1:

      https://datatracker.ietf.org/doc/html/rfc4346

      image-20250309125331199

      版本號驗證

      此時,我們基本也完成了關(guān)于版本號是怎么一步一步設(shè)置的過程的研究,最終,就會指定到如下圖的位置:

      image-20250309125455607

      不抓包如何查看使用的版本

      -Djavax.net.debug=ssl:handshake:verbose
      或者
      System.setProperty("javax.net.debug","ssl:handshake:verbose");
      
      然后標準輸出中會打印很多握手消息,可以搜索: ClientHello ,就能看到用的啥。
      

      如何解決該問題

      可選方案

      針對不同的http調(diào)用方式,方法不一樣,如,對于原生的URL、httpUrlConnection等,用以下方法基本夠了:

      System.setProperty("https.protocols", "TLSv1.2");
      或者
      虛擬機參數(shù)設(shè)置 -Dhttps.protocols=TLSv1.2
      

      使用apache httpclient的話,網(wǎng)上找下吧,方式很多,框架本身就支持指定。

      如果你們也有老項目,使用我這里的commons httpclient的話:

      可以先看下如下文章:https://blog.csdn.net/jilo88/article/details/123424442

      這個方法的重點就在于:

      image-20250309130257569

      我們前面提到過,以下代碼,默認返回的是:sun.security.ssl.SSLContextImpl.DefaultSSLContext

      image-20250309130422711

      而上述文章中,就是先自己手動指定了1.2:

      SSLContext sc = SSLContext.getInstance("TLSv1.2");
      

      然后設(shè)置到了這個javax.net.ssl.SSLContext#defaultContext。

      這個方式,影響很深遠,因為這個是一個靜態(tài)變量,整個jdk也就這一個SSLContext類,也就這一個靜態(tài)變量,所以是全局的影響。

      我試過了,改這里,會導(dǎo)致使用原生的URL、httpUrlConnection的方式的代碼也受到影響,大家可以自己試試。

      apache httpclient,有沒有影響,我有點忘了,大家自己測下。

      我的方案

      我是希望使用影響最小的方法,我如下的方法,只影響使用commons httpclient這種框架的,不使用這種框架的,不會受到影響。

      commons httpclient支持對于https,注冊自己的socketFactory:

      image-20250309131117584

      我這邊給https自定義了一個ProtocolSocketFactory,代碼很簡單,大家只要找個合適的時機(如發(fā)起http調(diào)用之前),調(diào)用一次如下的init方法,就可以了

      
      import org.apache.commons.httpclient.protocol.Protocol;
      import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import java.security.KeyManagementException;
      import java.security.NoSuchAlgorithmException;
      
      public class HttpClientSupport {
          private static Logger logger = LoggerFactory.getLogger(HttpClientSupport.class);
      
          public static void init(){
              Protocol protocol = Protocol.getProtocol("https");
              if (protocol != null) {
                  ProtocolSocketFactory socketFactory = protocol.getSocketFactory();
                  if (socketFactory instanceof CustomSSLProtocolSocketFactory){
      //                logger.info("already registered");
                      return;
                  }
                  logger.error("registered protocol for https is not CustomSSLProtocolSocketFactory type,will register");
              }
      
              // 注冊自定義的 ProtocolSocketFactory 到 HTTPS 協(xié)議
              CustomSSLProtocolSocketFactory socketFactory = null;
              try {
                  socketFactory = new CustomSSLProtocolSocketFactory();
                  Protocol.registerProtocol("https", new Protocol("https", socketFactory, 443));
                  logger.info("register tls1.2 socket factory success");
              } catch (NoSuchAlgorithmException | KeyManagementException e) {
                  logger.error("err",e);
              }
      
          }
      }
      
      
      import org.apache.commons.httpclient.ConnectTimeoutException;
      import org.apache.commons.httpclient.params.HttpConnectionParams;
      import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.SSLSocketFactory;
      import javax.net.ssl.TrustManager;
      import javax.net.ssl.X509TrustManager;
      import java.io.IOException;
      import java.net.InetAddress;
      import java.net.Socket;
      import java.net.UnknownHostException;
      import java.security.KeyManagementException;
      import java.security.NoSuchAlgorithmException;
      import java.security.cert.X509Certificate;
      
      /**
       * oa側(cè)升級tls協(xié)議為tls1.2及以上,我方進行適配
       */
      public class CustomSSLProtocolSocketFactory implements SecureProtocolSocketFactory {
          private static Logger logger = LoggerFactory.getLogger(CustomSSLProtocolSocketFactory.class);
      
      
          private final SSLContext sslContext;
      
          public CustomSSLProtocolSocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
              sslContext = SSLContext.getInstance("TLSv1.2");
      
              // 初始化 SSLContext(使用默認的 TrustManager)
              sslContext.init(null, new TrustManager[]{new X509TrustManager() {
                  @Override
                  public void checkClientTrusted(X509Certificate[] chain, String authType) {
                      // 信任所有客戶端證書
                  }
      
                  @Override
                  public void checkServerTrusted(X509Certificate[] chain, String authType) {
                      // 信任所有服務(wù)器證書
                  }
      
                  @Override
                  public X509Certificate[] getAcceptedIssuers() {
                      return new X509Certificate[0];
                  }
              }}, null);
      
          }
      
          /**
           * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
           */
          public Socket createSocket(
              String host,
              int port,
              InetAddress clientHost,
              int clientPort)
              throws IOException, UnknownHostException {
              SSLSocketFactory socketFactory = sslContext.getSocketFactory();
      //        logger.info("socketFactory:" + socketFactory);
              return socketFactory.createSocket(
                  host,
                  port,
                  clientHost,
                  clientPort
              );
          }
      
      
          public Socket createSocket(
              final String host,
              final int port,
              final InetAddress localAddress,
              final int localPort,
              final HttpConnectionParams params
          ) throws IOException, UnknownHostException, ConnectTimeoutException {
              if (params == null) {
                  throw new IllegalArgumentException("Parameters may not be null");
              }
              int timeout = params.getConnectionTimeout();
              if (timeout == 0) {
                  return createSocket(host, port, localAddress, localPort);
              } else {
                  logger.error("not support connection timeout param");
                  return createSocket(host, port, localAddress, localPort);
              }
          }
      
          /**
           * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
           */
          public Socket createSocket(String host, int port)
              throws IOException, UnknownHostException {
              SSLSocketFactory socketFactory = sslContext.getSocketFactory();
              return socketFactory.createSocket(
                  host,
                  port
              );
          }
      
          /**
           * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
           */
          public Socket createSocket(
              Socket socket,
              String host,
              int port,
              boolean autoClose)
              throws IOException, UnknownHostException {
              SSLSocketFactory socketFactory = sslContext.getSocketFactory();
              return socketFactory.createSocket(
                  socket,
                  host,
                  port,
                  autoClose
              );
          }
      
          /**
           * All instances of CustomSSLProtocolSocketFactory are the same.
           */
          public boolean equals(Object obj) {
              return ((obj != null) && obj.getClass().equals(CustomSSLProtocolSocketFactory.class));
          }
      
          /**
           * All instances of CustomSSLProtocolSocketFactory have the same hash code.
           */
          public int hashCode() {
              return CustomSSLProtocolSocketFactory.class.hashCode();
          }    
          
      }
      

      參考資料

      https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/ReadDebug.html

      總結(jié)

      這個問題能解決,說白了,還是因為jdk1.7本來就支持tls1.2,只是因為默認用了tls.10,這里只是強制指定下。

      希望能解決大家的問題就行了,維護老項目,處處小心點即可。今年估計要開始學(xué)python了,有領(lǐng)導(dǎo)安排的其他任務(wù),量化什么的,python更適合點,所以以后學(xué)廢了的話,可能也會更新一些java語言之外的。

      posted @ 2025-03-09 13:20  三國夢回  閱讀(543)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 人人澡人人妻人人爽人人蜜桃| 搡老熟女老女人一区二区| 东京热一区二区三区在线| 亚洲熟妇无码另类久久久| 亚洲精品中文字幕尤物综合| 国产亚洲tv在线观看| 国产亚洲精品久久久久久无亚洲 | h无码精品3d动漫在线观看| 亚洲熟妇久久精品| 国产农村老熟女国产老熟女| 野外做受三级视频| 怀安县| 国产在线乱子伦一区二区| 99久久精品视香蕉蕉| 精品国产成人国产在线观看| 亚洲乱色一区二区三区丝袜| 国产熟睡乱子伦视频在线播放| 邻居少妇张开腿让我爽了一夜| 日产中文字幕在线精品一区| 99久久久国产精品免费无卡顿| 普兰店市| 国产精品不卡一区二区三区| 美女爽到高潮嗷嗷嗷叫免费网站| 罗田县| 亚洲一级特黄大片一级特黄| 亚洲an日韩专区在线| 亚洲韩国精品无码一区二区三区| 亚洲日本韩国欧美云霸高清| 国产精品免费看久久久无码| 99久久亚洲综合精品成人| 国产精品中文第一字幕| 欧美乱妇高清无乱码免费| 精品一区精品二区制服| 线观看的国产成人av天堂| 国产黄色精品一区二区三区| 亚洲国产大胸一区二区三区| 吉川爱美一区二区三区视频 | 成人爽a毛片免费| 精品日韩人妻中文字幕| 久久国产成人午夜av影院| 国产激情无码一区二区三区|