import?java.security.InvalidKeyException;
創(chuàng)新互聯專業(yè)為企業(yè)提供邳州網站建設、邳州做網站、邳州網站設計、邳州網站制作等企業(yè)網站建設、網頁設計與制作、邳州企業(yè)網站模板建站服務,十年邳州做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。
import?java.security.Key;
import?java.security.KeyPair;
import?java.security.KeyPairGenerator;
import?java.security.NoSuchAlgorithmException;
import?java.security.PrivateKey;
import?java.security.PublicKey;
import?java.security.SecureRandom;
import?java.security.Signature;
import?java.security.SignatureException;
import?java.util.logging.Level;
import?java.util.logging.Logger;
/**
*?ECDSA?160bit?簽名及簽名驗證例子
*/
public?class?ECDSASignature?{
public?static?void?main(String?argv[])?{
signatureTest();
}
public?static?void?signatureTest()?{
/**
*?密鑰對生成
*/
KeyPairGenerator?keyPairGenerator?=?null;
try?{
keyPairGenerator?=?KeyPairGenerator.getInstance("EC");
}?catch?(NoSuchAlgorithmException?ex)?{
return;
}
SecureRandom?secureRandom?=?new?SecureRandom();
keyPairGenerator.initialize(160,?secureRandom);
KeyPair?pair?=?keyPairGenerator.generateKeyPair();
Key?publicKey?=?pair.getPublic();
Key?privateKey?=?pair.getPrivate();
//?字符串
String?hako?=?"test";
/**
*?私鑰簽名(ECDSA?160bit)
*/
byte[]?sign?=?null;
try?{
Signature?signatureSign?=?null;
signatureSign?=?Signature.getInstance("NONEwithECDSA");
signatureSign.initSign((PrivateKey)?privateKey,?secureRandom);
signatureSign.update(hako.getBytes());
sign?=?signatureSign.sign();
System.out.println("sign:?"?+?new?String(sign));
}?catch?(InvalidKeyException?|?NoSuchAlgorithmException?|?SignatureException?ex)?{
Logger.getLogger(ECDSASignature.class.getName()).log(Level.SEVERE,?null,?ex);
}
/**
*?用公鑰進行簽名驗證
*/
Signature?signatureVerify?=?null;
try?{
signatureVerify?=?Signature.getInstance("NONEwithECDSA");
signatureVerify.initVerify((PublicKey)?publicKey);
signatureVerify.update(hako.getBytes());
boolean?verifyResult?=?signatureVerify.verify(sign);
System.out.println(verifyResult???"簽名OK"?:?"簽名NG");
}?catch?(NoSuchAlgorithmException?|?InvalidKeyException?|?SignatureException?e)?{
Logger.getLogger(ECDSASignature.class.getName()).log(Level.SEVERE,?null,?e);
}
}
}
上期講述了pdf文檔的操作,這期講述對pdf進行電子簽章,公司的一個小業(yè)務,主要實現 1)線上登記學員信息 》2)線上付款 》 3)電子簽名 》4)生成帶有公司電子簽章的pdf收據
線上付款和電子簽名我會在后續(xù)章節(jié)講述,這期講述pdf電子簽章
一、申請電子印章
二、生成PKCS12證書
1. PKCS介紹
PKCS:The Public-Key Cryptography Standards (簡稱PKCS)是由美國RSA數據安全公司及其合作伙伴制定的一組公鑰密碼學標準,其中包括證書申請、證書更新、證書作廢表發(fā)布、擴展證書內容以及數字簽名、數字信封的格式等方面的一系列相關協議。
到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,主要用來描述個人身份信息
2、JAVA生成PKCS12證書并進行存貯
生成的文件keystore.cer和keystore.p12放在自己項目的配置文件中,后面調用。
三、電子簽章
2. 簽名工具類SignPdf
3. 然后在業(yè)務中調用即可。
參考如下代碼:
package com.wonders.cop.billing.util;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.imageio.ImageIO;
public class ImageMarkLogoUtil {
// 水印透明度
private static float alpha = 1f;
// 水印橫向位置
private static int positionWidth = 82;
// 水印縱向位置
private static int positionHeight = 545;
// 水印文字字體
private static Font font = new Font("宋體", Font.PLAIN, 13);
// 水印文字顏色
private static Color color = Color.black;
public static void main(String[] args) {
String srcImgPath = "d:/888880002302900_web.jpg";
String targerTextPath = "d:/qie_text.jpg";
ImageMarkLogoUtil
.markImageByTexts(testValue(),
BillDetailImagePosition.getPosition("888880002302900"), srcImgPath,
targerTextPath);
}
public static Map testValue() {
MapString, String value = new HashMapString, String();
value.put("feedPrice", "15.1");
value.put("feedCount", "20");
value.put("nowNum", "124");
value.put("drainageCount", "55");
value.put("drainagePrice", "1.5");
value.put("feedCost", "66");
value.put("cost", "66");
value.put("drainageCost", "100");
value.put("barcode", "10101010101010101");
value.put("nextCopy", "2014-12-10");
value.put("waterType", "居民生活用水");
value.put("meterReader", "測試人員");
value.put("copyNumber", "741sg");
value.put("prevCarryOver", "0.25");
value.put("nowCarryOver", "2.12");
value.put("openDate", "20141002");
value.put("nextMonth", "201402 ");
value.put("remark", "您繳付的2013年03月30.80元水費,我公司已收到,謝謝!");
value.put("detailStatus", "00");
value.put("billStatus", "00");
value.put("prevMonth", "201406");
value.put("lastPayDate", "20140112");
value.put("companyName", "市北水");
value.put("type", "1");
value.put("amount", "58.1");
value.put("address", "浦秀路220弄10號101");
value.put("year","2014");
value.put("month", "04");
value.put("billId", "11111");
value.put("account", "38445450");
value.put("companyId", "888880002302900");
value.put("realName", "姚航");
return value;
}
/**
* 給圖片添加水印文字、可設置水印文字的旋轉角度
*
* @param logoText
* @param srcImgPath
* @param targerPath
* @param degree
*/
public static void markImageByTexts(MapString, String value,
MapString, String[] position, String srcImgPath, String targerPath) {
InputStream is = null;
OutputStream os = null;
try {
// 1、源圖片
Image srcImg = ImageIO.read(new File(srcImgPath));
BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);
// 2、得到畫筆對象
IteratorString positionIter = position.keySet().iterator();
String key = "";
String logotext = "";
String[] xy;
while (positionIter.hasNext()) {
key = positionIter.next();
xy = position.get(key);
logotext = value.get(key);
System.out.println("key:"+key+",value:"+logotext);
if (xy != null xy.length == 2)
printText(srcImg, buffImg, logotext,
Integer.valueOf(xy[0]), Integer.valueOf(xy[1]));
}
// 10、生成圖片
os = new FileOutputStream(targerPath);
ImageIO.write(buffImg, "JPG", os);
System.out.println("圖片完成添加水印文字");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != is)
is.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (null != os)
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 在圖片上打印文字
*
* @param srcImg
* @param buffImg
* @param logoText
* @return
*/
private static void printText(Image srcImg, BufferedImage buffImg,
String logoText, Integer positionX, Integer PositionY) {
Graphics2D g = buffImg.createGraphics();
// 3、設置對線段的鋸齒狀邊緣處理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0, null);
// 5、設置水印文字顏色
g.setColor(color);
// 6、設置水印文字Font
g.setFont(font);
// 7、設置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
// 8、第一參數-設置的內容,后面兩個參數-文字在圖片上的坐標位置(x,y)
g.drawString(logoText, positionX, PositionY);
// 9、釋放資源
g.dispose();
}
}
哎,早就不用水晶了,做報表習慣性用FineReport,在FineReport幫助文檔里面查了一下此問題的解決方案,供借鑒:1. 問題描述 電子簽章是電子簽名的一種表現形式,以圖片形式將電子簽名轉化為與紙質文件蓋章相同的效果,希望在報表中,嵌入電子簽章,如下圖:下面詳細介紹如何實現報表中嵌入電子簽章。 2. 報表嵌入電子簽章方法一 2.1 直接以圖片作為電子簽章 若電子簽章是現成的圖片,此時可以直接以插入圖片形式來顯示,右擊單元格單元格元素插入圖片選擇圖片目錄確定,報表中嵌入電子簽章完成。 3. 報表嵌入電子簽章方法二 3.1 以HTML語言設置電子簽章 電子簽章通過HTML中使用如OBJECT標簽設計不同樣式,將object源碼拷貝到單元格中,右擊單元格,選擇其他屬性,把用HTML語言顯示內容的勾打上,則可直接顯示object標簽里面的內容,預覽模板,電子簽章設計完成。 注:HTML的object 標簽用于包含對象,比如圖像、音頻、視頻、Java applets、ActiveX、PDF 以及 Flash。
建議你先把word的電子簽章弄掉,轉成PDF,然后再用PDF編輯器添加圖章就好了。
先用福昕PDF閱讀器打開文件,然后點擊注釋----創(chuàng)建自定義圖章
會跳出這個框框,你把電子簽章添加進去,然后類別名稱寫一下,圖片透明度什么都可以設置,然后按確定
之后再到注釋--圖章里就可以找到自己剛剛創(chuàng)建的簽章。添加就好了
/**?
*?Copyright?(c)?2003-2007?Wonders?Information?Co.,Ltd.?All?Rights?Reserved.
*?5-6/F,?20?Bldg,?481?Guiping?RD.?Shanghai?200233,PRC
*
*?This?software?is?the?confidential?and?proprietary?information?of?Wonders?Group.
*?(Research??Development?Center).?You?shall?not?disclose?such
*?Confidential?Information?and?shall?use?it?only?in?accordance?with?
*?the?terms?of?the?license?agreement?you?entered?into?with?Wonders?Group.?
*
*?Distributable?under?GNU?LGPL?license?by?gun.org
*/
package?com.wonders.cop.billing.util;
import?java.awt.AlphaComposite;
import?java.awt.Color;
import?java.awt.Font;
import?java.awt.Graphics2D;
import?java.awt.Image;
import?java.awt.RenderingHints;
import?java.awt.image.BufferedImage;
import?java.io.File;
import?java.io.FileOutputStream;
import?java.io.InputStream;
import?java.io.OutputStream;
import?java.util.HashMap;
import?java.util.Iterator;
import?java.util.Map;
import?javax.imageio.ImageIO;
/**
*?TODO(用一句話描述該文件做什么)
*?
*?@Title:?ImageMarkLogUtil.java
*?@Package?com.wonders.cop.billing.util
*?@ClassName:?ImageMarkLogUtil
*?@author?YaoHang
*?@company?Wonders?Information?Co.,Ltd.
*?@date?2014年11月6日?下午4:24:35
*?@version?V1.0
*/
public?class?ImageMarkLogoUtil?{
//?水印透明度
private?static?float?alpha?=?1f;
//?水印橫向位置
private?static?int?positionWidth?=?82;
//?水印縱向位置
private?static?int?positionHeight?=?545;
//?水印文字字體
private?static?Font?font?=?new?Font("宋體",?Font.PLAIN,?13);
//?水印文字顏色
private?static?Color?color?=?Color.black;
public?static?void?main(String[]?args)?{
String?srcImgPath?=?"d:/888880002302900_web.jpg";
String?targerTextPath?=?"d:/qie_text.jpg";
ImageMarkLogoUtil
.markImageByTexts(testValue(),
BillDetailImagePosition.getPosition("888880002302900"),?srcImgPath,
targerTextPath);
}
public?static?Map?testValue()?{
MapString,?String?value?=?new?HashMapString,?String();
value.put("feedPrice",?"15.1");
value.put("feedCount",?"20");
value.put("nowNum",?"124");
value.put("drainageCount",?"55");
value.put("drainagePrice",?"1.5");
value.put("feedCost",?"66");
value.put("cost",?"66");
value.put("drainageCost",?"100");
value.put("barcode",?"10101010101010101");
value.put("nextCopy",?"2014-12-10");
value.put("waterType",?"居民生活用水");
value.put("meterReader",?"測試人員");
value.put("copyNumber",?"741sg");
value.put("prevCarryOver",?"0.25");
value.put("nowCarryOver",?"2.12");
value.put("openDate",?"20141002");
value.put("nextMonth",?"201402?");
value.put("remark",?"您繳付的2013年03月30.80元水費,我公司已收到,謝謝!");
value.put("detailStatus",?"00");
value.put("billStatus",?"00");
value.put("prevMonth",?"201406");
value.put("lastPayDate",?"20140112");
value.put("companyName",?"市北水");
value.put("type",?"1");
value.put("amount",?"58.1");
value.put("address",?"浦秀路220弄10號101");
value.put("year","2014");
value.put("month",?"04");
value.put("billId",?"11111");
value.put("account",?"38445450");
value.put("companyId",?"888880002302900");
value.put("realName",?"姚航");
return?value;
}
/**
*?給圖片添加水印文字、可設置水印文字的旋轉角度
*?
*?@param?logoText
*?@param?srcImgPath
*?@param?targerPath
*?@param?degree
*/
public?static?void?markImageByTexts(MapString,?String?value,
MapString,?String[]?position,?String?srcImgPath,?String?targerPath)?{
InputStream?is?=?null;
OutputStream?os?=?null;
try?{
//?1、源圖片
Image?srcImg?=?ImageIO.read(new?File(srcImgPath));
BufferedImage?buffImg?=?new?BufferedImage(srcImg.getWidth(null),
srcImg.getHeight(null),?BufferedImage.TYPE_INT_RGB);
//?2、得到畫筆對象
IteratorString?positionIter?=?position.keySet().iterator();
String?key?=?"";
String?logotext?=?"";
String[]?xy;
while?(positionIter.hasNext())?{
key?=?positionIter.next();
xy?=?position.get(key);
logotext?=?value.get(key);
System.out.println("key:"+key+",value:"+logotext);
if?(xy?!=?null??xy.length?==?2)
printText(srcImg,?buffImg,?logotext,
Integer.valueOf(xy[0]),?Integer.valueOf(xy[1]));
}
//?10、生成圖片
os?=?new?FileOutputStream(targerPath);
ImageIO.write(buffImg,?"JPG",?os);
System.out.println("圖片完成添加水印文字");
}?catch?(Exception?e)?{
e.printStackTrace();
}?finally?{
try?{
if?(null?!=?is)
is.close();
}?catch?(Exception?e)?{
e.printStackTrace();
}
try?{
if?(null?!=?os)
os.close();
}?catch?(Exception?e)?{
e.printStackTrace();
}
}
}
/**
*?在圖片上打印文字
*?
*?@param?srcImg
*?@param?buffImg
*?@param?logoText
*?@return
*/
private?static?void?printText(Image?srcImg,?BufferedImage?buffImg,
String?logoText,?Integer?positionX,?Integer?PositionY)?{
Graphics2D?g?=?buffImg.createGraphics();
//?3、設置對線段的鋸齒狀邊緣處理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(
srcImg.getScaledInstance(srcImg.getWidth(null),
srcImg.getHeight(null),?Image.SCALE_SMOOTH),?0,?0,?null);
//?5、設置水印文字顏色
g.setColor(color);
//?6、設置水印文字Font
g.setFont(font);
//?7、設置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
alpha));
//?8、第一參數-設置的內容,后面兩個參數-文字在圖片上的坐標位置(x,y)
g.drawString(logoText,?positionX,?PositionY);
//?9、釋放資源
g.dispose();
}
}