亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java 實(shí)現(xiàn)RSA非對(duì)稱加密算法

瀏覽:9日期:2022-08-10 09:11:54
目錄公鑰與私鑰Java實(shí)現(xiàn)公鑰與私鑰

公鑰與私鑰是成對(duì)的,一般的,我們認(rèn)為的是公鑰加密、私鑰解密、私鑰簽名、公鑰驗(yàn)證,有人說(shuō)成私鑰加密,公鑰解密時(shí)不對(duì)的。

公鑰與私鑰的生成有多種方式,可以通過(guò)程序生成(下文具體實(shí)現(xiàn)),可以通過(guò)openssl工具:

# 生成一個(gè)私鑰,推薦使用1024位的秘鑰,秘鑰以pem格式保存到-out參數(shù)指定的文件中,采用PKCS1格式 openssl genrsa -out rsa.pem 1024 # 生成與私鑰對(duì)應(yīng)的公鑰,生成的是Subject Public Key,一般配合PKCS8格式私鑰使用 openssl rsa -in rsa.pem -pubout -out rsa.pub

RSA生成公鑰與私鑰一般有兩種格式:PKCS1和PKCS8,上面的命令生成的秘鑰是PKCS1格式的,而公鑰是Subject Public Key,一般配合PKCS8格式私鑰使用,所以就可能會(huì)涉及到PKCS1和PKCS8之間的轉(zhuǎn)換:

# PKCS1格式私鑰轉(zhuǎn)換為PKCS8格式私鑰,私鑰直接輸出到-out參數(shù)指定的文件中 openssl pkcs8 -topk8 -inform PEM -in rsa.pem -outform pem -nocrypt -out rsa_pkcs8.pem # PKCS8格式私鑰轉(zhuǎn)換為PKCS1格式私鑰,私鑰直接輸出到-out參數(shù)指定的文件中 openssl rsa -in rsa_pkcs8.pem -out rsa_pkcs1.pem # PKCS1格式公鑰轉(zhuǎn)換為PKCS8格式公鑰,轉(zhuǎn)換后的內(nèi)容直接輸出 openssl rsa -pubin -in rsa.pub -RSAPublicKey_out # PKCS8格式公鑰轉(zhuǎn)換為PKCS1格式公鑰,轉(zhuǎn)換后的內(nèi)容直接輸出 openssl rsa -RSAPublicKey_in -pubout -in rsa.pub

現(xiàn)實(shí)中,我們往往從pem、crt、pfx文件獲取公私和私鑰,crt、pfx的制作可以參考:簡(jiǎn)單的制作ssl證書(shū),并在nginx和IIS中使用,或者使用現(xiàn)成的:https://pan.baidu.com/s/1MJ5YmuZiLBnf-DfNR_6D7A (提取碼:c6tj),密碼都是:123456

Java實(shí)現(xiàn)

為簡(jiǎn)化說(shuō)明介紹,這里我直接封裝了一個(gè)工具類,因?yàn)橐獜膒em、crt、pfx文件獲取公私和私鑰,因此引用了一個(gè)第三方包:BouncyCastle,可以直接在pom.xml中添加依賴:

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.68</version> </dependency>

或者去mvn上下載:跳轉(zhuǎn)

簡(jiǎn)單封裝的RsaUtil.java:

import java.io.FileInputStream;import java.io.FileReader;import java.io.FileWriter;import java.math.BigInteger;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.KeyStore;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;import java.security.Security;import java.security.Signature;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.KeySpec;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.RSAPrivateCrtKeySpec;import java.security.spec.RSAPublicKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Enumeration;import javax.crypto.Cipher;import org.bouncycastle.asn1.ASN1Integer;import org.bouncycastle.asn1.ASN1Primitive;import org.bouncycastle.asn1.DLSequence;import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;import org.bouncycastle.asn1.x509.AlgorithmIdentifier;import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.util.io.pem.PemObject;import org.bouncycastle.util.io.pem.PemReader;import org.bouncycastle.util.io.pem.PemWriter;public class RsaUtil { static {Security.addProvider(new BouncyCastleProvider()); } /** * 隨機(jī)生成密鑰對(duì) * * @param usePKCS8 * 是否采用PKCS8填充模式 */ public static Object[] generateRsaKey(boolean usePKCS8) throws Exception {KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance('RSA', BouncyCastleProvider.PROVIDER_NAME);// 初始化keyPairGen.initialize(1024, new SecureRandom());// 生成一個(gè)密鑰對(duì),保存在keyPair中KeyPair keyPair = keyPairGen.generateKeyPair();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私鑰RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公鑰// 這兩個(gè)公私鑰是PKCS8格式的byte[] publicKeyBytes = publicKey.getEncoded();byte[] privateKeyBytes = privateKey.getEncoded();if (!usePKCS8) { // 將PSCK8格式公私鑰轉(zhuǎn)換為PKCS1格式 publicKeyBytes = pkcs8ToPkcs1(false, publicKeyBytes); privateKeyBytes = pkcs8ToPkcs1(true, privateKeyBytes);}return new Object[] { publicKeyBytes, privateKeyBytes }; } /** * 從Pem文件讀取密鑰對(duì) * * @param reader * 輸入流 * @param pemFileName * pem文件 */ public static byte[] readFromPem(String pemFileName) throws Exception {PemReader pemReader = new PemReader(new FileReader(pemFileName));PemObject pemObject = pemReader.readPemObject();byte[] publicKey = pemObject.getContent();pemReader.close();return publicKey; } /** * 從Pem文件讀取密鑰 * * @param isPrivateKey * 是否是私鑰 * @param buffer * 字節(jié) * @param pemFileName * pem文件 */ public static void writeToPem(byte[] buffer, boolean isPrivateKey, String pemFileName) throws Exception {PemObject pemObject = new PemObject(isPrivateKey ? 'RSA PRIVATE KEY' : 'RSA PUBLIC KEY', buffer);FileWriter fileWriter = new FileWriter(pemFileName);PemWriter pemWriter = new PemWriter(fileWriter);pemWriter.writeObject(pemObject);pemWriter.close(); } /** * 從crt文件讀取公鑰(pkcs8) * * @param crtFileName * crt文件 * @return 公鑰 */ public static byte[] readPublicKeyFromCrt(String crtFileName) throws Exception {CertificateFactory cf = CertificateFactory.getInstance('X.509');X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream(crtFileName));PublicKey publicKey = cert.getPublicKey();return publicKey.getEncoded(); } /** * 從pfx文件讀取秘鑰對(duì)(pkcs8) * * @param pfxFileName * pfx文件 * @return 秘鑰對(duì) */ public static Object[] readFromPfx(String pfxFileName, String password) throws Exception {KeyStore keystore = KeyStore.getInstance('PKCS12');char[] passwordChars = null;if (password == null || password.equals('')) { passwordChars = null;} else { passwordChars = password.toCharArray();}keystore.load(new FileInputStream(pfxFileName), passwordChars);Enumeration<String> enums = keystore.aliases();PrivateKey privateKey = null;Certificate certificate = null;while (enums.hasMoreElements()) { String alias = enums.nextElement(); System.out.println(alias); if (keystore.isKeyEntry(alias)) {privateKey = (PrivateKey) keystore.getKey(alias, passwordChars);certificate = keystore.getCertificate(alias); } if (privateKey != null && certificate != null)break;}if (privateKey == null || certificate == null) { throw new Exception('fail to read key from pfx');}PublicKey publicKey = certificate.getPublicKey();return new Object[] { publicKey.getEncoded(), privateKey.getEncoded() }; } /** * Pkcs8轉(zhuǎn)Pkcs1 * * @param isPrivateKey * 是否是私鑰轉(zhuǎn)換 * @param buffer * Pkcs1秘鑰 * @return Pkcs8秘鑰 * @throws Exception * 加密過(guò)程中的異常信息 */ public static byte[] pkcs8ToPkcs1(boolean isPrivateKey, byte[] buffer) throws Exception {if (isPrivateKey) { PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance(buffer); return privateKeyInfo.parsePrivateKey().toASN1Primitive().getEncoded();} else { SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(buffer); return subjectPublicKeyInfo.parsePublicKey().toASN1Primitive().getEncoded();} } /** * Pkcs1轉(zhuǎn)Pkcs8 * * @param isPrivateKey * 是否是私鑰轉(zhuǎn)換 * @param buffer * Pkcs1秘鑰 * @return Pkcs8秘鑰 * @throws Exception * 加密過(guò)程中的異常信息 */ public static byte[] pkcs1ToPkcs8(boolean isPrivateKey, byte[] buffer) throws Exception {AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption);ASN1Primitive asn1Primitive = ASN1Primitive.fromByteArray(buffer);if (isPrivateKey) { PrivateKeyInfo privateKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Primitive); return privateKeyInfo.getEncoded();} else { SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo(algorithmIdentifier, asn1Primitive); return subjectPublicKeyInfo.getEncoded();} } /** * RSA公鑰 * * @param usePKCS8 * 是否采用PKCS8填充模式 * @param publicKey * 公鑰 * @return 公鑰 * @throws Exception * 加密過(guò)程中的異常信息 */ public static RSAPublicKey generatePublicKey(boolean usePKCS8, byte[] publicKey) throws Exception {KeySpec keySpec;if (usePKCS8) { // PKCS8填充 keySpec = new X509EncodedKeySpec(publicKey);} else { // PKCS1填充 DLSequence sequence = (DLSequence) ASN1Primitive.fromByteArray(publicKey); BigInteger v1 = ((ASN1Integer) sequence.getObjectAt(0)).getValue(); BigInteger v2 = ((ASN1Integer) sequence.getObjectAt(1)).getValue(); keySpec = new RSAPublicKeySpec(v1, v2);}RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance('RSA', BouncyCastleProvider.PROVIDER_NAME).generatePublic(keySpec);return pubKey; } /** * RSA私鑰 * * @param usePKCS8 * 是否采用PKCS8填充模式 * @param privateKey * 私鑰 * @return 私鑰 * @throws Exception * 解密過(guò)程中的異常信息 */ public static RSAPrivateKey generatePrivateKey(boolean usePKCS8, byte[] privateKey) throws Exception {KeySpec keySpec;if (usePKCS8) { // PKCS8填充 keySpec = new PKCS8EncodedKeySpec(privateKey);} else { // PKCS1填充 DLSequence sequence = (DLSequence) ASN1Primitive.fromByteArray(privateKey); // BigInteger v1= ((ASN1Integer)sequence.getObjectAt(0)).getValue(); BigInteger v2 = ((ASN1Integer) sequence.getObjectAt(1)).getValue(); BigInteger v3 = ((ASN1Integer) sequence.getObjectAt(2)).getValue(); BigInteger v4 = ((ASN1Integer) sequence.getObjectAt(3)).getValue(); BigInteger v5 = ((ASN1Integer) sequence.getObjectAt(4)).getValue(); BigInteger v6 = ((ASN1Integer) sequence.getObjectAt(5)).getValue(); BigInteger v7 = ((ASN1Integer) sequence.getObjectAt(6)).getValue(); BigInteger v8 = ((ASN1Integer) sequence.getObjectAt(7)).getValue(); BigInteger v9 = ((ASN1Integer) sequence.getObjectAt(8)).getValue(); keySpec = new RSAPrivateCrtKeySpec(v2, v3, v4, v5, v6, v7, v8, v9);}RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance('RSA', BouncyCastleProvider.PROVIDER_NAME).generatePrivate(keySpec);return priKey; } /** * RSA公鑰加密 * * @param value * 加密字符串 * @param publicKey * 公鑰 * @return 密文 * @throws Exception * 加密過(guò)程中的異常信息 */ public static String rsaEncrypt(String value, RSAPublicKey publicKey) throws Exception {if (value == null || value.length() == 0) return '';// RSA加密Cipher cipher = Cipher.getInstance('RSA');cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] buffer = cipher.doFinal(value.getBytes('utf-8'));// 使用hex格式輸出公鑰StringBuffer result = new StringBuffer();for (int i = 0; i < buffer.length; i++) { result.append(String.format('%02x', buffer[i]));}return result.toString(); } /** * RSA私鑰解密 * * @param value * 加密字符串 * @param privateKey * 私鑰 * @return 明文 * @throws Exception * 解密過(guò)程中的異常信息 */ public static String rsaDecrypt(String value, RSAPrivateKey privateKey) throws Exception {if (value == null || value.length() == 0) return '';byte[] buffer = new byte[value.length() / 2];for (int i = 0; i < buffer.length; i++) { buffer[i] = (byte) Integer.parseInt(value.substring(i * 2, i * 2 + 2), 16);}// RSA解密Cipher cipher = Cipher.getInstance('RSA');cipher.init(Cipher.DECRYPT_MODE, privateKey);buffer = cipher.doFinal(buffer);return new String(buffer, 'utf-8'); } /** * RSA簽名 * * @param value * 加密字符串 * @param privateKey * 私鑰 * @param halg * 加密算法,如MD5, SHA1, SHA256, SHA384, SHA512等 * @return 簽名 * @throws Exception * 簽名過(guò)程中的異常信息 */ public static String sign(String value, RSAPrivateKey privateKey, String halg) throws Exception {Signature s = Signature.getInstance(halg.toUpperCase().endsWith('WithRSA') ? halg : (halg + 'WithRSA'));s.initSign(privateKey);s.update(value.getBytes('utf-8'));byte[] buffer = s.sign();// 使用hex格式輸出公鑰StringBuffer result = new StringBuffer();for (int i = 0; i < buffer.length; i++) { result.append(String.format('%02x', buffer[i]));}return result.toString(); } /** * RSA簽名驗(yàn)證 * * @param value * 加密字符串 * @param publicKey * 公鑰 * @param halg * 加密算法,如MD5, SHA1, SHA256, SHA384, SHA512等 * @return 簽名合法則返回true,否則返回false * @throws Exception * 驗(yàn)證過(guò)程中的異常信息 */ public static boolean verify(String value, RSAPublicKey publicKey, String signature, String halg) throws Exception {Signature s = Signature.getInstance(halg.toUpperCase().endsWith('WithRSA') ? halg : (halg + 'WithRSA'));s.initVerify(publicKey);s.update(value.getBytes('utf-8'));byte[] buffer = new byte[signature.length() / 2];for (int i = 0; i < buffer.length; i++) { buffer[i] = (byte) Integer.parseInt(signature.substring(i * 2, i * 2 + 2), 16);}return s.verify(buffer); }}

 生成公鑰和私鑰:

// 生成公私鑰 Object[] rsaKey = RsaUtil.generateRsaKey(usePKCS8); //usePKCS8=true表示是否成PKCS8格式的公私秘鑰,否則乘車PKCS1格式的公私秘鑰 byte[] publicKey = (byte[]) rsaKey[0]; byte[] privateKey = (byte[]) rsaKey[1];

生成秘鑰后,需要保存,一般保存到pem文件中: 

// 保存到pem文件,filePath是保存目錄 RsaUtil.writeToPem(publicKey, false, filePath + 'rsa.pub'); RsaUtil.writeToPem(privateKey, true, filePath + 'rsa.pem');

 可以保存到pem文件中,當(dāng)然也可以從pem文件中讀取了:

// 從Pem文件讀取公私鑰,filePath是文件目錄 byte[] publicKey = RsaUtil.readFromPem(filePath + 'rsa.pub'); byte[] privateKey = RsaUtil.readFromPem(filePath + 'rsa.pem');

還可以從crt證書(shū)中讀取公鑰,而crt文件不包含私鑰,因此需要單獨(dú)獲取私鑰: 

// 從crt文件讀取公鑰(crt文件中不包含私鑰),filePath是文件目錄 byte[] publicKey = RsaUtil.readPublicKeyFromCrt(filePath + 'demo.crt'); byte[] privateKey = RsaUtil.readFromPem(filePath + 'demo.key');

 pfx文件中包含了公鑰和私鑰,可以很方便就讀取到:

// 從pfx文件讀取公私鑰,filePath是文件目錄 Object[] rsaKey = RsaUtil.readFromPfx(filePath + 'demo.pfx', '123456'); byte[] publicKey = (byte[]) rsaKey[0]; byte[] privateKey = (byte[]) rsaKey[1];

有時(shí)候我們還可能需要進(jìn)行秘鑰的轉(zhuǎn)換:

// Pkcs8格式公鑰轉(zhuǎn)換為Pkcs1格式公鑰 publicKey = RsaUtil.pkcs8ToPkcs1(false, publicKey); // Pkcs8格式私鑰轉(zhuǎn)換為Pkcs1格式私鑰 privateKey = RsaUtil.pkcs8ToPkcs1(true, privateKey); // Pkcs1格式公鑰轉(zhuǎn)換為Pkcs8格式公鑰 publicKey = RsaUtil.pkcs1ToPkcs8(false, publicKey); // Pkcs1格式私鑰轉(zhuǎn)換為Pkcs8格式私鑰 privateKey = RsaUtil.pkcs1ToPkcs8(true, privateKey);

有了公鑰和私鑰,接下就就能實(shí)現(xiàn)加密、解密、簽名、驗(yàn)證簽名等操作了:

RSAPublicKey rsaPublicKey = RsaUtil.generatePublicKey(usePKCS8, publicKey); RSAPrivateKey rsaPrivateKey = RsaUtil.generatePrivateKey(usePKCS8, privateKey); String encryptText = RsaUtil.rsaEncrypt(text, rsaPublicKey); System.out.printf('【%s】經(jīng)過(guò)【RSA】加密后:%sn', text, encryptText); String decryptText = RsaUtil.rsaDecrypt(encryptText, rsaPrivateKey); System.out.printf('【%s】經(jīng)過(guò)【RSA】解密后:%sn', encryptText, decryptText); String signature = RsaUtil.sign(text, rsaPrivateKey, 'MD5'); System.out.printf('【%s】經(jīng)過(guò)【RSA】簽名后:%sn', text, signature); boolean result = RsaUtil.verify(text, rsaPublicKey, signature, 'MD5'); System.out.printf('【%s】的簽名【%s】經(jīng)過(guò)【RSA】驗(yàn)證后結(jié)果是:' + result, text, signature);

這里完整的demo代碼:

import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey;public class RsaMain { public static void main(String[] args) { try {String text = '上山打老虎';boolean usePKCS8 = true; // usePKCS8=true表示是否成PKCS8格式的公私秘鑰,否則乘車PKCS1格式的公私秘鑰String filePath = RsaUtil.class.getClassLoader().getResource('').getPath();System.out.printf('文件路徑:%sn', filePath);// 存放pem,crt,pfx等文件的目錄byte[] publicKey, privateKey;// 公鑰和私鑰 // 生成公私鑰Object[] rsaKey = RsaUtil.generateRsaKey(usePKCS8); // usePKCS8=true表示是否成PKCS8格式的公私秘鑰,否則乘車PKCS1格式的公私秘鑰publicKey = (byte[]) rsaKey[0];privateKey = (byte[]) rsaKey[1];// 從Pem文件讀取公私鑰,filePath是文件目錄// publicKey = RsaUtil.readFromPem(filePath + 'rsa.pub');// privateKey = RsaUtil.readFromPem(filePath + 'rsa.pem');// 從pfx文件讀取公私鑰,filePath是文件目錄// Object[] rsaKey = RsaUtil.readFromPfx(filePath + 'demo.pfx',// '123456');// publicKey = (byte[]) rsaKey[0];// privateKey = (byte[]) rsaKey[1];// 從crt文件讀取公鑰(crt文件中不包含私鑰),filePath是文件目錄// publicKey = RsaUtil.readPublicKeyFromCrt(filePath + 'demo.crt');// privateKey = RsaUtil.readFromPem(filePath + 'demo.key'); // 保存到pem文件,filePath是保存目錄RsaUtil.writeToPem(publicKey, false, filePath + 'rsa.pub');RsaUtil.writeToPem(privateKey, true, filePath + 'rsa.pem'); // Pkcs8格式公鑰轉(zhuǎn)換為Pkcs1格式公鑰publicKey = RsaUtil.pkcs8ToPkcs1(false, publicKey);// Pkcs8格式私鑰轉(zhuǎn)換為Pkcs1格式私鑰privateKey = RsaUtil.pkcs8ToPkcs1(true, privateKey);// Pkcs1格式公鑰轉(zhuǎn)換為Pkcs8格式公鑰publicKey = RsaUtil.pkcs1ToPkcs8(false, publicKey);// Pkcs1格式私鑰轉(zhuǎn)換為Pkcs8格式私鑰privateKey = RsaUtil.pkcs1ToPkcs8(true, privateKey); RSAPublicKey rsaPublicKey = RsaUtil.generatePublicKey(usePKCS8, publicKey);RSAPrivateKey rsaPrivateKey = RsaUtil.generatePrivateKey(usePKCS8, privateKey); String encryptText = RsaUtil.rsaEncrypt(text, rsaPublicKey);System.out.printf('【%s】經(jīng)過(guò)【RSA】加密后:%sn', text, encryptText); String decryptText = RsaUtil.rsaDecrypt(encryptText, rsaPrivateKey);System.out.printf('【%s】經(jīng)過(guò)【RSA】解密后:%sn', encryptText, decryptText); String signature = RsaUtil.sign(text, rsaPrivateKey, 'MD5');System.out.printf('【%s】經(jīng)過(guò)【RSA】簽名后:%sn', text, signature); boolean result = RsaUtil.verify(text, rsaPublicKey, signature, 'MD5');System.out.printf('【%s】的簽名【%s】經(jīng)過(guò)【RSA】驗(yàn)證后結(jié)果是:' + result, text, signature);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace(); }} }

以上就是Java 實(shí)現(xiàn)RSA非對(duì)稱加密算法的詳細(xì)內(nèi)容,更多關(guān)于Java RSA非對(duì)稱加密算法的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 日韩黑寡妇一级毛片国语对白 | 亚洲欧洲精品成人久久曰影片 | 国产淫视 | 国产剧情视频在线观看 | 亚洲六月丁香婷婷综合 | 国产成人yy精品1024在线 | 精品大臿蕉视频在线观看 | 亚洲黄色美女视频 | 老师的丰满大乳奶水视频 | 欧美亚洲国产精品第一页 | xxxxx18日本人hdxx| 欧美特黄特色aaa大片免费看 | 亚洲精品国产精品乱码视色 | 老司机成人午夜精品福利视频 | 久久羞羞 | a国产 | 精品香蕉伊思人在线观看 | 亚洲精品视频免费在线观看 | 成人免费视频一区二区 | 国产成在线观看免费视频成本人 | 边做边摸边揉的免费视频 | 国产大尺度吃奶无遮无挡网 | 香蕉视频在线免费播放 | 伊人中文字幕在线观看 | 欧美大片a一级毛片视频 | 亚洲精品123区在线观看 | 国产高清精品一级毛片 | 成人免费男女视频网站慢动作 | 伊人精品 | 国产农村1级毛片 | 免费人成在线视频播放2022 | 国产免费拍拍视频在线观看网站 | 韩国精品一区二区久久 | 黄色污片| 亚洲精品99久久久久久欧美版 | 成人午夜精品网站在线观看 | 视频在线国产 | 日本黄色免费看 | 成人三级黄色片 | 大象焦伊人久久综合网色视 | 国产成人毛片精品不卡在线 |