扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
import java.security.InvalidKeyException;
创新互联专业为企业提供邳州网站建设、邳州做网站、邳州网站设计、邳州网站制作等企业网站建设、网页设计与制作、邳州企业网站模板建站服务,十年邳州做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
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进行电子签章,公司的一个小业务,主要实现 1)线上登记学员信息 》2)线上付款 》 3)电子签名 》4)生成带有公司电子签章的pdf收据
线上付款和电子签名我会在后续章节讲述,这期讲述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,主要用来描述个人身份信息
2、JAVA生成PKCS12证书并进行存贮
生成的文件keystore.cer和keystore.p12放在自己项目的配置文件中,后面调用。
三、电子签章
2. 签名工具类SignPdf
3. 然后在业务中调用即可。
参考如下代码:
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阅读器打开文件,然后点击注释----创建自定义图章
会跳出这个框框,你把电子签章添加进去,然后类别名称写一下,图片透明度什么都可以设置,然后按确定
之后再到注释--图章里就可以找到自己刚刚创建的签章。添加就好了
/**
* 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();
}
}
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流