国产一级一区二区_segui88久久综合9999_97久久夜色精品国产_欧美色网一区二区

掃一掃
關注微信公眾號

用JSSE定制SSL連接
2005-12-01   

在深入介紹JSSE之前,讓我們來一個簡單的客戶機/服務器程序,程序中包含了兩個文件:SimpleSSLServer和SimpleSSLClient。在運行程序之前,你需要配置下面這些KeyStore和TrestStore文件:
· 一個客戶端的KeyStore文件,該文件中包含了對Alice和Bob的授權。
· 一個服務器端的KeyStore文件,該文件中包含了對server的授權。
· 一個名為clientTrust的客戶端TrustStore文件,該文件中包含了對server的授權。
· 一個名為serverTrust的服務器端TrustStore文件,該文件中包含了對Alice和Bob的授權。
使用keytool可以幫助你創建這些文件(該工具在Java的bin目錄下):
· 一個客戶端的KeyStore文件,該文件中包含了對Alice和Bob的授權。
在命令窗口中輸入下面的命令:
keytool -genkey -alias alice -keystore clientKeys
窗口中會出現下面的提示,根據提示輸入相應的信息:

輸入keystore密碼: password
您的名字與姓氏是什么?
[Unknown]: Alice
您的組織單位名稱是什么?
[Unknown]: Development
您的組織名稱是什么?
[Unknown]: DCQ
您所在的城市或區域名稱是什么?
[Unknown]: ChongQing
您所在的州或省份名稱是什么?
[Unknown]: ChongQing
該單位的兩字母國家代碼是什么
[Unknown]: CH
CN=Alice, OU=Development, O=DCQ, L=ChongQing, ST=ChongQing, C=CH 正確嗎?
[否]: 是
輸入的主密碼


(如果和 keystore 密碼相同,按回車):
通過相同的方式可以建立對Bob的授權。
keytool -genkey -alias bob -keystore clientKeys
注意在名字與姓氏一欄中填寫Bob。在完成后可以鍵入下面的命令來檢測是否已經正確完成了授權。
keytool -list -v -keystore clientKeys????
· 一個服務器端的KeyStore文件,該文件中包含了對server的授權。
在命令窗口中鍵入下面的命令:
keytool -genkey -alias server -keystore serverKeys
注意將密碼設為password,名字與姓氏設定為Server。完成授權后同樣可以通過上面提到的命令來檢測。
· 一個名為clientTrust的客戶端TrustStore文件,該文件中包含了對server的授權。以及一個名為serverTrust的服務器端TrustStore文件,該文件中包含了對Alice和Bob的授權。
keytool -export -alias server -keystore clientKeys -file server.cer
輸入keystore密碼: password
保存在文件中的認證


keytool -export -alias alice -keystore clientKeys -file alice.cer
輸入keystore密碼: password
保存在文件中的認證


keytool -export -alias bob -keystore clientKeys -file bob.cer
輸入keystore密碼: password
保存在文件中的認證


這樣keytool就在當前目錄下創建了三個授權文件。然后我們將server.cer文件導入到clientTrust文件中;將alice.cer和bob.cer導入到serverTruest文件中:


keytool -import -alias server -keystore clientTrust -file server.cer
keytool -import -alias alice -keystore serverTrust -file alice.cer
keytool -import -alias bob -keystore serverTrust-file bob.cer
到目前為止,在當前目錄下包含clientKeys,serverKeys,clientTrust,serverTrust四個文件。完成了KeyStore和TrustStore的設置后就可以運行例子程序了。首先需要運行服務器程序:
java -Djavax.net.ssl.keyStore=serverKeys
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore#NAME?
-Djavax.net.ssl.trustStorePassword=password SimpleSSLServer
在命令行中我們指定了keyStore屬性為serverKeys。由于服務器程序需要獲得客戶端的授權信息,我們指定trustStore為serverTrust。這樣SSLSimpleServer就可以驗證由SSLSimpleClient提供的授權信息。當服務器程序成功運行后,你會看到下面的提示:
SimpleSSLServer running on port 49152????
這時候服務器會等待客戶端發出建立連接的申請。如果你希望在另一個端口上運行服務器程序,可以在命令中指定-port xxx參數,其中xxx是端口號。


然后在另一個命令窗口中運行客戶端程序:
java -Djavax.net.ssl.keyStore=clientKeys
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=clientTrust
-Djavax.net.ssl.trustStorePassword=password SimpleSSLClient
客戶端程序會試圖向本機的49152端口建立SSL連接。同樣你可以通過-port參數指定端口號,也可以通過-host參數指定主機名稱。當連接成功后,會出現下面的提示信息:


Connected
同時在服務器端會提示用戶客戶端已經連接成功。


SimpleSSLServer


讓我們先來看一下SimpleSSLServer。在main()方法中,程序獲得了缺省的SSLServerSocketFactory對象;然后利用SSLServerSocketFactory創建一個SimpleSSLServer對象,最后調用start()方法啟動SimpleSSLServer對象。


SSLServerSocketFactory ssf=
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SimpleSSLServer server=new SimpleSSLServer(ssf,port);
server.start();
由于服務器是在一個單獨的線程中運行的,main()方法啟動了服務器之后就退出了。start()方法啟動了一個新的線程,該線程執行run()方法中的代碼。在run()方法中創建了一個SSLServerSocket對象,然后設定服務器需要進行客戶端驗證:
SSLServerSocket serverSocket= (SSLServerSocket)serverSocketFactory.createServerSocket(port);
serverSocket.setNeedClientAuth(true);
調用run()方法后,程序進入了一個死循環,等待客戶端的連接申請。循環中的每個Socket對應一個HandshakeCompletedListener對象(該對象是用來顯示客戶驗證信息中的標識名稱[distinguished name]的)。Socket的InputStream對象被包裝在一個InputDisplayer對象中,這個InputDisplayer對象運行在另外一個線程中,用來將Socket接收到的數據發送到System.out。下面的代碼是SimpleSSLServer中的主循環體:
while (true) {
String ident=String.valueOf(id++);
//監聽連接請求.
SSLSocket socket=(SSLSocket)serverSocket.accept();
//通過使用HandshakeCompletedListener對象,程序進行授權驗證.
HandshakeCompletedListener hcl=new SimpleHandshakeListener(ident);
socket.addHandshakeCompletedListener(hcl);
InputStream in=socket.getInputStream();
new InputDisplayer(ident, in);
}
程序中的SimpleHandshakeListener類實現了HandshakeCompletedListerner接口。在SimpleHandshakeListener類中實現了handshakeCompleted()方法,該方法在SSL握手階段完成后將被JSSE調用。它將顯示出客戶端的標識名稱:
class SimpleHandshakeListener implements HandshakeCompletedListener
{
String ident;
/**
* 構造函數.
*/
public SimpleHandshakeListener(String ident)
{
this.ident=ident;
}
/**當SSL握手過程完成后該方法被激活. */
public void handshakeCompleted(HandshakeCompletedEvent event)
{
//顯示授權信息.
try {
X509Certificate
cert=(X509Certificate)event.getPeerCertificates()[0];
String peer=cert.getSubjectDN().getName();
System.out.println(ident+": Request from "+peer);
}
catch (SSLPeerUnverifiedException pue) {
System.out.println(ident+": Peer unverified");
}
}
}
用紅色字體表示的兩行代碼是這段代碼的核心:getPeerCertificates()方法返回一個X509Certificated對象的數組。這些X509Certificated對象創建了客戶端的身份標識。在數組中的第一個元素是客戶端的驗證信息,而最后一個通常是CA驗證。當我們有了客戶端的驗證信息后。我們可以得到其中的標識名稱,并將它傳送到System.out。


SimpleSSLClient


SimpleSSLClient類比較簡單,但是在后面的一些比較復雜的例子中的類會繼承該類。在getSLLSocketFactory()方法中,程序返回缺省的工廠類:


protected SSLSocketFactory getSSLSocketFactory()
throws IOException, GeneralSecurityException
{
return (SSLSocketFactory)SSLSocketFactory.getDefault();
}
在runClient()方法中,程序處理了輸入參數后,獲得SSLSockFactory對象,調用connect()方法連接到服務器程序。在connect()方法中,程序首先創建一個SSLSocket對象,然后調用SSLSocket對象的startHandshang()方法啟動和服務器端的握手過程。當握手過程完成后,會觸發一個HandshakeCompletedEvent事件。在服務器端的HandshakeCompletedListener對象會處理這個事件。事實上,JSSE可以自動啟動握手過程,但是必須是在第一次有數據通過Socket傳輸的情況下。由于在例子程序中,直到用戶在鍵盤上輸入信息后才會有數據通過Socket傳輸,而我們希望服務器端及時報告連接情況,因此我們用startShake()方法來手工激活握手過程。

boolean done=false;
while (!done) {
String line=reader.readLine();
if (line!=null) {
writer.write(line);
writer.write('\n');
writer.flush();
}
else done=true;
}
定制KeyStore和TrustStore?
還記得我們是如何運行客戶端的嗎?我們需要在命令行中指定keyStore,keyStorePasword, trustStore和trustStorePassword參數,以至于整個命令顯得過于冗長。事實上你可以在程序中指定KeyStore和TrustStore,后面的例子中將告訴你如何實現這一點。同時在例子中還會演示如何配置多個SSLSocketFactory對象,其中每個SSLSocketFactory對象對應不同的KeyStore和TrustStore設置。如果沒有這種技術,在同一個虛擬機上的所有安全連接都只能使用同一個KeyStore和TrustStore。對于比較小的應用程序,這也許不會產生問題;但是對于那些比較大的應用程序來說,這絕對是一個嚴重的缺陷。


在下面的例子中,我們將使用CustomTrustStoreClient來動態定義KeyStore和TrustStore。首先讓我們先運行一下CustomTrustStoreClient:


java CustomTrustStoreClient
為什么運行CustomTrustStoreClient時不需要指定KeyStore和TrustStore參數呢?這是應為在CustomTrustStoreClient的代碼中指定了KeyStore(ClientKeys)和TrustStore(ClientTruts)以及它們的密鑰(password)。如果你想使用其他的KeyStore、 TrustStore或密鑰,可以使用-ks、-kspass、-ts和-tspass參數來指定。下面讓我們來看一下CustomTrustStoreClient的getSSLSocketFactory()方法。該方法通過調用getTrustManager()方法獲得一個TurstManager對象數組,通過調用getKeyManagers()方法獲得一個KeyManager對象數組。然后利用得到的TurstManager和KeyManager對象數組構造一個SSLContext對象,最后通過SSLContext對象的getSocketFactory()方法來配置JSSE。需要注意的是在調用SSLContext類的init()方法時使用的參數。第一個參數是KeyManager對象數組。第二個參數和第一個參數類似,是TrustManager數組。如果前兩個參數被設定為null,程序將使用缺省的KeyManager和TrustStore(缺省的KeyStore來源于系統屬性中的javax.net.ssl.keyStore和javax.net.ssl.keyStorePassword屬性;缺省的TrustStore來源于系統屬性中的javax.net.ssl.trustStore和javax.net.ssl.trustStorePassword屬性)。通過設定第三個參數可以指定JSSE中的隨機數產生器(Random Number Generate, RNG)。由于在SSL中隨機數的產生是一個很敏感的問題,錯誤使用這個參數會導致安全連接變得不安全,因此我在例子中使用了null。這樣程序將使用缺省的并且是安全的SecureRandom對象。
protected SSLSocketFactory getSSLSocketFactory()
throws IOException, GeneralSecurityException
{
// 調用getTrustManagers方法獲得trust managers
TrustManager[] tms=getTrustManagers();
// 調用getKeyManagers方法獲得key manager
KeyManager[] kms=getKeyManagers();
//利用KeyManagers創建一個SSLContext對象.用獲得的KeyStore和
// TrustStore初始化該SSLContext對象.我們使用缺省的SecureRandom.
SSLContext context=SSLContext.getInstance("SSL");
context.init(kms, tms, null);
//最后獲得了SocketFactory對象.
SSLSocketFactory ssf=context.getSocketFactory();
return ssf;
}
下面讓我們看一看CustomKeyStoreClient類中的getKeyMangers()方法是如何初始化KeyManagers對象數組的:


protected KeyManager[] getKeyManagers()
throws IOException, GeneralSecurityException
{
// 獲得KeyManagerFactory對象.
String alg=KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmFact=KeyManagerFactory.getInstance(alg);
// 配置KeyManagerFactory對象使用的KeyStoree.我們通過一個文件加載
// KeyStore.
FileInputStream fis=new FileInputStream(keyStore);
KeyStore ks=KeyStore.getInstance("jks");
ks.load(fis, keyStorePassword.toCharArray());
fis.close();
// 使用獲得的KeyStore初始化KeyManagerFactory對象
kmFact.init(ks, keyStorePassword.toCharArray());
// 獲得KeyManagers對象
KeyManager[] kms=kmFact.getKeyManagers();
return kms;
}
首先的任務是獲得一個KeyManagerFactory對象,但是你必須知道應該使用哪種算法。JSSE中提供了一個缺省的KeyManagerFactory算法(程序員也可以通過指定ssl.KeyManagerFacotory.algorithm屬性指定缺省算法)。獲得KeyManagerFactory對象后就可以加載KeyStore文件了,程序中通過一個InputStream對象將信息從文件送入KeyStore對象中。在這個過程之前,KeyStore對象需要知道輸入流的格式(例子中我使用的是jks)和密鑰。當我們完成了KeyStore的加載后,我們就可以用它來初始化KeyManagerFactory對象了。通常在JSSE中,在KeyStore中的所有證書使用和KeyStore相同的密碼,但是通過創建KeyManagerFactory對象你可以突破這個限制。在初始化了KeyManagerFactory對象后,通常使用getKeyManager()方法來獲得KeyManager對象數組。程序員通過使用和getKeyMangers()方法類似的流程來初始化TrustManager數組,這里我就不再重復了。
實現一個KeyManager類
到目前為止,我們已經知道如何在程序中動態生成KeyStore和TrustStore了。最后一個例子將告訴你如何實現一個KeyManager類。


當運行前幾個例子的時候,不知道大家是否注意到服務器端顯示的授權的標識名稱。在前面我們授權給了兩個人:Alice和Bob,在運行程序時JSSE會從中任選一個。在我的計算機上JSSE選擇的總是Bob,或許在你的計算機上情況會有所不同。下面讓我們來看一看最后一個例子程序:SelectAliasClient。這個例子使你能夠在運行客戶端時使用指定的授權。例如你需要指定使用Alice的授權,由于Alice的別名是alice,你需要在命令窗口中鍵入下面的命令:


java SelectAliasClient -alias alice
當客戶端和服務器端成功連接后,客戶器端會出現下面的信息:
1: New connection request
1: Request from CN=Alice, OU= Development, O=DCQ, L=ChongQing,
ST=ChongQing, C=CH
為了使程序使用指定的授權,我們需要實現X509KeyManager接口(X509KeyManager是JSSE中最常用的KeyManager)。X509KeyManager接口在SSL握手階段使用了幾個方法來獲得授權。下面是X509KeyManager接口獲得授權的過程:


1.JSSE調用chooseClientAlias()方法獲得指定的授權。


2.chooseClientAlias()方法調用X509KeyManager接口的getClientAlaises()方法獲得SSLSocket對象使用的所有授權的別名,然后檢查指定的授權別名是否有效。
3.JSSE將別名作為參數調用X509KeyManager接口的getCertificateChain()和getPrivateKey()方法,這樣就獲得了指定授權的相關信息。
在例子程序中,X509KeyManager接口的實現類是AliasForcingKeyManager。在該類中最重要的方法就是就是chooseClientAlias()方法。下面是該方法的源代碼:


public String chooseClientAlias(String[] keyType, Principal[] issuers,
Socket socket)
{
//對于每一種類型的授權,都需要調用一次getClientAliases()方法來驗
// 證別名是否有效.
boolean aliasFound=false;
for (int i=0; i< i++) !aliasFound; &&>


String[] validAliases=baseKM.getClientAliases(keyType, issuers);
if (validAliases!=null) {
for (int j=0; j< !aliasFound; && j++)>


if (validAliases[j].equals(alias)) aliasFound=true;
}
}
}
if (aliasFound) return alias;
else return null;
}
我們可以看到在程序中,chooserClientAlias()方法實際上多次調用了getClientAliases()方法,每次都針對不同的授權類型。AliasForingKeyManager還實現了X509KeyManager接口的其他五個方法,在這里就不再一一贅述了。


然后我們就可以在程序中用AliasForingKeyManager對象來替代KeyManager對象了。在getSSLSocketFactory()方法中,我們只需要將通過調用getKeyManagers()方法獲得KeyManager對象數組,然后將其強制轉化為AliasForcingKeyManager對象就可以了。下面是新的getSSLSocketFactory()方法的代碼:


protected SSLSocketFactory getSSLSocketFactory()
throws IOException, GeneralSecurityException
{
// 調用父類中的方法獲得TrustManager和KeyManager
KeyManager[] kms=getKeyManagers();
TrustManager[]tms=getTrustManagers();
// 如果指定了別名,將KeyManagers包裝在AliasForcingKeyManager對象中.
if (alias!=null) {
for (int i=0; i< i++)>


// 這里只處理了X509KeyManager接口
if (kms instanceofX509KeyManager)
kms=new AliasForcingKeyManager((X509KeyManager)kms,alias);
}
}
// 利用TrustManagers和已經被包裝的KeyManagers創建一個SSLContext對象.
SSLContext context=SSLContext.getInstance("SSL");
context.init(kms, tms, null);
// 獲得SocketFactory對象.
SSLSocketFactory ssf=context.getSocketFactory();
return ssf;
}
我們可以使用同樣的方法來替換TrustManager對象,這樣我們就可以控制JSSE驗證授權的機制。具體的實現就留給讀者朋友去解決了。
小結
在這篇文章中,我們講述了使用JSSE的一些小技巧。讀完這篇文章后,我相信大家因該知道如何通過編程實現下面的任務:


· 使用HandshagCompletedListerner對象來獲得關于連接的信息。


· 從SSLContext對象中獲得一個SLLSocketFactory對象。


· 使用動態的TrustStroe或KeyStore。
· 突破在JSSE中KeySotre的密鑰的每個授權的密鑰必須相同的限制。


· 通過實現自己的KeyManager類來指定JSSE使用的授權。


如果大家有興趣的話,還可以進一步將這些技術進行擴展。例如你可以在JSSE的其他類中使用X509KeyManager接口,也可以在TrustStore和KeyStore的實現類中從數據庫中讀取授權信息。但是在使用自己編寫的TrustStore,KeyStore,TrustManager和KeyManager的時候,需要非常小心,因為任何一個細微的錯誤都可能導致SSL連接不再是安全的了。
作者簡介:馮睿畢業于美國北伊利諾大學計算機和電氣工程系,獲工程碩士學位。曾就職于NewMonics公司,進行Java虛擬機部分包的設計和開發和Java底層的性能優化工作。目前負責一些政府和企業級GIS系統的設計和實現。


熱詞搜索:

上一篇:安全連接方式SSL
下一篇:SSL代理客戶端使用

分享到: 收藏
国产一级一区二区_segui88久久综合9999_97久久夜色精品国产_欧美色网一区二区
日韩欧美国产系列| 99久久综合狠狠综合久久| 夜夜操天天操亚洲| 中文字幕字幕中文在线中不卡视频| 日韩欧美国产麻豆| 久久只精品国产| 精品国产第一区二区三区观看体验| 精品少妇一区二区三区免费观看 | 99re视频精品| 成人黄色av电影| 91亚洲精品一区二区乱码| 91免费小视频| 欧美日韩一二三| 日韩一区二区三区视频| 久久一夜天堂av一区二区三区| 久久人人爽爽爽人久久久| 亚洲国产精品t66y| 亚洲精品精品亚洲| 日韩中文字幕区一区有砖一区| 麻豆精品在线观看| 懂色一区二区三区免费观看| 91丨九色丨蝌蚪富婆spa| 精品视频在线免费观看| 日韩免费在线观看| 中国色在线观看另类| 一区二区三区在线播放| 日本午夜精品一区二区三区电影| 国产精品伊人色| 色噜噜狠狠成人中文综合| 91精品欧美福利在线观看| 国产视频911| 午夜欧美一区二区三区在线播放| 国产精品一区二区在线播放| 色呦呦网站一区| 精品国产伦一区二区三区观看体验 | 成人精品鲁一区一区二区| 在线视频中文字幕一区二区| 精品伦理精品一区| 夜色激情一区二区| 国产成人av电影在线观看| 欧美日韩一区二区三区四区五区| 久久综合丝袜日本网| 午夜在线成人av| 97se亚洲国产综合自在线| 日韩欧美视频一区| 一区2区3区在线看| 成人一区二区三区在线观看| 日韩欧美一级二级三级| 一区二区三区成人| 国产sm精品调教视频网站| 3d动漫精品啪啪1区2区免费| 三级成人在线视频| 欧美日韩一区国产| av电影在线观看一区| 国产99久久久精品| 精品在线观看视频| 欧美日韩视频在线观看一区二区三区| 欧美tickling挠脚心丨vk| 香蕉成人啪国产精品视频综合网 | 国产欧美综合在线| 美腿丝袜亚洲三区| 欧美四级电影在线观看| 亚洲视频香蕉人妖| 国产成人免费xxxxxxxx| 精品日韩一区二区| 麻豆精品久久精品色综合| 欧美喷水一区二区| 亚洲高清视频的网址| 在线视频观看一区| 亚洲激情一二三区| av欧美精品.com| 亚洲欧洲另类国产综合| 成人av电影免费观看| 国产精品久久久久永久免费观看| 国产一区二区在线免费观看| 精品区一区二区| 男女性色大片免费观看一区二区| 欧美综合色免费| 亚洲二区在线视频| 这里是久久伊人| 奇米四色…亚洲| 26uuu亚洲| 成人永久aaa| 亚洲天堂av一区| 欧美三区在线观看| 天堂精品中文字幕在线| 欧美精选一区二区| 久久99国产精品成人| 国产偷v国产偷v亚洲高清| 成人午夜短视频| 亚洲美女区一区| 欧美三级欧美一级| 六月婷婷色综合| 国产精品嫩草99a| 色久综合一二码| 免费视频一区二区| 国产三级欧美三级日产三级99| 成人深夜视频在线观看| 亚洲国产精品久久不卡毛片| 9191成人精品久久| 国产xxx精品视频大全| 亚洲免费观看高清| 日韩你懂的在线播放| 成人黄页在线观看| 亚洲成av人片一区二区梦乃| 久久欧美一区二区| 91在线观看美女| 免费观看成人鲁鲁鲁鲁鲁视频| 国产清纯白嫩初高生在线观看91| 在线国产电影不卡| 国产伦理精品不卡| 日韩和的一区二区| 亚洲欧美在线观看| 日韩视频在线一区二区| 99国内精品久久| 久久精品国产第一区二区三区| 最近中文字幕一区二区三区| 欧美一卡二卡三卡| 91美女在线视频| 国产在线看一区| 视频一区二区国产| 亚洲人成网站在线| 久久久综合精品| 欧美妇女性影城| 91亚洲男人天堂| 国产精品99久| 麻豆精品精品国产自在97香蕉 | 欧美成人精品福利| 色屁屁一区二区| 国产高清精品久久久久| 日韩不卡手机在线v区| 一级女性全黄久久生活片免费| 精品国产一区久久| 日韩欧美亚洲一区二区| 欧美人牲a欧美精品| 色婷婷av一区二区三区之一色屋| 国产成人免费在线| 久久99久久久久| 免费观看日韩av| 奇米四色…亚洲| 久久se精品一区二区| 免费成人av在线播放| 午夜欧美大尺度福利影院在线看| 亚洲精品国产一区二区精华液 | 日韩国产在线观看一区| 亚洲国产综合人成综合网站| 日韩码欧中文字| 国产精品美女一区二区三区| 国产欧美精品在线观看| 久久综合视频网| 久久久无码精品亚洲日韩按摩| 欧美一级二级三级乱码| 欧美丰满高潮xxxx喷水动漫| 欧美日韩一区精品| 91麻豆精品国产自产在线观看一区 | 欧美精品乱码久久久久久按摩| 色婷婷综合久久久中文一区二区| 不卡在线视频中文字幕| eeuss鲁片一区二区三区在线观看 eeuss鲁片一区二区三区在线看 | 成人免费毛片app| 成人精品视频一区二区三区 | 亚洲精品美国一| 一区二区三区日韩欧美| 亚洲精品国产精品乱码不99| 一区二区三区产品免费精品久久75| 亚洲国产视频一区二区| 亚洲观看高清完整版在线观看| 亚洲亚洲人成综合网络| 婷婷夜色潮精品综合在线| 青青草国产成人99久久| 国产大陆精品国产| av成人免费在线| 欧美伦理影视网| 欧美精品一区二区三区视频 | 欧美午夜一区二区三区| 日韩免费高清av| 国产精品女人毛片| 三级一区在线视频先锋| 国产尤物一区二区| 91搞黄在线观看| 精品国产乱码久久| 亚洲欧美激情视频在线观看一区二区三区 | 丁香网亚洲国际| 日本丶国产丶欧美色综合| 制服丝袜在线91| 欧美精彩视频一区二区三区| 一区二区在线观看视频在线观看| 日本一区中文字幕| jiyouzz国产精品久久| 91精品国产欧美一区二区成人| 亚洲国产精品v| 丝袜亚洲另类丝袜在线| 丰满亚洲少妇av| 欧美一级片免费看| 国产精品乱码一区二三区小蝌蚪| 亚洲国产精品视频| 99这里都是精品| 欧美videofree性高清杂交| 一区二区三区免费观看| 国产成人在线看|