精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何優雅的實現 Spring Boot 接口參數加密解密?

安全 應用安全
加密解密本身并不是難事,問題是在何時去處理?定義一個過濾器,將請求和響應分別攔截下來進行處理也是一個辦法,這種方式雖然粗暴,但是靈活,因為可以拿到一手的請求參數和響應數據。

因為有小伙伴剛好問到這個問題,松哥就抽空擼一篇文章和大家聊聊這個話題。

加密解密本身并不是難事,問題是在何時去處理?定義一個過濾器,將請求和響應分別攔截下來進行處理也是一個辦法,這種方式雖然粗暴,但是靈活,因為可以拿到一手的請求參數和響應數據。不過 SpringMVC 中給我們提供了 ResponseBodyAdvice 和 RequestBodyAdvice,利用這兩個工具可以對請求和響應進行預處理,非常方便。

所以今天這篇文章有兩個目的:

  • 分享參數/響應加解密的思路。
  • 分享 ResponseBodyAdvice 和 RequestBodyAdvice 的用法。

好了,那么接下來就不廢話了,我們一起來看下。

1.開發加解密 starter

為了讓我們開發的這個工具更加通用,也為了復習一下自定義 Spring Boot Starter,這里我們就將這個工具做成一個 stater,以后在 Spring Boot 項目中直接引用就可以。

首先我們創建一個 Spring Boot 項目,引入 spring-boot-starter-web 依賴:

  1. <dependency> 
  2.     <groupId>org.springframework.boot</groupId> 
  3.     <artifactId>spring-boot-starter-web</artifactId> 
  4.     <scope>provided</scope> 
  5.     <version>2.4.3</version> 
  6. </dependency> 

因為我們這個工具是為 Web 項目開發的,以后必然使用在 Web 環境中,所以這里添加依賴時 scope 設置為 provided。

依賴添加完成后,我們先來定義一個加密工具類備用,加密這塊有多種方案可以選擇,對稱加密、非對稱加密,其中對稱加密又可以使用 AES、DES、3DES 等不同算法,這里我們使用 Java 自帶的 Cipher 來實現對稱加密,使用 AES 算法:

  1. public class AESUtils { 
  2.  
  3.     private static final String AES_ALGORITHM = "AES/ECB/PKCS5Padding"
  4.  
  5.     // 獲取 cipher 
  6.     private static Cipher getCipher(byte[] keyint model) throws Exception { 
  7.         SecretKeySpec secretKeySpec = new SecretKeySpec(key"AES"); 
  8.         Cipher cipher = Cipher.getInstance(AES_ALGORITHM); 
  9.         cipher.init(model, secretKeySpec); 
  10.         return cipher; 
  11.     } 
  12.  
  13.     // AES加密 
  14.     public static String encrypt(byte[] data, byte[] key) throws Exception { 
  15.         Cipher cipher = getCipher(key, Cipher.ENCRYPT_MODE); 
  16.         return Base64.getEncoder().encodeToString(cipher.doFinal(data)); 
  17.     } 
  18.  
  19.     // AES解密 
  20.     public static byte[] decrypt(byte[] data, byte[] key) throws Exception { 
  21.         Cipher cipher = getCipher(key, Cipher.DECRYPT_MODE); 
  22.         return cipher.doFinal(Base64.getDecoder().decode(data)); 
  23.     } 

這個工具類比較簡單,不需要多解釋。需要說明的是,加密后的數據可能不具備可讀性,因此我們一般需要對加密后的數據再使用 Base64 算法進行編碼,獲取可讀字符串。換言之,上面的 AES 加密方法的返回值是一個 Base64 編碼之后的字符串,AES 解密方法的參數也是一個 Base64 編碼之后的字符串,先對該字符串進行解碼,然后再解密。

接下來我們封裝一個響應工具類備用,這個大家如果經??此筛缫曨l已經很了解了:

  1. public class RespBean { 
  2.     private Integer status; 
  3.     private String msg; 
  4.     private Object obj; 
  5.  
  6.     public static RespBean build() { 
  7.         return new RespBean(); 
  8.     } 
  9.  
  10.     public static RespBean ok(String msg) { 
  11.         return new RespBean(200, msg, null); 
  12.     } 
  13.  
  14.     public static RespBean ok(String msg, Object obj) { 
  15.         return new RespBean(200, msg, obj); 
  16.     } 
  17.  
  18.     public static RespBean error(String msg) { 
  19.         return new RespBean(500, msg, null); 
  20.     } 
  21.  
  22.     public static RespBean error(String msg, Object obj) { 
  23.         return new RespBean(500, msg, obj); 
  24.     } 
  25.  
  26.     private RespBean() { 
  27.     } 
  28.  
  29.     private RespBean(Integer status, String msg, Object obj) { 
  30.         this.status = status; 
  31.         this.msg = msg; 
  32.         this.obj = obj; 
  33.     } 
  34.  
  35.     public Integer getStatus() { 
  36.         return status; 
  37.     } 
  38.  
  39.     public RespBean setStatus(Integer status) { 
  40.         this.status = status; 
  41.         return this; 
  42.     } 
  43.  
  44.     public String getMsg() { 
  45.         return msg; 
  46.     } 
  47.  
  48.     public RespBean setMsg(String msg) { 
  49.         this.msg = msg; 
  50.         return this; 
  51.     } 
  52.  
  53.     public Object getObj() { 
  54.         return obj; 
  55.     } 
  56.  
  57.     public RespBean setObj(Object obj) { 
  58.         this.obj = obj; 
  59.         return this; 
  60.     } 

接下來我們定義兩個注解 @Decrypt 和 @Encrypt:

  1. @Retention(RetentionPolicy.RUNTIME) 
  2. @Target({ElementType.METHOD,ElementType.PARAMETER}) 
  3. public @interface Decrypt { 
  4. @Retention(RetentionPolicy.RUNTIME) 
  5. @Target(ElementType.METHOD) 
  6. public @interface Encrypt { 

這兩個注解就是兩個標記,在以后使用的過程中,哪個接口方法添加了 @Encrypt 注解就對哪個接口的數據加密返回,哪個接口/參數添加了 @Decrypt 注解就對哪個接口/參數進行解密。這個定義也比較簡單,沒啥好說的,需要注意的是 @Decrypt比 @Encrypt 多了一個使用場景就是 @Decrypt 可以用在參數上。

考慮到用戶可能會自己配置加密的 key,因此我們再來定義一個 EncryptProperties 類來讀取用戶配置的 key:

  1. @ConfigurationProperties(prefix = "spring.encrypt"
  2. public class EncryptProperties { 
  3.     private final static String DEFAULT_KEY = "www.itboyhub.com"
  4.     private String key = DEFAULT_KEY; 
  5.  
  6.     public String getKey() { 
  7.         return key
  8.     } 
  9.  
  10.     public void setKey(String key) { 
  11.         this.key = key
  12.     } 

這里我設置了默認的 key 是 www.itboyhub.com,key 是 16 位字符串,松哥這個網站地址剛好滿足。以后如果用戶想自己配置 key,只需要在 application.properties 中配置 spring.encrypt.key=xxx 即可。

所有準備工作做完了,接下來就該正式加解密了。

因為松哥這篇文章一個很重要的目的是想和大家分享 ResponseBodyAdvice 和 RequestBodyAdvice 的用法,RequestBodyAdvice 在做解密的時候倒是沒啥問題,而 ResponseBodyAdvice 在做加密的時候則會有一些局限,不過影響不大,還是我前面說的,如果想非常靈活的掌控一切,那還是自定義過濾器吧。這里我就先用這兩個工具來實現了。

另外還有一點需要注意,ResponseBodyAdvice 在你使用了 @ResponseBody 注解的時候才會生效,RequestBodyAdvice 在你使用了 @RequestBody 注解的時候才會生效,換言之,前后端都是 JSON 交互的時候,這兩個才有用。不過一般來說接口加解密的場景也都是前后端分離的時候才可能有的事。

先來看接口加密:

  1. @EnableConfigurationProperties(EncryptProperties.class) 
  2. @ControllerAdvice 
  3. public class EncryptResponse implements ResponseBodyAdvice<RespBean> { 
  4.     private ObjectMapper om = new ObjectMapper(); 
  5.     @Autowired 
  6.     EncryptProperties encryptProperties; 
  7.     @Override 
  8.     public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { 
  9.         return returnType.hasMethodAnnotation(Encrypt.class); 
  10.     } 
  11.  
  12.     @Override 
  13.     public RespBean beforeBodyWrite(RespBean body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { 
  14.         byte[] keyBytes = encryptProperties.getKey().getBytes(); 
  15.         try { 
  16.             if (body.getMsg()!=null) { 
  17.                 body.setMsg(AESUtils.encrypt(body.getMsg().getBytes(),keyBytes)); 
  18.             } 
  19.             if (body.getObj() != null) { 
  20.                 body.setObj(AESUtils.encrypt(om.writeValueAsBytes(body.getObj()), keyBytes)); 
  21.             } 
  22.         } catch (Exception e) { 
  23.             e.printStackTrace(); 
  24.         } 
  25.         return body; 
  26.     } 

我們自定義 EncryptResponse 類實現 ResponseBodyAdvice接口,泛型表示接口的返回類型,這里一共要實現兩個方法:

  1. supports:這個方法用來判斷什么樣的接口需要加密,參數 returnType 表示返回類型,我們這里的判斷邏輯就是方法是否含有 @Encrypt 注解,如果有,表示該接口需要加密處理,如果沒有,表示該接口不需要加密處理。
  2. beforeBodyWrite:這個方法會在數據響應之前執行,也就是我們先對響應數據進行二次處理,處理完成后,才會轉成 json 返回。我們這里的處理方式很簡單,RespBean 中的 status 是狀態碼就不用加密了,另外兩個字段重新加密后重新設置值即可。
  3. 另外需要注意,自定義的 ResponseBodyAdvice 需要用 @ControllerAdvice 注解來標記。

再來看接口解密:

  1. @EnableConfigurationProperties(EncryptProperties.class) 
  2. @ControllerAdvice 
  3. public class DecryptRequest extends RequestBodyAdviceAdapter { 
  4.     @Autowired 
  5.     EncryptProperties encryptProperties; 
  6.     @Override 
  7.     public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { 
  8.         return methodParameter.hasMethodAnnotation(Decrypt.class) || methodParameter.hasParameterAnnotation(Decrypt.class); 
  9.     } 
  10.  
  11.     @Override 
  12.     public HttpInputMessage beforeBodyRead(final HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { 
  13.         byte[] body = new byte[inputMessage.getBody().available()]; 
  14.         inputMessage.getBody().read(body); 
  15.         try { 
  16.             byte[] decrypt = AESUtils.decrypt(body, encryptProperties.getKey().getBytes()); 
  17.             final ByteArrayInputStream bais = new ByteArrayInputStream(decrypt); 
  18.             return new HttpInputMessage() { 
  19.                 @Override 
  20.                 public InputStream getBody() throws IOException { 
  21.                     return bais; 
  22.                 } 
  23.  
  24.                 @Override 
  25.                 public HttpHeaders getHeaders() { 
  26.                     return inputMessage.getHeaders(); 
  27.                 } 
  28.             }; 
  29.         } catch (Exception e) { 
  30.             e.printStackTrace(); 
  31.         } 
  32.         return super.beforeBodyRead(inputMessage, parameter, targetType, converterType); 
  33.     } 
  1. 首先大家注意,DecryptRequest 類我們沒有直接實現 RequestBodyAdvice 接口,而是繼承自 RequestBodyAdviceAdapter 類,該類是 RequestBodyAdvice 接口的子類,并且實現了接口中的一些方法,這樣當我們繼承自 RequestBodyAdviceAdapter 時,就只需要根據自己實際需求實現某幾個方法即可。
  2. supports:該方法用來判斷哪些接口需要處理接口解密,我們這里的判斷邏輯是方法上或者參數上含有 @Decrypt 注解的接口,處理解密問題。
  3. beforeBodyRead:這個方法會在參數轉換成具體的對象之前執行,我們先從流中加載到數據,然后對數據進行解密,解密完成后再重新構造 HttpInputMessage 對象返回。

接下來,我們再來定義一個自動化配置類,如下:

  1. @Configuration 
  2. @ComponentScan("org.javaboy.encrypt.starter"
  3. public class EncryptAutoConfiguration { 
  4.  

這個也沒啥好說的,比較簡單。

最后,resources 目錄下定義 META-INF,然后再定義 spring.factories 文件,內容如下:

  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.javaboy.encrypt.starter.autoconfig.EncryptAutoConfiguration 

這樣當項目啟動時,就會自動加載該配置類。

至此,我們的 starter 就開發完成啦。

2.打包發布

我們可以將項目安裝到本地倉庫,也可以發布到線上供他人使用。

2.1 安裝到本地倉庫

安裝到本地倉庫比較簡單,直接 mvn install,或者在 IDEA 中,點擊右邊的 Maven,然后雙擊 install,如下:

 

2.2 發布到線上

發不到線上我們可以使用 JitPack 來做。

首先我們在 GitHub 上創建一個倉庫,將我們的代碼上傳上去,這個過程應該不用我多說吧。

上傳成功后,點擊右邊的 Create a new release 按鈕,發布一個正式版,如下:

 

發布成功后,打開 jitpack,輸入倉庫的完整路徑,點擊 lookup 按鈕,查找到之后,再點擊 Get it 按鈕完成構建,如下:

 

構建成功后,JitPack 上會給出項目引用方式:

 

注意引用時將 tag 改成你具體的版本號。

至此,我們的工具就已經成功發布了!小伙伴們可以通過如下方式引用這個 starter:

  1. <dependencies> 
  2.     <dependency> 
  3.         <groupId>com.github.lenve</groupId> 
  4.         <artifactId>encrypt-spring-boot-starter</artifactId> 
  5.         <version>0.0.3</version> 
  6.     </dependency> 
  7. </dependencies> 
  8. <repositories> 
  9.     <repository> 
  10.         <id>jitpack.io</id> 
  11.         <url>https://jitpack.io</url> 
  12.     </repository> 
  13. </repositories> 

3.應用

我們創建一個普通的 Spring Boot 項目,引入 web 依賴,再引入我們剛剛的 starter 依賴,如下:

  1. <dependencies> 
  2.     <dependency> 
  3.         <groupId>org.springframework.boot</groupId> 
  4.         <artifactId>spring-boot-starter-web</artifactId> 
  5.     </dependency> 
  6.     <dependency> 
  7.         <groupId>com.github.lenve</groupId> 
  8.         <artifactId>encrypt-spring-boot-starter</artifactId> 
  9.         <version>0.0.3</version> 
  10.     </dependency> 
  11.     <dependency> 
  12.         <groupId>org.springframework.boot</groupId> 
  13.         <artifactId>spring-boot-starter-test</artifactId> 
  14.         <scope>test</scope> 
  15.     </dependency> 
  16. </dependencies> 
  17. <repositories> 
  18.     <repository> 
  19.         <id>jitpack.io</id> 
  20.         <url>https://jitpack.io</url> 
  21.     </repository> 
  22. </repositories> 

然后再創建一個實體類備用:

  1. public class User { 
  2.     private Long id; 
  3.     private String username; 
  4.     //省略 getter/setter 

創建兩個測試接口:

  1. @RestController 
  2. public class HelloController { 
  3.     @GetMapping("/user"
  4.     @Encrypt 
  5.     public RespBean getUser() { 
  6.         User user = new User(); 
  7.         user.setId((long) 99); 
  8.         user.setUsername("javaboy"); 
  9.         return RespBean.ok("ok"user); 
  10.     } 
  11.  
  12.     @PostMapping("/user"
  13.     public RespBean addUser(@RequestBody @Decrypt User user) { 
  14.         System.out.println("user = " + user); 
  15.         return RespBean.ok("ok"user); 
  16.     } 

第一個接口使用了 @Encrypt 注解,所以會對該接口的數據進行加密(如果不使用該注解就不加密),第二個接口使用了 @Decrypt 所以會對上傳的參數進行解密,注意 @Decrypt 注解既可以放在方法上也可以放在參數上。

接下來啟動項目進行測試。

首先測試 get 請求接口:

 

可以看到,返回的數據已經加密。

再來測試 post 請求:

 

可以看到,參數中的加密數據已經被還原了。

如果用戶想要修改加密密鑰,可以在 application.properties 中添加如下配置:

spring.encrypt.key=1234567890123456

加密數據到了前端,前端也有一些 js 工具來處理加密數據,這個松哥后面有空再和大家說說 js 的加解密。

 

4.小結

好啦,今天這篇文章主要是想和大家聊聊 ResponseBodyAdvice 和 RequestBodyAdvice 的用法,一些加密思路,當然 ResponseBodyAdvice 和 RequestBodyAdvice 還有很多其他的使用場景,小伙伴們可以自行探索~本文使用了對稱加密中的 AES 算法,大家也可以嘗試改成非對稱加密。

本文轉載自微信公眾號「江南一點雨」,可以通過以下二維碼關注。轉載本文請聯系江南一點雨公眾號。

 

責任編輯:武曉燕 來源: 江南一點雨
相關推薦

2022-06-04 12:25:10

解密加密過濾器

2023-11-01 08:58:10

2025-03-11 00:55:00

Spring停機安全

2022-07-27 08:49:34

接口加密解密

2024-12-06 09:27:28

2024-09-27 15:24:15

Spring數據加解密

2023-03-06 08:49:02

加密和解密SpringBoot

2025-05-14 04:00:00

2022-12-14 09:06:58

接口Spring解密

2024-12-18 12:10:00

2023-10-16 11:12:29

2024-10-18 08:00:00

SpringBoot框架開發

2024-08-02 09:15:22

Spring捕捉格式

2020-12-08 08:08:51

Java接口數據

2025-02-07 09:11:04

JSON對象策略

2025-06-04 01:00:00

2023-09-27 08:14:56

2023-04-17 23:49:09

開發代碼Java

2019-04-15 08:32:25

Spring Boot日志門面模式

2024-05-29 08:12:55

接口參數格式
點贊
收藏

51CTO技術棧公眾號

国产欧美久久一区二区| 中文字幕日韩av电影| 丁香六月激情网| 成人高潮片免费视频| 国产欧美高清| 日韩中文在线中文网在线观看| 97人人爽人人| 两个人看的在线视频www| 国产喂奶挤奶一区二区三区| 91久久精品在线| 五月婷婷激情网| 国产精品成人a在线观看| 欧美xxx久久| 亚洲五月天综合| 懂色av一区| 久久久久久97三级| 国产精品初高中精品久久| 国产男人搡女人免费视频| 欧美日韩18| 中文字幕不卡在线视频极品| youjizz.com日本| 国产成人精品一区二区三区在线| 亚洲精品视频免费观看| 日韩精品欧美在线| 日本黄色三级视频| 狠狠色伊人亚洲综合成人| 91精品国产高清自在线| 蜜桃av免费观看| 图片婷婷一区| 精品久久久网站| 校园春色 亚洲色图| sm久久捆绑调教精品一区| 国产精品美女久久久久高潮| 九色91视频| 亚洲va久久久噜噜噜无码久久| 日日摸夜夜添夜夜添精品视频| 欧美高清视频在线播放| 欧洲性xxxx| 久久av资源| 日韩电影网在线| 18深夜在线观看免费视频| 日韩欧美一区二区三区在线观看| 亚洲高清免费一级二级三级| 国产成人精品免费看在线播放 | 亚洲人成啪啪网站| 亚洲色偷偷色噜噜狠狠99网| 亚洲狼人在线| 欧美人体做爰大胆视频| www.com黄色片| 日产精品一区| 色欧美乱欧美15图片| 免费无码不卡视频在线观看| av影视在线| 亚洲小说欧美激情另类| 欧美一级爱爱视频| 深夜国产在线播放| 亚洲一区二区在线播放相泽 | 国产手机视频一区二区 | 放荡的美妇在线播放| 久久中文亚洲字幕| 北条麻妃99精品青青久久| 国产精品一区二区亚洲| 成人在线电影在线观看视频| 中文字幕国产日韩| 蜜桃av免费在线观看| 久久精品国产99久久| 久久精品视频网站| 国产97免费视频| 激情亚洲成人| 欧美一级大片视频| 国产乡下妇女三片| 激情另类小说区图片区视频区| 成人一区二区电影| 亚洲av综合色区无码一二三区| 成人av在线影院| 久久久久久久有限公司| 九色视频在线播放| 国产精品私人影院| 青春草在线视频免费观看| 深夜国产在线播放| 色94色欧美sute亚洲线路二| 91网址在线播放| 欧美黄色一级| 亚洲国产欧美一区二区丝袜黑人 | 亚洲97在线观看| 99久热在线精品996热是什么| 性欧美xxxx大乳国产app| 国产精品免费福利| 亚洲精品97久久中文字幕| 99久久99久久久精品齐齐| 欧美黄色直播| av理论在线观看| 午夜精品久久久久久久蜜桃app| aa在线免费观看| 香蕉成人在线| 亚洲激情成人网| 特级西西人体高清大胆| 亚洲视屏一区| 国产精品日韩专区| 好吊视频一区二区三区| 国产喂奶挤奶一区二区三区| av在线免费观看国产| 精品国产第一福利网站| 91精品国产手机| 成人在线一级片| 亚洲天天综合| 亚洲18私人小影院| 波多野结衣mp4| 国产成人精品免费一区二区| 免费观看成人高| 制服丝袜在线播放| 色综合av在线| 亚洲欧美日韩偷拍| 久久国产综合| 欧美专区日韩视频| 亚洲h视频在线观看| 中文字幕欧美国产| jizzjizz国产精品喷水| 九九99久久精品在免费线bt| 亚洲深夜福利在线| 日本一二三区不卡| 国产精品自拍网站| 中文字幕欧美人与畜| 自拍视频在线看| 精品国产乱码久久久久久影片| 一本色道久久88| 日韩影院免费视频| 久久精品五月婷婷| 99在线视频影院| 日韩视频在线观看一区二区| 女人裸体性做爰全过| 日韩成人免费电影| 老司机精品福利在线观看| av电影在线地址| 欧美一卡二卡三卡| 糖心vlog免费在线观看| 蜜臀久久99精品久久久久久9| 免费国产一区二区| 色偷偷偷在线视频播放| 亚洲国产成人精品一区二区| 欧美日韩在线国产| 国产精品一区免费在线观看| 一道精品一区二区三区| 成人在线观看免费视频| 亚洲性69xxxbbb| 无码人妻丰满熟妇区五十路| 91麻豆精品在线观看| 日本a视频在线观看| 2020最新国产精品| 国内精品久久久久久| 六月丁香色婷婷| 亚洲va韩国va欧美va| 人妻激情偷乱频一区二区三区| 激情成人亚洲| 国产欧美一区二区三区不卡高清| 国产盗摄一区二区| 精品剧情在线观看| 影音先锋亚洲天堂| 国产亚洲精品超碰| 一级在线免费视频| 亚洲第一天堂| 91在线精品观看| 国产第一页在线视频| 日韩麻豆第一页| 中国a一片一级一片| 中文字幕一区日韩精品欧美| 亚洲天堂av一区二区三区| 亚洲欧美综合| 国产精选一区二区| 国产免费不卡| 最近中文字幕2019免费| 国产美女免费看| 亚洲永久免费av| 久久久久国产精品无码免费看| 亚洲深夜av| 亚洲激情图片| 精品麻豆剧传媒av国产九九九| 欧美激情一级欧美精品| 在线观看xxx| 欧美性猛交xxxxxx富婆| 日韩在线中文字幕视频| av欧美精品.com| 天堂社区在线视频| 一区二区在线| 久久久久久亚洲精品不卡4k岛国| 成人亚洲视频| 欧美激情日韩图片| 国产日本在线视频| 日韩欧美一区在线| 无码日韩精品一区二区| 国产精品成人在线观看| 深田咏美中文字幕| 日本午夜精品视频在线观看| 水蜜桃在线免费观看| 亚洲天堂日韩在线| 91精品视频播放| 激情视频网站在线播放色| 精品久久久av| 免费在线稳定资源站| 欧美一区欧美二区| 国产真人无遮挡作爱免费视频| 亚洲精品国产无天堂网2021 | 色一情一乱一伦一区二区三区日本| 97视频热人人精品免费| 激情视频一区二区| 国产精品日韩精品在线播放| 17婷婷久久www| 中文字幕伦理免费在线视频| 亚洲欧美一区二区激情| 欧美在线 | 亚洲| 欧美男人的天堂一二区| 国产成人免费观看视频| 一区二区三区在线观看动漫| 国产一区二区三区精品在线| 成人网在线播放| 婷婷中文字幕在线观看| 日韩精品1区2区3区| 国产freexxxx性播放麻豆| 图片区亚洲欧美小说区| 欧美在线播放一区| 豆花视频一区二区| 3d动漫啪啪精品一区二区免费| 亚洲a∨精品一区二区三区导航| 久久全球大尺度高清视频| 成人免费观看视频大全| 国产一区二区日韩| 欧洲天堂在线观看| 亚洲成人网在线| 国产夫妻自拍av| 3d动漫精品啪啪1区2区免费| 懂色av蜜臀av粉嫩av喷吹| 欧美日韩一区二区三区在线免费观看| 麻豆影视在线播放| 亚洲欧美区自拍先锋| 日韩精品久久久久久久的张开腿让| 91丨porny丨首页| 中文在线观看免费视频| 成人黄色在线视频| 日本性生活一级片| 国产激情偷乱视频一区二区三区| av噜噜在线观看| 极品少妇一区二区三区精品视频| 91最新在线观看| 热久久久久久久| 亚洲欧美日韩一级| 蜜桃精品在线观看| 拔插拔插华人永久免费| 久久99久久久欧美国产| 97超碰人人爽| 久久成人免费日本黄色| 91视频这里只有精品| 国产麻豆一精品一av一免费| 91精品视频国产| 国产寡妇亲子伦一区二区| 国产精品一级无码| 成人久久视频在线观看| 老司机午夜免费福利| 91色|porny| 日韩精品电影一区二区| 中文字幕成人av| 我要看黄色一级片| 亚洲精品综合在线| 国产奶水涨喷在线播放| 欧美日韩一区二区三区| 夜夜躁日日躁狠狠久久av| 欧美剧在线免费观看网站 | 伊人情人网综合| 婷婷久久一区| av日韩在线看| 亚洲一区二区三区高清不卡| 国产成人综合一区| 狠狠色综合播放一区二区| 美女伦理水蜜桃4| 26uuu国产一区二区三区| 欧美激情久久久久久久| 中文字幕日本乱码精品影院| 免费看一级一片| 色88888久久久久久影院野外 | 91精品产国品一二三产区| 国产精品福利片| 国产一区二区视频在线看| 国产一级精品aaaaa看| 欧美日韩高清| 日韩极品视频在线观看 | 少妇一级淫免费播放| 国产高清不卡二三区| 日本丰满少妇裸体自慰| 国产精品免费视频一区| 日本网站在线免费观看| 欧美午夜视频网站| 亚洲福利在线观看视频| 亚洲性生活视频| 羞羞的网站在线观看| 热99久久精品| 亚洲成人五区| 日本在线观看不卡| 欧美久久一区| av污在线观看| caoporm超碰国产精品| 亚洲女同二女同志奶水| 精品日韩美女的视频高清| 亚洲综合网av| 国产偷亚洲偷欧美偷精品| 超碰公开在线| 国产精品精品视频一区二区三区| 国产精品白丝av嫩草影院| 视频在线99| 夜夜精品视频| 宇都宫紫苑在线播放| 欧美国产成人精品| 日本少妇性生活| 3d成人h动漫网站入口| 国产永久免费高清在线观看 | 日韩国产欧美精品在线| 麻豆系列在线观看| 国产成人精品免高潮在线观看| 中文字幕一区图| 曰韩不卡视频| 日本欧美在线观看| 538国产视频| 亚洲一区二区欧美激情| 国产一区二区三区成人| 国产亚洲人成a一在线v站| 欧美gv在线观看| www日韩av| 99久久久久国产精品| www.99av.com| 久久久精品天堂| 国产又大又黑又粗免费视频| 欧美大片在线观看| av电影免费在线观看| 国产在线观看不卡| 日韩一区二区三区免费播放| 日日碰狠狠躁久久躁婷婷| 91在线一区二区| 日韩黄色在线视频| 精品国产a毛片| 91黄页在线观看| 国产私拍一区| 在线国产精品一区| 日本五十肥熟交尾| 亚洲丶国产丶欧美一区二区三区| 精品黑人一区二区三区在线观看 | 欧美第一页在线观看| 欧美美女网站色| 午夜视频在线| 成人日韩在线电影| 亚洲高清影视| 999久久久精品视频| 亚洲色图视频网站| 国产色综合视频| 精品中文字幕乱| 91成人午夜| 国内精品视频一区二区三区| 成人丝袜高跟foot| 成年人免费高清视频| 亚洲精品丝袜日韩| 香蕉成人影院| 亚洲在线欧美| 国产一区二区在线免费观看| 国产日韩欧美在线观看视频| 日韩美女主播在线视频一区二区三区| 亚洲h片在线看| 国产尤物91| 老牛嫩草一区二区三区日本| 黄色三级生活片| 69av一区二区三区| 国内高清免费在线视频| 久久综合毛片| 日本在线观看不卡视频| 亚洲 欧美 国产 另类| 欧美变态tickle挠乳网站| 三妻四妾完整版在线观看电视剧 | 国产在线高清精品| 国产精品观看| 久久精品成人av| 欧美日韩成人高清| 超清av在线| 日产中文字幕在线精品一区| 久色婷婷小香蕉久久| 欧美激情一区二区视频| 国产丝袜一区视频在线观看 | 九色91国产| 美日韩一级片在线观看| 麻豆changesxxx国产| 国产午夜精品全部视频播放| 在线不卡一区| 成人综合视频在线| 亚洲欧洲日韩一区二区三区| 潮喷失禁大喷水aⅴ无码| 图片小说视频色综合| 亚洲国产精品va在线看黑人| 国产精品熟妇一区二区三区四区| 欧美日一区二区三区在线观看国产免| av漫画在线观看| 欧美国产精品一区| 亚洲乱码一区二区三区三上悠亚| 在线中文资源天堂| 久久久久国产精品www| 国产一区国产二区国产三区|