<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ALL is Well!

    敏捷是一條很長的路,摸索著前進著

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      30 隨筆 :: 23 文章 :: 71 評論 :: 0 Trackbacks
    繼上一篇 擴展Spring-實現對外部引用的屬性文件的 屬性值 進行加密、解密 ,這次要實現的是對整個外部屬性文件進行加密,Spring在加載這個外部屬性文件時進行解密。
    分析過程與在 擴展Spring-實現對外部引用的屬性文件的 屬性值 進行加密、解密 中介紹的基本一致,只不過這次的入口就在 PropertiesLoaderSupport.java 這個抽象類的loadProperties方法。代碼片段:(注意注釋部分)
        @Override
        
    /**
         * Load properties into the given instance.
         * 
    @param props the Properties instance to load into
         * 
    @throws java.io.IOException in case of I/O errors
         * 
    @see #setLocations
         
    */

        
    protected void loadProperties(Properties props) throws IOException {
            
    if (this.locations != null{
                
    for (int i = 0; i < this.locations.length; i++{
                    Resource location 
    = this.locations[i];
                    
    if (logger.isInfoEnabled()) {
                        logger.info(
    "Loading properties file from " + location);
                    }

                    InputStream is 
    = null;
                    
    try {
                        
    // 屬性文件的輸入流
                        
    // 因為這個屬性文件是我們事先加密過的
                        
    // 所以在這里我們只要將此輸入流解密 再將其作為輸入流返回
                        
    // 其他的工作就按照Spring的流程即可
                        is = location.getInputStream();
                        
    if (location.getFilename().endsWith(XML_FILE_EXTENSION)) {
                            
    this.propertiesPersister.loadFromXml(props, is);
                        }
     else {
                            
    if (this.fileEncoding != null{
                                
    this.propertiesPersister.load(props, new InputStreamReader(is,
                                    
    this.fileEncoding));
                            }
     else {
                                
    this.propertiesPersister.load(props, is);
                            }

                        }

                    }
     catch (IOException ex) {
                        
    if (this.ignoreResourceNotFound) {
                            
    if (logger.isWarnEnabled()) {
                                logger.warn(
    "Could not load properties from " + location + ""
                                    
    + ex.getMessage());
                            }

                        }
     else {
                            
    throw ex;
                        }

                    }
     finally {
                        
    if (is != null{
                            is.close();
                        }

                    }

                }

            }

        }

    開始我們的實現過程:
    1.生成密鑰:DesUtil.java 這其中包括生成密鑰,對文件進行加密、解密操作。
    此解密方法返回輸入流對象,以便在 spring的loadProperties方法中使用。
    最終密鑰文件生成為:mytest.key
    package com.sec;

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.security.Key;
    import java.security.SecureRandom;

    import javax.crypto.Cipher;
    import javax.crypto.CipherInputStream;
    import javax.crypto.CipherOutputStream;
    import javax.crypto.KeyGenerator;

    import org.apache.commons.io.IOUtils;

    public class DesUtil {
        
    /**
         * 生成密鑰
         * 
         * 
    @param keyPath 密鑰文件
         
    */

        
    public static void createDesKey(String keyPath) {
            FileOutputStream fos 
    = null;
            ObjectOutputStream oos 
    = null;
            
    try {
                SecureRandom sr 
    = new SecureRandom();
                KeyGenerator kg 
    = KeyGenerator.getInstance("DES");
                kg.init(sr);
                fos 
    = new FileOutputStream(keyPath);
                oos 
    = new ObjectOutputStream(fos);
                
    // 生成密鑰
                Key key = kg.generateKey();
                oos.writeObject(key);
            }
     catch (Exception e) {
                e.printStackTrace();
            }
     finally {
                IOUtils.closeQuietly(fos);
                IOUtils.closeQuietly(oos);
            }

        }


        
    /**
         * 獲得密鑰
         * 
         * 
    @param keyPath
         * 
    @return
         
    */

        
    public static Key getKey(String keyPath) {
            Key kp 
    = null;
            InputStream is 
    = null;
            ObjectInputStream ois 
    = null;
            
    try {
                is 
    = ClassLoader.getSystemClassLoader().getResourceAsStream(keyPath);
                
    return getKey(is);
            }
     catch (Exception e) {
                e.printStackTrace();
            }
     finally {
                IOUtils.closeQuietly(is);
                IOUtils.closeQuietly(ois);
            }

            
    return kp;
        }

        
        
    /**
         * 獲得密鑰
         * 
    @param is
         * 
    @return
         
    */

        
    public static Key getKey(InputStream is) {
            Key key 
    = null;
            ObjectInputStream ois 
    = null;
            
    try {
                ois 
    = new ObjectInputStream(is);
                key 
    = (Key)ois.readObject();
            }
     catch (Exception e) {
                e.printStackTrace();
            }
     finally {
                IOUtils.closeQuietly(ois);
            }

            
    return key;
        }


        
    /**
         * 加密源文件并保存到目標文件
         * 
         * 
    @param srcFile
         *            源文件
         * 
    @param destFile
         *            目標文件
         * 
    @param key
         *            加密用的Key
         * 
    @throws Exception
         
    */

        
    public static void encrypt(String srcFile, String destFile, Key key) throws Exception {
            InputStream is 
    = null;
            OutputStream out 
    = null;
            CipherInputStream cis 
    = null;
            
    try {
                Cipher cipher 
    = Cipher.getInstance("DES");
                cipher.init(Cipher.ENCRYPT_MODE, key);
                is 
    = ClassLoader.getSystemClassLoader().getResourceAsStream(srcFile);
                out 
    = new FileOutputStream(destFile);
                cis 
    = new CipherInputStream(is, cipher);
                
    byte[] buffer = new byte[1024];
                
    int r;
                
    while ((r = cis.read(buffer)) > 0{
                    out.write(buffer, 
    0, r);
                }

            }
     finally {
                IOUtils.closeQuietly(cis);
                IOUtils.closeQuietly(is);
                IOUtils.closeQuietly(out);
            }


        }


        
    /**
         * 解密文件
         * 
         * 
    @param file
         * 
    @param key
         * 
    @return
         * 
    @throws Exception
         
    */

        
    public static InputStream decrypt(InputStream is, Key key) throws Exception {
            OutputStream out 
    = null;
            CipherOutputStream cos 
    = null;
            ByteArrayOutputStream bout 
    = null;
            
    try {
                Cipher cipher 
    = Cipher.getInstance("DES");
                cipher.init(Cipher.DECRYPT_MODE, key);

                bout 
    = new ByteArrayOutputStream();
                
    byte[] buf = new byte[1024];
                
    int count = 0;
                
    while ((count = is.read(buf)) != -1{
                    bout.write(buf, 
    0, count);
                    buf 
    = new byte[1024];
                }

                
    byte[] orgData = bout.toByteArray();
                
    byte[] raw = cipher.doFinal(orgData);
                
    return new ByteArrayInputStream(raw);
            }
     finally {
                IOUtils.closeQuietly(cos);
                IOUtils.closeQuietly(out);
                IOUtils.closeQuietly(bout);
            }

        }

    }


    2.對jdbc.properties文件進行加密:加密的方法為DesUtil的encrypt方法。
    jdbc.properties內容如下:
    driver=oracle.jdbc.OracleDriver
    dburl
    =jdbc:oracle:thin:@127.0.0.1:1521:root
    username
    =blogjava
    password
    =javadesps

    加密后得到文件desJdbc.properties,其內容如下:
    (ä8i6n??O?IÏ,d¢M?Ö?Ç??äðëñÖn$BÞ?d|ê?¾. ÓF—pêLylGýÓ?$Iv'ÕJô

    3.為了進行測試,新建SpringTestBean.java類,該類中只包含driver、url、username、password屬性以及get、set方法。
    package com.spring;

    import org.apache.commons.lang.builder.ToStringBuilder;
    import org.apache.commons.lang.builder.ToStringStyle;

    public class SpringTestBean {
        
    private String driver   = null;
        
    private String url      = null;
        
    private String username = null;
        
    private String password = null;
        
    //  get set 方法略

        
    /**
         * 重寫toString方法 觀察測試結果用
         
    */

        @Override
        
    public String toString() {
            
    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("driver", driver)
                .append(
    "url", url).append("username", username).append("password", password)
                .toString();
        }

    }


    4.配置applicationContext.xml文件。內容如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans
        
    xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop
    ="http://www.springframework.org/schema/aop"
        xmlns:tx
    ="http://www.springframework.org/schema/tx"
        xmlns:context
    ="http://www.springframework.org/schema/context"
        xsi:schemaLocation
    ="http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                            http://www.springframework.org/schema/aop 
                            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
                            http://www.springframework.org/schema/tx 
                            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
                            http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context-2.5.xsd"

               default-lazy-init
    ="true">
        
        
    <bean id="propertyConfigurer"
            class
    ="com.spring.DecryptPropertyPlaceholderConfigurer">
            
    <property name="locations">
                
    <list>      
                    
    <value>classpath:com/spring/desJdbc.properties</value><!-- 加密后文件 -->
                
    </list>
            
    </property>
            
    <property name="fileEncoding" value="utf-8"/> 
            
    <property name="keyLocation" value="classpath:com/spring/mytest.key" /><!-- 密鑰文件位置 -->
        
    </bean> 
       
       
    <!-- 測試用bean -->
        
    <bean id="testBean" class="com.spring.SpringTestBean" destroy-method="close">
            
    <property name="driver" value="${driver}" />
            
    <property name="url" value="${dburl}" />
            
    <property name="username" value="${username}" /> 
            
    <property name="password" value="${password}" />
        
    </bean>
    </beans>

    5.實現自己的PropertyPlaceholderConfigurer類----DecryptPropertyPlaceholderConfigurer.java,繼承自Spring的PropertyPlaceholderConfigurer類:
    package com.spring;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.Properties;

    import org.apache.commons.io.IOUtils;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    import org.springframework.core.io.Resource;
    import org.springframework.util.DefaultPropertiesPersister;
    import org.springframework.util.PropertiesPersister;

    import com.sec.DesUtil;

    public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
        
    private Resource[]          locations;
        
    private Resource            keyLocation;
        
    private PropertiesPersister propertiesPersister    = new DefaultPropertiesPersister();
        
    private String              fileEncoding           = "utf-8";
        
    private boolean             ignoreResourceNotFound = false;

        @Override
        
    public void setLocations(Resource[] locations) {
            
    this.locations = locations;
        }


        @Override
        
    public void setFileEncoding(String encoding) {
            
    this.fileEncoding = encoding;
        }


        @Override
        
    public void setIgnoreResourceNotFound(boolean ignoreResourceNotFound) {
            
    this.ignoreResourceNotFound = ignoreResourceNotFound;
        }


        
    public void setKeyLocation(Resource keyLocation) {
            
    this.keyLocation = keyLocation;
        }


        @Override
        
    /**
         * Load properties into the given instance.
         * 
    @param props the Properties instance to load into
         * 
    @throws java.io.IOException in case of I/O errors
         * 
    @see #setLocations
         
    */

        
    protected void loadProperties(Properties props) throws IOException {
            
    if (this.locations != null{
                
    for (int i = 0; i < this.locations.length; i++{
                    Resource location 
    = this.locations[i];
                    InputStream is 
    = null;        // 屬性文件輸入流
                    InputStream keyStream = null// 密鑰輸入流
                    InputStream readIs = null;    // 解密后屬性文件輸入流
                    try {
                        
    // 屬性文件輸入流
                        is = location.getInputStream();
                        
    // 密鑰輸入流
                        keyStream = keyLocation.getInputStream();
                        
    // 得到解密后的輸入流對象
                        readIs = DesUtil.decrypt(is, DesUtil.getKey(keyStream));
                        
    // 以下操作按照Spring的流程做即可
                        if (location.getFilename().endsWith(XML_FILE_EXTENSION)) {
                            
    this.propertiesPersister.loadFromXml(props, readIs);
                        }
     else {
                            
    if (this.fileEncoding != null{
                                
    this.propertiesPersister.load(props, new InputStreamReader(readIs,
                                    
    this.fileEncoding));
                            }
     else {
                                
    this.propertiesPersister.load(props, readIs);
                            }

                        }

                    }
     catch (Exception ex) {
                        
    if (this.ignoreResourceNotFound) {
                            
    if (logger.isWarnEnabled()) {
                                logger.warn(
    "Could not load properties from " + location + ""
                                    
    + ex.getMessage());
                            }

                        }

                    }
     finally {
                        IOUtils.closeQuietly(is);
                        IOUtils.closeQuietly(keyStream);
                        IOUtils.closeQuietly(readIs);
                    }

                }

            }

        }

    }



    6.測試代碼:SpringCryptTest.java,這個代碼很簡單,就是用Spring去取得我們的測試bean----SpringTestBean,打印它的屬性,測試已經加密過的desJdbc.properties文件,能否被Spring正確解密并加載。
    package com.spring;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class SpringCryptTest {
        
    public static void main(String args[]) {
            ClassPathXmlApplicationContext ctx 
    = new ClassPathXmlApplicationContext(
                
    "com/spring/applicationContext.xml");
            SpringTestBean bean 
    = (SpringTestBean)ctx.getBean("testBean");
            System.out.println(bean.toString());
        }

    }

    執行結果:
    SpringTestBean[driver=oracle.jdbc.OracleDriver,url=jdbc:oracle:thin:@127.0.0.1:1521:root,username=blogjava,password=javadesps]

    OK。到此,Spring已經正確解密并加載了此外部屬性文件。

    本文為原創,歡迎轉載,轉載請注明出處BlogJava
    posted on 2010-10-02 12:44 李 明 閱讀(4376) 評論(8)  編輯  收藏 所屬分類: Spring

    評論

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-06-13 17:05 gsf
    我測試不成功啊
      回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-06-13 17:05 gsf
    我的QQ:407584979  回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-09-13 11:28 admin_yin
    @gsf
    我測試也沒有成功,請問你的可以了嗎?QQ:26509925  回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-09-18 21:32 李 明
    把不成功的信息發一下,比如出現什么樣的情況,描述一下,有異常,貼一下。@gsf
      回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-09-18 21:32 李 明
    把不成功的信息發一下,比如出現什么樣的情況,描述一下,有異常,貼一下。@admin_yin
      回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-09-19 18:07 admin_yin
    @李 明
    我測試時成功了,但是要是連接數據庫話,不知在application中怎么配置了,目前配置如:
    <bean id="propertyConfigurer"
    class="config.ReadEncryptedPropertyPlaceholderConfigurer">
    <property name="locations">
    <list>
    <value>classpath:config/db.properties</value><!-- 加密后文件 -->
    </list>
    </property>
    <property name="fileEncoding" value="utf-8"/>
    <property name="keyLocation" value="classpath:config/key.dat" /><!-- 密鑰文件位置 -->
    </bean>

    <!-- 測試用bean -->
    <bean id="testBean" class="config.SpringTestBean" >
    <property name="driver" value="${driver}"/>
    <property name="url" value="${dburl}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />
    </bean>


    <bean id="datasource"
    class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName"
    value="com.microsoft.sqlserver.jdbc.SQLServerDriver">
    </property>
    <!-- <property name="url"-->
    <!-- value="jdbc:sqlserver://localhost:1433;DatabaseName=stu">-->
    <!-- </property>-->
    <!-- <property name="username" value="sa"></property>-->
    <!-- <property name="password" value="sa"></property>-->
    </bean>
    <bean id="sessionfactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
    <ref bean="datasource" />
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    org.hibernate.dialect.SQLServerDialect
    </prop>
    </props>
    </property>
    <property name="mappingResources">
    <list>
    <value>vo/Student.hbm.xml</value></list>
    </property>
    </bean>
    <bean id="StudentDAO" class="vo.StudentDAO">
    <property name="sessionFactory">
    <ref bean="sessionfactory" />
    </property>
    </bean>  回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-09-20 11:52 admin_yin
    @李 明
    我在Spring里面配置,當啟動Tomcat的時候能解密,但是出現了如以下的錯誤:
    信息: Initializing Spring root WebApplicationContext
    dburl=jdbc:sqlserver://localhost:1433;databaseName=stu

    password=sa

    driver=com.microsoft.sqlserver.jdbc.SQLServerDriver

    username=sa

    2011-9-20 11:49:33 org.apache.catalina.core.StandardContext listenerStart
    嚴重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'datasource' defined in class path resource [applicationContext.xml]: Could not resolve placeholder 'driver'
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:268)
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:75)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:553)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:527)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:362)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3843)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4342)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:926)
    at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:889)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1149)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
    at org.apache.catalina.core.StandardService.start(StandardService.java:516)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:578)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
    2011-9-20 11:49:33 org.apache.catalina.core.StandardContext start

    ----------------------------------------------------
    難道配置不對嗎?配置
    <bean id="propertyConfigurer"
    class="test0x31.ReadEncryptedPropertyPlaceholderConfigurer">
    <property name="locations">
    <list>
    <value>classpath:db.properties</value><!-- 加密后文件 -->
    </list>
    </property>
    <property name="fileEncoding" value="utf-8"/>
    <!-- <property name="keyLocation" value="classpath:config/key.dat" /> 密鑰文件位置 -->
    </bean>
    <bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${driver}"/>
    <property name="url" value="${dburl}" />
    <property name="username" value="${username}" />
    <property name="password" value="${password}" />
    </bean>
    <bean id="sessionfactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
    <ref bean="datasource" />
    </property>
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">
    org.hibernate.dialect.SQLServerDialect
    </prop>
    </props>
    </property>
    <property name="mappingResources">
    <list>
    <value>vo/Student.hbm.xml</value></list>
    </property>
    </bean>
    <bean id="StudentDAO" class="vo.StudentDAO">
    <property name="sessionFactory">
    <ref bean="sessionfactory" />
    </property>
    </bean>  回復  更多評論
      

    # re: 擴展Spring-實現對外部引用的屬性文件進行加密、解密 2011-09-25 09:43 李 明
    根據你的異常信息是說 沒有 placeholder 關鍵字 driver,你檢查一下config/db.properties 的配置,是否配置了 driver,或者關鍵字有沒有寫錯。@admin_yin
      回復  更多評論
      

    主站蜘蛛池模板: 日本亚洲中午字幕乱码| 亚洲精品美女久久777777| 成人免费无毒在线观看网站| 1000部羞羞禁止免费观看视频| a级毛片免费全部播放| 成年免费a级毛片免费看无码 | 日韩精品视频免费观看| 成熟女人特级毛片www免费| 免费无码A片一区二三区| 毛片免费观看网站| 免费无码看av的网站| 国产成人在线观看免费网站 | 亚洲av午夜精品一区二区三区| 国产无遮挡吃胸膜奶免费看视频| 免费观看a级毛片| 国产精品酒店视频免费看| 免费大黄网站在线观| 亚洲VA综合VA国产产VA中| 国产亚洲人成A在线V网站| 久久亚洲国产午夜精品理论片| 亚洲成AV人片在| 久久亚洲AV成人无码| 亚洲冬月枫中文字幕在线看| 亚洲人成www在线播放| 亚洲av成人中文无码专区| 免费一区二区三区在线视频 | 在线aⅴ亚洲中文字幕| 麻豆亚洲AV成人无码久久精品 | 亚洲精品国产高清在线观看| 在线看亚洲十八禁网站| 久久免费观看视频| 久久久国产精品无码免费专区| 亚洲精品免费在线观看| 免费福利网站在线观看| 又爽又黄无遮挡高清免费视频| 亚洲一区二区三区香蕉| 久久久久久亚洲Av无码精品专口 | 亚洲三级中文字幕| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 在线观看亚洲免费视频| 国产午夜精品免费一区二区三区|