黄a在线观看-黄a在线-黄a大片-黄色片在线看-黄色毛片免费-黄色大片网站

您的位置:首頁技術文章
文章詳情頁

利用Java對PDF文件進行電子簽章的實戰過程

瀏覽:73日期:2022-08-09 09:25:25
目錄一、 概述二、 技術選型三、 生成一個圖片簽章1. 生成一個如下圖的簽章圖片2. 相關代碼四、 如何按模板生成PDF文件1. 制作PDF模板2. 制作一個如下圖的PDF模板,該模板是帶有PDF的表單域的五、 如何生成PKCS12證書1. PKCS的簡單介紹2. 使用JAVA生成一個PKCS12證書并進行存貯,相關分析見代碼注解六、 如何生成一個高清晰的簽章1. 由PDF模板生成一個PDF文件,見代碼注解2. 對PDF文件進行簽章3. 高清簽章七、 如何進行多次PDF簽名八、 總結一、 概述

印章是我國特有的歷史文化產物,古代主要用作身份憑證和行駛職權的工具。它的起源是由于社會生活的實際需要。早在商周時代,印章就已經產生。如今的印章已成為一種獨特的,融實用性和藝術性為一體的藝術瑰寶。傳統的印章容易被壞人、小人私刻;從而新聞鮮有報道某某私刻公章,侵吞國家財產。隨著計算機技術、加密技術及圖像處理技術的發展,出現了電子簽章。電子簽章是電子簽名的一種表現形式,利用圖像處理技術、數字加密技術將電子簽名操作轉化為與紙質文件蓋章操作相同的可視效果,同時利用電子簽名技術保障電子信息的真實性和完整性以及簽名人的不可否認性。

電子簽章與數字證書一樣是身份驗證的一種手段,泛指所有以電子形式存在,依附在電子文件并與其邏輯關聯,可用以辨識電子文件簽署者身份,保證文件的完整性,并表示簽署者同意電子文件所陳述事實的內容。一般來說對電子簽章的認定都是從技術角度而言的。主要是指通過特定的技術方案來鑒別當事人的身份及確保電子資料內容不被篡改的安全保障措施。電子簽章常于發送安全電子郵件、訪問安全站點、網上招標投標、網上簽約、安全網上公文傳送、公司合同、電子處方箋等。

電子簽章是一個很復雜的問題,大到有相關的電子簽章系統;今天分享一下如何把電子簽章應用到電子處方箋的PDF文件里。

二、 技術選型

目前主流處理PDF文件兩個jar包分別是:

開源組織Apache的PDFBox,官網https://pdfbox.apache.org/ 大名鼎鼎adobe公司的iText,官網https://itextpdf.com/tags/adobe,其中iText又分為iText5和iText7

如何在PDFBox、iText5和iText7選出合適自己項目的技術呢?

對比PDFBox、iText5和iText7這三者:

PDFBox的功能相對較弱,iText5和iText7的功能非常強悍; iText5的資料網上相對較多,如果出現問題容易找到解決方案;PDFBox和iText7的網上資料相對較少,如果出現問題不易找到相關解決方案; 通過閱讀PDFBox代碼目前PDFBox還沒提供自定義簽章的相關接口;iText5和iText7提供了處理自定義簽章的相關實現; PDFBox只能實現把簽章圖片加簽到PDF文件;iText5和iText7除了可以把簽章圖片加簽到PDF文件,還可以實現直接對簽章進行繪制,把文件繪制到簽章上。 PDFBox和iText5/iText7使用的協議不一樣。PDFBox使用的是APACHE LICENSE VERSION 2.0(https://www.apache.org/licenses/);iText5/iText7使用的是AGPL(https://itextpdf.com/agpl)。PDFBox免費使用,AGPL商用收費

本分享JAVA對PDF文件進行電子簽章需要實現的功能:

生成證書。與PDFBox、iText5和iText7技術無關 按模板輸出PDF文件:PDFBox、iText5和iText7都可以完成,但是PDFBox會遇到中文亂碼比較棘手的問題 在PDF文件中實現把簽章圖片加簽到PDF文件:PDFBox、iText5和iText7都可以實現,沒有很多的區別 在PDF文件中繪制簽章:iText5和iText7都可以實現,PDFBox目前不支持 在PDF文件中生成高清簽章:iText5和iText7都可以實現,PDFBox目前不支持 在PDF文件中進行多次簽名::PDFBox、iText5和iText7都可以完成,沒有區別

通過相關技術分析和要實現的功能分析,采用iText5進行開發,唯一遺憾的是iText商用收費;但是這不是做技術需要關心的!!選用iText5的理由:

使用iText5能實現全部的功能 如何在開發中遇到相關問題,容易找到相應解決方案 三、 生成一個圖片簽章1. 生成一個如下圖的簽章圖片

利用Java對PDF文件進行電子簽章的實戰過程

2. 相關代碼

import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.FileOutputStream; import java.io.IOException; import sun.font.FontDesignMetrics; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class SignImage { /** * @param doctorName * String 醫生名字 * @param hospitalName * String 醫生名稱 * @param date * String 簽名日期 * 圖片高度 * @param jpgname * String jpg圖片名 * @return */ public static boolean createSignTextImg( String doctorName, // String hospitalName, // String date, String jpgname) {int width = 255;int height = 100;FileOutputStream out = null;//背景色Color bgcolor = Color.WHITE;//字色Color fontcolor = Color.RED;Font doctorNameFont = new Font(null, Font.BOLD, 20);Font othorTextFont = new Font(null, Font.BOLD, 18);try { // 寬度 高度 BufferedImage bimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bimage.createGraphics(); g.setColor(bgcolor); // 背景色 g.fillRect(0, 0, width, height); // 畫一個矩形 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 去除鋸齒(當設置的字體過大的時候,會出現鋸齒) g.setColor(Color.RED); g.fillRect(0, 0, 8, height); g.fillRect(0, 0, width, 8); g.fillRect(0, height - 8, width, height); g.fillRect(width - 8, 0, width, height); g.setColor(fontcolor); // 字的顏色 g.setFont(doctorNameFont); // 字體字形字號 FontMetrics fm = FontDesignMetrics.getMetrics(doctorNameFont); int font1_Hight = fm.getHeight(); int strWidth = fm.stringWidth(doctorName); int y = 35; int x = (width - strWidth) / 2; g.drawString(doctorName, x, y); // 在指定坐標除添加文字 g.setFont(othorTextFont); // 字體字形字號 fm = FontDesignMetrics.getMetrics(othorTextFont); int font2_Hight = fm.getHeight(); strWidth = fm.stringWidth(hospitalName); x = (width - strWidth) / 2; g.drawString(hospitalName, x, y + font1_Hight); // 在指定坐標除添加文字 strWidth = fm.stringWidth(date); x = (width - strWidth) / 2; g.drawString(date, x, y + font1_Hight + font2_Hight); // 在指定坐標除添加文字 g.dispose(); out = new FileOutputStream(jpgname); // 指定輸出文件 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage); param.setQuality(50f, true); encoder.encode(bimage, param); // 存盤 out.flush(); return true;} catch (Exception e) { return false;}finally{ if(out!=null){try { out.close();} catch (IOException e) {} }} } public static void main(String[] args) {createSignTextImg('華佗', '在線醫院', '2018.01.01', 'sign.jpg'); }}四、 如何按模板生成PDF文件1. 制作PDF模板

目前PDF模板工具別無他物,只能使用偉大的Adobe公司提供的Adobe Acrobatpro DC軟件進行制作。如何使用該軟件這里就不多說了,如果在使用中遇到什么可以另外咨詢。

2. 制作一個如下圖的PDF模板,該模板是帶有PDF的表單域的

利用Java對PDF文件進行電子簽章的實戰過程

五、 如何生成PKCS12證書1. PKCS的簡單介紹

PKCS:The Public-Key Cryptography Standards (簡稱PKCS)是由美國RSA數據安全公司及其合作伙伴制定的一組公鑰密碼學標準,其中包括證書申請、證書更新、證書作廢表發布、擴展證書內容以及數字簽名、數字信封的格式等方面的一系列相關協議。

到1999年底,PKCS已經公布了以下標準:

PKCS#1:定義RSA公開密鑰算法加密和簽名機制,主要用于組織PKCS#7中所描述的數字簽名和數字信封[22]。 PKCS#3:定義Diffie-Hellman密鑰交換協議[23]。 PKCS#5:描述一種利用從口令派生出來的安全密鑰加密字符串的方法。使用MD2或MD5 從口令中派生密鑰,并采用DES-CBC模式加密。主要用于加密從一個計算機傳送到另一個計算機的私人密鑰,不能用于加密消息[24]。 PKCS#6:描述了公鑰證書的標準語法,主要描述X.509證書的擴展格式[25]。 PKCS#7:定義一種通用的消息語法,包括數字簽名和加密等用于增強的加密機制,PKCS#7與PEM兼容,所以不需其他密碼操作,就可以將加密的消息轉換成PEM消息[26]。 PKCS#8:描述私有密鑰信息格式,該信息包括公開密鑰算法的私有密鑰以及可選的屬性集等[27]。 PKCS#9:定義一些用于PKCS#6證書擴展、PKCS#7數字簽名和PKCS#8私鑰加密信息的屬性類型[28]。 PKCS#10:描述證書請求語法[29]。 PKCS#11:稱為Cyptoki,定義了一套獨立于技術的程序設計接口,用于智能卡和PCMCIA卡之類的加密設備[30]。 PKCS#12:描述個人信息交換語法標準。描述了將用戶公鑰、私鑰、證書和其他相關信息打包的語法[31]。 PKCS#13:橢圓曲線密碼體制標準[32]。 PKCS#14:偽隨機數生成標準。 PKCS#15:密碼令牌信息格式標準[33]。

PKCS12也就是以上標準的PKCS#12,主要用來描述個人身份信息;本次分享中要進行簽章操作的是醫生和藥師,他們就是一個個人主體,給他們分配一個PKCS12的證書,就等于給他們分配了一個用于蓋章的印章。

2. 使用JAVA生成一個PKCS12證書并進行存貯,相關分析見代碼注解

public class Extension { private String oid; private boolean critical; private byte[] value; public String getOid() { return oid;} public byte[] getValue() { return value;}public boolean isCritical() { return critical;} } import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.X509v3CertificateBuilder; import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; public class Pkcs { private static KeyPair getKey() throws NoSuchAlgorithmException {KeyPairGenerator generator = KeyPairGenerator.getInstance('RSA',new BouncyCastleProvider());generator.initialize(1024);// 證書中的密鑰 公鑰和私鑰KeyPair keyPair = generator.generateKeyPair();return keyPair; } /** * @param password * 密碼 * @param issuerStr 頒發機構信息 * * @param subjectStr 使用者信息 * * @param certificateCRL 頒發地址 * * @return */ public static Map<String, byte[]> createCert(String password, String issuerStr, String subjectStr, String certificateCRL) {Map<String, byte[]> result = new HashMap<String, byte[]>();ByteArrayOutputStream out = null;try { // 生成JKS證書 // KeyStore keyStore = KeyStore.getInstance('JKS'); // 標志生成PKCS12證書 KeyStore keyStore = KeyStore.getInstance('PKCS12', new BouncyCastleProvider()); keyStore.load(null, null); KeyPair keyPair = getKey(); // issuer與 subject相同的證書就是CA證書 Certificate cert = generateCertificateV3(issuerStr, subjectStr, keyPair, result, certificateCRL, null); // cretkey隨便寫,標識別名 keyStore.setKeyEntry('cretkey', keyPair.getPrivate(), password.toCharArray(), new Certificate[] { cert }); out = new ByteArrayOutputStream(); cert.verify(keyPair.getPublic()); keyStore.store(out, password.toCharArray()); byte[] keyStoreData = out.toByteArray(); result.put('keyStoreData', keyStoreData); return result;} catch (Exception e) { e.printStackTrace();} finally { if (out != null) {try { out.close();} catch (IOException e) {} }}return result; } /** * @param issuerStr * @param subjectStr * @param keyPair * @param result * @param certificateCRL * @param extensions * @return */ public static Certificate generateCertificateV3(String issuerStr, String subjectStr, KeyPair keyPair, Map<String, byte[]> result, String certificateCRL, List<Extension> extensions) {ByteArrayInputStream bout = null;X509Certificate cert = null;try { PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); Date notBefore = new Date(); Calendar rightNow = Calendar.getInstance(); rightNow.setTime(notBefore); // 日期加1年 rightNow.add(Calendar.YEAR, 1); Date notAfter = rightNow.getTime(); // 證書序列號 BigInteger serial = BigInteger.probablePrime(256, new Random()); X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder( new X500Name(issuerStr), serial, notBefore, notAfter, new X500Name(subjectStr), publicKey); JcaContentSignerBuilder jBuilder = new JcaContentSignerBuilder( 'SHA1withRSA'); SecureRandom secureRandom = new SecureRandom(); jBuilder.setSecureRandom(secureRandom); ContentSigner singer = jBuilder.setProvider( new BouncyCastleProvider()).build(privateKey); // 分發點 ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier( '2.5.29.31'); GeneralName generalName = new GeneralName( GeneralName.uniformResourceIdentifier, certificateCRL); GeneralNames seneralNames = new GeneralNames(generalName); DistributionPointName distributionPoint = new DistributionPointName( seneralNames); DistributionPoint[] points = new DistributionPoint[1]; points[0] = new DistributionPoint(distributionPoint, null, null); CRLDistPoint cRLDistPoint = new CRLDistPoint(points); builder.addExtension(cRLDistributionPoints, true, cRLDistPoint); // 用途 ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier( '2.5.29.15'); // | KeyUsage.nonRepudiation | KeyUsage.keyCertSign builder.addExtension(keyUsage, true, new KeyUsage( KeyUsage.digitalSignature | KeyUsage.keyEncipherment)); // 基本限制 X509Extension.java ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier( '2.5.29.19'); builder.addExtension(basicConstraints, true, new BasicConstraints( true)); // privKey:使用自己的私鑰進行簽名,CA證書 if (extensions != null)for (Extension ext : extensions) { builder.addExtension( new ASN1ObjectIdentifier(ext.getOid()), ext.isCritical(), ASN1Primitive.fromByteArray(ext.getValue()));} X509CertificateHolder holder = builder.build(singer); CertificateFactory cf = CertificateFactory.getInstance('X.509'); bout = new ByteArrayInputStream(holder.toASN1Structure() .getEncoded()); cert = (X509Certificate) cf.generateCertificate(bout); byte[] certBuf = holder.getEncoded(); SimpleDateFormat format = new SimpleDateFormat('yyyy-MM-dd'); // 證書數據 result.put('certificateData', certBuf); //公鑰 result.put('publicKey', publicKey.getEncoded()); //私鑰 result.put('privateKey', privateKey.getEncoded()); //證書有效開始時間 result.put('notBefore', format.format(notBefore).getBytes('utf-8')); //證書有效結束時間 result.put('notAfter', format.format(notAfter).getBytes('utf-8'));} catch (Exception e) { e.printStackTrace();} finally { if (bout != null) {try { bout.close();} catch (IOException e) {} }}return cert; } public static void main(String[] args) throws Exception{// CN: 名字與姓氏 OU : 組織單位名稱// O :組織名稱 L : 城市或區域名稱 E : 電子郵件// ST: 州或省份名稱 C: 單位的兩字母國家代碼 String issuerStr = 'CN=在線醫院,OU=gitbook研發部,O=gitbook有限公司,C=CN,E=gitbook@sina.com,L=北京,ST=北京';String subjectStr = 'CN=huangjinjin,OU=gitbook研發部,O=gitbook有限公司,C=CN,E=huangjinjin@sina.com,L=北京,ST=北京';String certificateCRL = 'https://gitbook.cn';Map<String, byte[]> result = createCert('123456', issuerStr, subjectStr, certificateCRL); FileOutputStream outPutStream = new FileOutputStream('c:/keystore.p12'); // ca.jksoutPutStream.write(result.get('keyStoreData'));outPutStream.close();FileOutputStream fos = new FileOutputStream(new File('c:/keystore.cer'));fos.write(result.get('certificateData'));fos.flush();fos.close(); } }六、 如何生成一個高清晰的簽章1. 由PDF模板生成一個PDF文件,見代碼注解

import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.AcroFields; import com.itextpdf.text.pdf.AcroFields.Item; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; public class PDFUtils { /** * @param fields * @param data * @throws IOException * @throws DocumentException */ private static void fillData(AcroFields fields, Map<String, String> data) throws IOException, DocumentException {List<String> keys = new ArrayList<String>();Map<String, Item> formFields = fields.getFields();for (String key : data.keySet()) { if(formFields.containsKey(key)){String value = data.get(key);fields.setField(key, value); // 為字段賦值,注意字段名稱是區分大小寫的keys.add(key); }}Iterator<String> itemsKey = formFields.keySet().iterator();while(itemsKey.hasNext()){ String itemKey = itemsKey.next(); if(!keys.contains(itemKey)){fields.setField(itemKey, ' '); }} } /** * @param templatePdfPath * 模板pdf路徑 * @param generatePdfPath * 生成pdf路徑 * @param data * 數據 */ public static String generatePDF(String templatePdfPath, String generatePdfPath, Map<String, String> data) {OutputStream fos = null;ByteArrayOutputStream bos = null;try { PdfReader reader = new PdfReader(templatePdfPath); bos = new ByteArrayOutputStream(); /* 將要生成的目標PDF文件名稱 */ PdfStamper ps = new PdfStamper(reader, bos); /* 使用中文字體 */ BaseFont bf = BaseFont.createFont('STSong-Light', 'UniGB-UCS2-H',BaseFont.NOT_EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); fontList.add(bf); /* 取出報表模板中的所有字段 */ AcroFields fields = ps.getAcroFields(); fields.setSubstitutionFonts(fontList); fillData(fields, data); /* 必須要調用這個,否則文檔不會生成的 如果為false那么生成的PDF文件還能編輯,一定要設為true*/ ps.setFormFlattening(true); ps.close(); fos = new FileOutputStream(generatePdfPath); fos.write(bos.toByteArray()); fos.flush(); return generatePdfPath;} catch (Exception e) { e.printStackTrace();} finally { if (fos != null) {try { fos.close();} catch (IOException e) { e.printStackTrace();} } if (bos != null) {try { bos.close();} catch (IOException e) { e.printStackTrace();} }}return null; } public static void main(String[] args) {Map<String, String> data = new HashMap<String, String>();//key為pdf模板的form表單的名字,value為需要填充的值data.put('title', '在線醫院');data.put('case', '123456789');data.put('date', '2018.12.07');data.put('name', 'gitbook');data.put('sex', '男');data.put('age', '29');data.put('phone', '13711645814');data.put('office', '內科');data.put('cert', '身癢找打');data.put('drug', '1、奧美拉唑腸溶膠囊 0.25g10粒×2板 ');data.put('dose', '×2盒');data.put('cons', '用法用量:口服 一日兩次 一次2粒');data.put('tips', '溫馨提示');data.put('desc', '盡量呆在通風較好的地方,保持空氣流通,有利于病情康復。盡量呆在通風較好的地方');generatePDF('C:UserszhilinDesktopchattpl.pdf', 'C:UserszhilinDesktopchatfilled.pdf', data ); } }

利用Java對PDF文件進行電子簽章的實戰過程

2. 對PDF文件進行簽章

經過過上面的代碼可以生成一個名為sign.jpg的簽章圖片,生成一個keystore.p12的證書文件,還有一個已經通過模板填充了表單的名為filled.pdf的pdf文件。下面就可通過以上材料生成一個簽名的PDF文件。

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Security; import java.security.cert.Certificate; import java.util.UUID; import org.bouncycastle.jce.provider.BouncyCastleProvider; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfSignatureAppearance; import com.itextpdf.text.pdf.PdfSignatureAppearance.RenderingMode; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.security.BouncyCastleDigest; import com.itextpdf.text.pdf.security.DigestAlgorithms; import com.itextpdf.text.pdf.security.ExternalDigest; import com.itextpdf.text.pdf.security.ExternalSignature; import com.itextpdf.text.pdf.security.MakeSignature; import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard; import com.itextpdf.text.pdf.security.PrivateKeySignature; public class SignPdf { /** * @param password * 秘鑰密碼 * @param keyStorePath * 秘鑰文件路徑 * @param signPdfSrc * 簽名的PDF文件 * @param signImage * 簽名圖片文件 * @param x * x坐標 * @param y * y坐標 * @return */ public static byte[] sign(String password, String keyStorePath, String signPdfSrc, String signImage, float x, float y) {File signPdfSrcFile = new File(signPdfSrc);PdfReader reader = null;ByteArrayOutputStream signPDFData = null;PdfStamper stp = null;FileInputStream fos = null;try { BouncyCastleProvider provider = new BouncyCastleProvider(); Security.addProvider(provider); KeyStore ks = KeyStore.getInstance('PKCS12', new BouncyCastleProvider()); fos = new FileInputStream(keyStorePath); // 私鑰密碼 為Pkcs生成證書是的私鑰密碼 123456 ks.load(fos, password.toCharArray()); String alias = (String) ks.aliases().nextElement(); PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray()); Certificate[] chain = ks.getCertificateChain(alias); reader = new PdfReader(signPdfSrc); signPDFData = new ByteArrayOutputStream(); // 臨時pdf文件 File temp = new File(signPdfSrcFile.getParent(), System.currentTimeMillis() + '.pdf'); stp = PdfStamper.createSignature(reader, signPDFData, ’0’, temp, true); stp.setFullCompression(); PdfSignatureAppearance sap = stp.getSignatureAppearance(); sap.setReason('數字簽名,不可改變'); // 使用png格式透明圖片 Image image = Image.getInstance(signImage); sap.setImageScale(0); sap.setSignatureGraphic(image); sap.setRenderingMode(RenderingMode.GRAPHIC); // 是對應x軸和y軸坐標 sap.setVisibleSignature(new Rectangle(x, y, x + 185, y + 68), 1, UUID.randomUUID().toString().replaceAll('-', '')); stp.getWriter().setCompressionLevel(5); ExternalDigest digest = new BouncyCastleDigest(); ExternalSignature signature = new PrivateKeySignature(key, DigestAlgorithms.SHA512, provider.getName()); MakeSignature.signDetached(sap, digest, signature, chain, null, null, null, 0, CryptoStandard.CADES); stp.close(); reader.close(); return signPDFData.toByteArray();} catch (Exception e) { e.printStackTrace();} finally { if (signPDFData != null) {try { signPDFData.close();} catch (IOException e) {} } if (fos != null) {try { fos.close();} catch (IOException e) {} }}return null; } public static void main(String[] args) throws Exception {byte[] fileData = sign('123456', 'C:UserszhilinDesktopchatkeystore.p12', //'C:UserszhilinDesktopchatfilled.pdf',//'C:UserszhilinDesktopchatsign.jpg', 100, 290);FileOutputStream f = new FileOutputStream(new File('C:UserszhilinDesktopchatsigned.pdf'));f.write(fileData);f.close(); } }

利用Java對PDF文件進行電子簽章的實戰過程

3. 高清簽章

高清簽章是通過iText的繪制功能來完成。主要直接在PDF文件中繪制簽章,代碼實現如下:

import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Security; import java.security.cert.Certificate; import org.bouncycastle.jce.provider.BouncyCastleProvider; import com.itextpdf.awt.AsianFontMapper; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfSignatureAppearance; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.PdfStream; import com.itextpdf.text.pdf.PdfTemplate; import com.itextpdf.text.pdf.security.BouncyCastleDigest; import com.itextpdf.text.pdf.security.DigestAlgorithms; import com.itextpdf.text.pdf.security.ExternalDigest; import com.itextpdf.text.pdf.security.ExternalSignature; import com.itextpdf.text.pdf.security.MakeSignature; import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard; import com.itextpdf.text.pdf.security.PrivateKeySignature; public class SignHighPdf { /** * @param password * 秘鑰密碼 * @param keyStorePath * 秘鑰文件路徑 * @param signPdfSrc * 簽名的PDF文件 * @param x * * @param y * @return */ public static byte[] sign(String password, String keyStorePath, String signPdfSrc, float x, float y, String signText) {File signPdfSrcFile = new File(signPdfSrc);PdfReader reader = null;ByteArrayOutputStream signPDFData = null;PdfStamper stp = null;FileInputStream fos = null;try { BouncyCastleProvider provider = new BouncyCastleProvider(); Security.addProvider(provider); KeyStore ks = KeyStore.getInstance('PKCS12', new BouncyCastleProvider()); fos = new FileInputStream(keyStorePath); ks.load(fos, password.toCharArray()); // 私鑰密碼 String alias = (String) ks.aliases().nextElement(); PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray()); Certificate[] chain = ks.getCertificateChain(alias); reader = new PdfReader(signPdfSrc); signPDFData = new ByteArrayOutputStream(); // 臨時pdf文件 File temp = new File(signPdfSrcFile.getParent(), System.currentTimeMillis() + '.pdf'); stp = PdfStamper.createSignature(reader, signPDFData, ’0’, temp, true); PdfSignatureAppearance sap = stp.getSignatureAppearance(); sap.setReason('數字簽名,不可改變'); // 是對應x軸和y軸坐標 sap.setVisibleSignature(new Rectangle(x, y, x + 150, y + 65), 1, 'sr'+String.valueOf(System.nanoTime())); /layer 0 Creating the appearance for layer 0 PdfTemplate n0 = sap.getLayer(0); n0.reset(); float lx = n0.getBoundingBox().getLeft(); float by = n0.getBoundingBox().getBottom(); float width = n0.getBoundingBox().getWidth(); float height = n0.getBoundingBox().getHeight(); n0.setRGBColorFill(255, 0, 0); n0.rectangle(lx, by, 5, height); n0.rectangle(lx, by, width, 5); n0.rectangle(lx, by+height-5, width, 5); n0.rectangle(lx+width-5, by, 5, height); n0.fill(); ///layer 2 PdfTemplate n2 = sap.getLayer(2); n2.setCharacterSpacing(0.0f); ColumnText ct = new ColumnText(n2); ct.setSimpleColumn(n2.getBoundingBox()); n2.setRGBColorFill(255, 0, 0); //做一個占位的動作 Paragraph p1 = new Paragraph(' '); BaseFont bf = BaseFont.createFont(AsianFontMapper.ChineseSimplifiedFont, AsianFontMapper.ChineseSimplifiedEncoding_H, BaseFont.NOT_EMBEDDED); Font font1 = new Font(bf, 5, Font.BOLD, BaseColor.RED); Font font2 = new Font(bf, 13, Font.BOLD, BaseColor.RED); p1.setFont(font1); ct.addElement(p1); Paragraph p = new Paragraph(signText); p.setAlignment(Element.ALIGN_CENTER); p.setFont(font2); ct.addElement(p); ct.go(); stp.getWriter().setCompressionLevel(PdfStream.BEST_COMPRESSION); ExternalDigest digest = new BouncyCastleDigest(); ExternalSignature signature = new PrivateKeySignature(key, DigestAlgorithms.SHA512, provider.getName()); MakeSignature.signDetached(sap, digest, signature, chain, null, null, null, 0, CryptoStandard.CADES); stp.close(); reader.close(); return signPDFData.toByteArray();} catch (Exception e) { e.printStackTrace();} finally { if (signPDFData != null) {try { signPDFData.close();} catch (IOException e) {} } if (fos != null) {try { fos.close();} catch (IOException e) {} }}return null; } public static void main(String[] args) throws Exception {//對已經簽章的signed.pdf文件再次簽章,這次是高清簽章byte[] fileData = sign('123456', 'C:UserszhilinDesktopchatkeystore.p12',//'C:UserszhilinDesktopchatsigned.pdf', 350, 290, '華佗n2017-12-20');FileOutputStream f = new FileOutputStream(new File('C:UserszhilinDesktopchatsigned2.pdf'));f.write(fileData);f.close(); } }

可以分析下下面這兩個簽章的區別,發現左邊的簽章很模糊,右邊的特別清晰。

利用Java對PDF文件進行電子簽章的實戰過程

七、 如何進行多次PDF簽名

生成多個簽章重點代碼,已在SignPdf.java類進行標注說明;如果想進行多次簽名,就只需對已經進行過簽名的PDF文件再次調用sign方法進行再次簽名即可(第六點有張圖片就有兩個簽章,這就是多次簽名的結果)。

PdfStamper.createSignature(reader, signPDFData, ’0’, temp, true);八、 總結

分享中sign.jpg文件的白色背景需要做透明化處理才能達到正確電子簽章的效果(不覆蓋PDF文件中已有的內容,真實的電子簽章也是這樣做的),大家回去可以思考下怎么把一個jpg文件白色背景透明化(高清簽章就已經實現透明化,可以試著把SignPdf.java和SignHighPdf.java簽章到有文字的PDF上面看看效果)。

大家見到的公司公章都是圓形的;這個也是可以做到的大家想想怎樣生成一個圓形的圖片簽章;然后進行電子簽名。這里主要是講解代碼實現,所有代碼非常多。大家回去好好研讀代碼。真正的電子簽名需要通過CA認證公司來完成,我這里只是提供參考方案讓大家學習。

到此這篇關于利用Java對PDF文件進行電子簽章的文章就介紹到這了,更多相關Java對PDF文件電子簽章內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
主站蜘蛛池模板: 天天操天天谢 | 99精品国产一区二区三区麻豆 | 国产网红女主播精品视频 | 色综合视频一区二区三区44 | 深夜福利网站 | 亚洲深夜福利视频 | 欧美日韩另类在线 | 在线视频一二区 | 熟妇人妻中文字幕 | 国产精品乱码一区二区三区四川人 | 午夜国产在线观看 | 国产福利视频 | 国产一区二区三区 | 鲁丝一区二区三区免费 | 天天看夜夜爽 | 美女一区二区三区 | 麻豆av免费在线 | 久久这里只有精品6 | 中文字幕av专区dvd | 日韩精品一区二区三区在线观看视频网站 | 亚洲精品无码人妻无码 | 亚洲欧美一区二区三区在线 | 理论在线视频 | 97欧美一乱一性一交一视频 | 蜜桃视频一区二区三区在线观看 | 国产偷人爽久久久久久老妇app | 久久一道本| 久久精品中文无码资源站 | 欧美一区二区三 | 成人免费久久 | 精品国产一区二区三区久久久蜜月 | 日韩首页| 蜜桃成人av | 中文精品一区二区 | 国产精品欧美久久久久天天影视 | 深夜激情网 | 偷国产乱人伦偷精品视频 | 欧美视频1区 | 婷婷四房综合激情五月在线 | 91在线第一页 | 在线成人| 国产精品一区二区三区四区在线观看 | 亚洲无人区午夜福利码高清完整版 | 佐山爱在线视频| 人妻av中文字幕久久 | 精品国产乱码久久久久久移动网络 | 成人高清视频免费观看 | 日本精品一区二区三区四区 | 欧美专区日韩专区 | 新毛片基地| 免费av观看 | 电车痴汉在线观看 | 亚洲午夜久久久久久久久电影网 | 国产一级美女 | 亚洲 欧美 日韩 在线 | www.av成人| 国产精品毛片在线完整版 | 亚洲婷婷免费 | 国产高清精品在线 | 国产做爰xxxⅹ高潮 国产做爰xxxⅹ高潮69 | 色偷偷91| 在线亚洲一区二区 | 亚洲三级在线观看 | 欧美一区二区三区在线免费观看 | 五十路丰满中年熟女中出 | 国产69精品久久久久久久 | a天堂视频在线观看 | 九九热在线免费视频 | 国产av久久久久精东av | 78国产伦精品一区二区三区 | 九九热精品在线视频 | 青青草狠狠干 | 国产精品国产三级国产专播精品人 | 国产精品你懂得 | 国产成人区| 97精品视频在线 | 精品国产乱码久久久久久牛牛 | 日本一区二区久久 | 国产精品视频免费播放 | 国产精品无码免费专区午夜 | av亚州 | 国产精品久久久久久久裸模 | 国产成人av一区 | 精品无人国产偷自产在线 | 欧美激情在线狂野欧美精品 | 日本人与黑人做爰视频 | 精品少妇一区二区三区日产乱码 | 久久99久国产精品黄毛片入口 | a∨变态另类天堂无码专区 人妻丰满熟妇av无码区不卡 | 男人添女人下部高潮视频 | 亚洲宗人网 | 国产精品久久二区二区 | 探花精品 | 国产在线 | 中文 | av无毛 | 桃色成人网 | 毛片大全在线观看 | 亚洲国产精品成人无码区 | 99久久久 | 中文字幕人妻无码系列第三区 | 国产精品三级视频 | 国产精品玖玖玖 | 国产女同玩人妖 | 男人天堂2024 | 日本福利视频一区 | 国产成人a人亚洲精v品无码 | 国产中文在线视频 | 日韩av无码精品一二三区 | 玖玖在线视频 | yellow免费在线观看 | 亚洲综合伊人 | 风间由美乳巨码无在线 | 亚洲一级一区 | 高潮毛片无遮挡 | 黄色录像毛片 | 欧美日韩中文字幕在线播放 | 国产一区二区三区中文字幕 | 白石茉莉奈一区二区av | 日韩中文字幕综合 | 自拍偷拍av | 在线色网址| 91精品91久久久中77777 | 久久偷窥视频 | 国产精品视频在线观看 | 亚洲理论影院 | 天天综合在线观看 | 麻豆视频在线免费观看 | 亚洲国产成人久久综合电影 | 国产3p又大又爽又粗又硬免费 | 操三八男人的天堂 | 一区二区三区不卡视频 | 国产精品成人av片免费看最爱 | 日韩看片| 久久无码专区国产精品s | 国产精品高潮呻吟久久aⅴ码 | 亚洲精品一区二区三区麻豆 | 成人久久久 | 日韩在线视频免费播放 | 中文字幕一区二区三区在线播放 | 精品一区二区三人妻视频 | 日韩精品极品视频在线 | 在线观看视频中文字幕 | 国产911情侣拍拍在线播放 | 国产亚洲精品久久久久久青梅 | 欧美激情在线一区二区 | 日韩午夜伦 | 91国内精品野花午夜精品 | 免费看毛片在线观看 | 午夜免费小视频 | 少妇一边呻吟一边说使劲视频 | 日韩视频网址 | 中文字幕一二三四区 | 久久久久国产精品一区 | 亚洲精品一区二区三区麻豆 | 色久综合视频 | 亚洲综合一区国产精品 | 怡春院在线视频 | 色屁屁xxxxⅹ免费视频 | 国产在线精品成人免费怡红院 | 国产精品女同 | 日日夜夜添 | 日本h片在线观看 | 国产特级黄色片 | 另类专区av | 国产绳艺sm入口 | 日本精品久久久久中文字幕 | 亚洲成av人片不卡无码手机版 | 成人国内精品久久久久一区 | 人人妻人人澡人人爽人人精品浪潮 | 成人激情免费 | 五月丁香色综合久久4438 | 亚洲精品国偷拍自产在线观看蜜臀 | 麻豆tv在线 | 天天躁日日躁狠狠躁欧美老妇 | 青青久在线视频 | 日本免费一二三区视频 | 久久精品国产99精品亚洲 | 国产色产综合色产在线视频 | 精品一卡二卡三卡 | 欧美精品久久久久久 | 亚洲精品无码久久久 | 国产a国产 | 男人的天堂色偷偷 | 午夜免费福利小视频 | 99久久免费精品国产男女性高好 | 亚洲 欧美 另类 综合 偷拍 | 欧美精品免费在线 | 国产亚洲精品久久久久蜜臀 | 国产不卡一二三 | 精品久久视频 | 加勒比色老久久综合网 | 性生交大片免费看 | 久久久久久a亚洲欧洲aⅴ96 | 久久一视频 | 欧美综合第一页 | 成人精品国产一区二区4080 | 亚洲精品美女久久久 | 极品videosvideo喷水 | 欧美午夜精品一区二区三区 | av青草| 久久久久久免费视频 | 中文字幕日韩一区二区三区不卡 | 成人性生交大免费看 | 免费a在线观看播放 | 中文字幕在线视频精品 | 综合国产在线 | 久久久久二区 | 成人激情在线 | 久久99亚洲网美利坚合众国 | 亚洲成人第一页 | 国产真实在线 | 国产国拍亚洲精品av在线 | 国产欧美一区二区精品性色超碰 | 国产中文欧美日韩在线 | 中文字幕有码在线观看 | 亚洲视频欧美 | 欧美成人午夜一区二区三区 | 亚洲三级一区 | 国产又黄又硬又湿又黄的故事 | 国产在线麻豆精品观看 | 国产经典自拍 | 影音先锋亚洲资源 | 岛国片免费在线观看 | 成人性生交大片免费看vr | 欧洲男女裸体无遮挡做爰 | 自拍偷自拍亚洲精品播放 | 欧美性黄色 | 国产人成免费爽爽爽视频 | 美女露出给别人摸图片 | 欧美精品在线观看一区二区 | 欧美性视频在线 | 九色91蝌蚪 | 国产成人精选视频在线观看 | 午夜精品一区二区三区在线视频 | 天天骑夜夜操 | 久久成人精品 | 4438x成人网最大色成网站 | 自拍偷拍小视频 | 99免费视频 | 国产人体视频 | 欧洲国产伦久久久久久久 | 免费在线观看毛片视频 | 五月婷婷激情综合 | 无码av片av片av无码 | 亚洲乱亚洲乱妇91p丰满 | 自拍偷在线精品自拍偷99九色 | 伊人春色影院 | 中国a级黄色片 | 最近免费中文字幕中文高清百度 | 国产一区二区三区自拍 | 狠狠躁夜夜躁人人爽天天 | 无码爆乳护士让我爽 | 欧美成人性生交大片免费看 | 欧美日韩精品一区二区三区蜜桃 | 国产精品无码久久综合 | 能直接看的av | 国产精品久久久久久久午夜 | 久久久久久久久免费看无码 | 国产成人看片 | 女人精69xxxxxx免费 | 中文字幕久久久久人妻 | 一起草最新网址 | 国产精品高潮呻吟久 | 天堂久久网 | 日本高清有码视频 | 欧美日韩精品一区二区在线视频 | 精品久久久久久久久久久久久 | 亚洲国产欧美日本视频 | 男人的天堂在线观看av | 91久久精| 亚洲精品女 | 中文字幕在线欧美 | 在线观看免费小视频 | 偷窥少妇高潮呻吟av久久免费 | 黄视频在线播放 | 67194熟妇在线观看线路1 | 人人草网站 | 青青草华人在线 | 欧美一区二区三区激情视频 | 无遮挡很爽很污很黄的网站 | 女同av在线播放 | 亚洲综合色吧 | 18禁免费观看网站 | 亚洲欧美日韩久久 | 久久合合 | 91久久精品一区 | 丝袜捆绑调教午夜一区二区 | 国产91热爆ts人妖月奴 | 免费毛片一区二区三区 | 欧美a在线看 | 亚洲男女av | 中文字幕免费在线看线人动作大片 | 91av观看| 久久免费看少妇高潮v片特黄 | 午夜视频免费看 | 狠狠色噜狠狠狠狠 | 日韩精品一区二区三区亚洲综合 | 免费a在线 | 日韩精品免费一区二区三区四区 | 69久久国产露脸精品国产 | brazzers猛女系列 | 欧美久久视频 | 精品xxxxx | 综合久久国产九一剧情麻豆 | 黄a大片av永久免费 亚洲欧美高清一区二区三区 | 色狠狠一区二区三区 | 天天操天天弄 | 国产精品污视频 | 中文字幕无码av波多野吉衣 | 国产女人叫床高潮大片视频 | 国产成年无码久久久久下载 | 黄色日韩网站 | 少妇人妻偷人精品视蜜桃 | 日本一区二区三区在线视频 | 久草视频网 | 国产精品永久久久久 | 美女性生活视频 | 国产美女诱惑 | 色婷av | 国产精品亚洲专区无码不卡 | 15p亚洲 | 艳妇臀荡乳欲伦交换h在线观看 | 日韩激情成人 | 日韩成人一级 | 久久99精品久久久秒播软件优势 | 丝袜美腿亚洲一区二区图片 | 国产做a爱一及毛片久久 | 狠狠综合久久av一区二区 | 全黄色毛片 | 午夜精品久久久久久久99樱桃 | 中文字幕在线观看亚洲视频 | 久草视频精品 | 夜间福利在线 | 成人颜色网站 | 亚洲色欧美另类 | 欧美无马 | 7777欧美日激情日韩精品 | 中国妞xxxhd露脸偷拍视频 | 久久久精品日韩 | 九九久久精品无码专区 | 国产成人精品三级麻豆 | 精品福利影院 | 人人玩人人弄 | 怡红院男人天堂 | 亚洲第一页色 | 成人免费在线 | 99国产精品久久不卡毛片 | 激情综合色综合啪啪开心 | 伊人春色av | 日韩专区在线播放 | 亚洲色欲色欲欲www在线 | 亚洲www啪成人一区二区 | 国产日产欧产精品浪潮安卓版特色 | 蜜臀av性久久久久av蜜臀妖精 | 爱情岛论坛亚洲品质自拍网址大全 | 亚洲黄色在线播放 | 娇喘顶撞深初h1v1 | 永久黄网站色视频免费直播 | 一区二区三区日韩 | 国产伦精品一区二区三区视频孕妇 | 丰满少妇高潮在线观看 | 97碰碰碰免费公开在线视频 | 国偷自产一区二区免费视频 | 欧美一区二区三区在线视频观看 | 国产精品无码无卡在线播放 | 国产第一精品 | 国产欧美一区二区精品婷婷 | 91精品视频免费在线观看 | 天堂mv在线mv免费mv香蕉 | 成人自拍网 | 清清草视频| 午夜小视频免费在线观看 | 欧美三区视频 | 欧美在线免费看 | 国产美女包臀裙一区二区 | 欧美日韩福利视频 | av片一区二区三区 | 激情黄色小说视频 | 久国久产久精永久网页 | zzzwww在线观看免| 日本一级黄色毛片 | 特大黑人巨交吊性xx | www亚洲视频com | 国产网红福利视频一区二区 | 桃色视频m3u8| 国产精品成人3p一区二区三区 | 成人免费看片入口 | 老头把女人躁得呻吟 | 9九色桋品熟女内射 | 超碰伊人网 | 亚洲欧美国产双大乳头 | 波多野结衣在线观看视频 | 国产在线精品一区二区中文 | 国产精品免费视频网站 | h片免费观看 | 久久精品国产精品亚洲红杏 | 东北妇女精品bbwbbw | 国产乱码精品一区二区三区四川人 | 日韩精品无码视频一区二区蜜桃 | av亚洲产国偷v产偷v自拍麻豆 | 国产一区二区在线观看视频 | 久草免费网站 | 亚洲一区二区在线播放相泽 | 国产97超碰| 午夜偷拍福利视频 | 轻轻色在线观看 | 欧洲av在线 | 亚洲精品第一国产综合野草社区 | 天堂av在线中文 | 一本色道久久综合亚洲精品不卡 | 成人免费看片 | 热久久亚洲 | 精品国产1区 | 亚洲综合精品第一页 | www788com色淫免费 | 日本熟女毛茸茸 | 亚洲综合情 | av免播放器 | 亚洲人性生活视频 | 久久综合九色综合网站 | 最近中文字幕免费 | 暴力强奷在线播放无码 | 三级久久| 欧美人妻日韩精品 | 国产亚洲视频在线 | 一区二区三区av | 国产一区二区综合 | 成熟丰满中国女人少妇 | 国产成人av性色在线影院 | 欧美 国产 综合 欧美 视频 | 国产97色在线 | 亚洲 | ts人妖在线观看 | 一区久久| 毛片天天看| 欧美日韩国产成人高清视频 | 性色av无码不卡中文字幕 | 亚洲小视频在线播放 | 成年人福利视频 | 色一情一交一乱一区二区 | 国产精品久久久久久久久久久久久久久 | 理论片在线观看视频 | 国产激情网站 | 男女爽爽无遮挡午夜视频 | 视色网站 | 丁香久久综合 | 永久天堂网av手机版 | 欧美三日本三级少妇三级99观看视频 | 国产精品www色诱视频 | av网站的免费观看 | 亚洲熟妇无码一区二区三区导航 | 色婷婷精品国产一区二区三区 | 精品久久久久久久无码人妻热 | 人体内射精一区二区三区 | 人妻一本久道久久综合久久鬼色 | 色狠狠av一区二区三区 | 日韩欧美一区二区三区视频 | 成人片在线播放 | 精品国产91久久久久久浪潮蜜月 | 直接看毛片 | 亚洲成人a v| 欧美性生话| 成人av社区| 日本肉体xxxx裸体784大胆 | 免费精品人在线二线三线 | 国产高潮视频在线观看 | 免费看美女被靠到爽的视频 | 在办公室被c到呻吟的动态图 | 美女裸体跪姿扒开屁股无内裤 | 欧美交换国产一区内射 | 午夜精品久久久久久不卡8050 | 亚洲另类春色偷拍在线观看 | 她也啪在线视频 | 色视频www在线播放国产人成 | 97高清国语自产拍 | 他揉捏她两乳不停呻吟微博 | 国产情侣一区二区 | 亚洲欧洲av综合色无码 | 国产精品无码翘臀在线观看 | 99久久综合狠狠综合久久aⅴ | 日韩99在线 | 中文 | av三级毛片 | 99久久99久国产黄毛片 | 国产又黄又猛又粗又爽 | 黄色小网站在线观看 | 久久99精品久久久久子伦 | 成人动漫在线观看视频 | 国产日韩欧美成人 | 玩弄少妇人妻 | 艳妇乳肉豪妇荡乳av无码福利 | 黄色免费在线网站 | 国产农村妇女aaaaa视频 | 国产精品欧美激情在线 | 国产精品人妻在线观看 | 少妇欧美激情一区二区三区 | 99视频偷窥在线精品国自产拍 | 亚洲天堂爱爱 | 99精品国产aⅴ | 午夜福利在线永久视频 | 熟女视频一区二区在线观看 | 亚洲欧美在线观看 | 色骚网| ww国产内射精品后入国产 | 天天伊人网| 国产女人和拘做受视频免费 | 亚洲精品亚洲人成在线 | 天天摸久久精品av | a视频在线观看免费 | 久久久999成人| 国内精品久久久久久久久久久久 | 日本19禁啪啪吃奶大尺度 | 国产黄a三级三级三级看三级黑人 | 51妺嘿嘿午夜福利 | 国产成人艳妇aa视频在线 | 自拍偷拍第一页 | 专干老肥女人88av | 51精品国自产在线 | 91涩漫直接入口 | 影音先锋久久久久av综合网成人 | 中国 免费 av | 波多野结衣调教 | 床戏一区| a级国产视频 | 在线丨暗呦小u女国产精品 在线爽 | 美女视频黄8视频大全 | 欧美一区二区三区 | 六月丁香色婷婷 | 久久精品精品 | 午夜精品视频一区二区三区在线看 | 国产精品亚洲а∨无码播放不卡 | 精品乱码久久久久久中文字幕 | 日韩在线播放一区二区 | 欧美巨大双龙性猛交乱大 | 亚洲高清偷拍一区二区三区 | 欧美激情在线播放 | 无码丰满少妇2在线观看 | 操三八男人的天堂 | 日韩精品内射视频免费观看 | 国产精欧美一区二区三区久久 | 热久久av | 国产老太交性20 | 亚洲色欲综合一区二区三区 | 久久精品国内 | 亚洲国产长腿丝袜av天堂 | 女人高潮叫三级 | 蜜臀av一区二区 | 国产精品粉嫩jk国产呦系列 | 日本伊人久久 | 少妇放荡的呻吟干柴烈火动漫 | 6080yyy午夜理论片中无码 | 国产毛茸茸 | 国产无遮挡又黄又爽又色 | 91av视频在线播放 | 精品一区二区三区免费播放 | 少妇久久久久久被弄到高潮 | 黄色一级大片免费版 | 五月婷婷天| 91高潮大合集爽到抽搐 | 在线观看免费av网 | 北条麻妃99精品青青久久 | 亚洲欧美日韩人成在线播放 | 日韩人妻无码免费视频一区二区三区 | 久久免费视频在线观看30 | 亚洲欧美成人中文日韩电影网站 | 俺也来俺也去俺也射 | 免费动漫av | 国产chinese | 美国伊人网 | 国产亚洲精品久久久久久久久久 | jvid福利写真一区二区三区 | 一起草av在线 | 国产91精清纯白嫩高中在线观看 | 邻居少妇与水电工啪啪 | 国产亚洲一卡2卡3卡4卡网站 | 午夜精品一区二区三区免费 | 欧美牲交a欧牲交aⅴ久久 | 777精品视频 | 国产三级精品视频 | 色婷婷av一区二区三区软件 | 亚洲一区二区日本 | 你懂的网站在线观看 | a 'v片欧美日韩在线 | 大黄网站在线观看 | 毛片无遮挡高清免费观看 | 亚洲乱码国产乱码精品精在线网站 | 亚洲va国产va天堂va久久 | 后进极品白嫩翘臀在线播放 | 青青草五月天 | 麻豆国产人妻欲求不满谁演的 | 成人免费777777被爆出 | 成人欧美日韩一区二区三区 | 四虎影视在线影院在线观看免费视频 | 国产全肉乱妇杂乱视频 | 国精品99久9在线 | 免费 | 成人在线观看小视频 | 亚洲欧美国产另类 | 最新精品国偷自产在线 | 亚洲va天堂va欧美ⅴa在线 | 粗大的内捧猛烈进出视频 | 欧美视频在线观看亚洲欧 | 在线观看网址你懂的 | 射久久久 | 96精品视频| 夜夜爽日日澡人人添 | 一级肉体全黄裸片高潮不断 | 久草在线2 | 狠狠干成人 | 无码人妻精品一二三区免费 | 自拍偷自拍亚洲精品情侣 | 中文字幕高清av | 亚洲美女午夜一区二区亚洲精品 | 好吊视频一区二区三区 | 国产精品亚洲综合 | 黄色av网址大全 | 精品中文字幕av | 亚洲永久网站 |