用Spire.Doc for Java 可以添加及验证数字签名,参考代码:
importcom.spire.pdf.*;
importcom.spire.pdf.graphics.PdfImage;
importcom.spire.pdf.graphics.PdfTrueTypeFont;
importcom.spire.pdf.security.GraphicMode;
importcom.spire.pdf.security.PdfCertificate;
importcom.spire.pdf.security.PdfCertificationFlags;
importcom.spire.pdf.security.PdfSignature;
importjava.awt.*;
importjava.awt.geom.Point2D;
importjava.awt.geom.Rectangle2D;
publicclassAddCertificate{
publicstaticvoidmain(String[]args){
//加载PDF文档
PdfDocumentdoc=newPdfDocument();
doc.loadFromFile("test.pdf");
//加载pfx证书,及证书秘钥
PdfCertificatecert=newPdfCertificate("Cermia.pfx","123654yes!");
//添加数字签名到指定页面,并设置其位置和大小
PdfSignaturesignature=newPdfSignature(doc,doc.getPages().get(2),cert,"MySignature");
Rectangle2Drect=newRectangle2D.Float();
rect.setFrame(newPoint2D.Float((float)doc.getPages().get(0).getActualSize().getWidth()-340,(float)doc.getPages().get(0).getActualSize().getHeight()-230),newDimension(280,150));
signature.setBounds(rect);
//设置签名为图片加文本模式
signature.setGraphicMode(GraphicMode.Sign_Image_And_Sign_Detail);
//设置签名的内容
signature.setNameLabel("签字者:");
signature.setName("Mia");
signature.setContactInfoLabel("联系电话:");
signature.setContactInfo("02881705109");
signature.setDateLabel("日期:");
signature.setDate(newjava.util.Date());
signature.setLocationInfoLabel("地点:");
signature.setLocationInfo("成都");
signature.setReasonLabel("原因:");
signature.setReason("文档所有者");
signature.setDistinguishedNameLabel("DN:");
signature.setDistinguishedName(signature.getCertificate().get_IssuerName().getName());
signature.setSignImageSource(PdfImage.fromFile("sign.png"));
//设置签名的字体
signature.setSignDetailsFont(newPdfTrueTypeFont(newFont("ArialUnicodeMS",Font.PLAIN,9)));
//设置文档权限为禁止更改
signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);
signature.setCertificated(true);
//保存文档
doc.saveToFile("AddSignature.pdf");
doc.close();
}
}
数字签名添加效果:
数字签名效果
参考原文
B. java注解怎么验证参数和签名
一般接口为了安全需要,都会这么做。可能你的思路还不明确。我的做法是这样的,双方约定好,参数按特定顺序排列,比如按首字母的顺序排列,如url:http://xxx/xxx.do?a=wersd&b=sd2354&c=4&signature=XXXXXXXXXXXX(signature为传入的签名),你拿到入参后,将参数串a=wersd&b=sd2354&c=4按你们约定的签名规则,自己用md5加签一次,然后和入参的signature值对比,以确认调用者是否合法,这就是接口签名验证的思路。
希望有帮到你,记得采纳。
简单的Java加密算法有:
第一种. BASE
Base是网络上最常见的用于传输Bit字节代码的编码方式之一,大家可以查看RFC~RFC,上面有MIME的详细规范。Base编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base来将一个较长的唯一标识符(一般为-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
第二种. MD
MD即Message-Digest Algorithm (信息-摘要算法),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD的前身有MD、MD和MD。
MD算法具有以下特点:
压缩性:任意长度的数据,算出的MD值长度都是固定的。
容易计算:从原数据计算出MD值很容易。
抗修改性:对原数据进行任何改动,哪怕只修改个字节,所得到的MD值都有很大区别。
弱抗碰撞:已知原数据和其MD值,想找到一个具有相同MD值的数据(即伪造数据)是非常困难的。
强抗碰撞:想找到两个不同的数据,使它们具有相同的MD值,是非常困难的。
MD的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD以外,其中比较有名的还有sha-、RIPEMD以及Haval等。
第三种.SHA
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于^位的消息,SHA会产生一个位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。
SHA-与MD的比较
因为二者均由MD导出,SHA-和MD彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
对强行攻击的安全性:最显着和最重要的区别是SHA-摘要比MD摘要长 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD是^数量级的操作,而对SHA-则是^数量级的操作。这样,SHA-对强行攻击有更大的强度。
对密码分析的安全性:由于MD的设计,易受密码分析的攻击,SHA-显得不易受这样的攻击。
速度:在相同的硬件上,SHA-的运行速度比MD慢。
第四种.HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
D. 请问java中的signature是什么意思是属性的意思吗
签名。
比如:method signature 方法签名。
方法参数个数、类型、返回值类型不同,虽然方法名一样,“签名”也不同。
E. java的signature类提供了哪些算法
Signature 类用来为应用程序提供数字签名算法功能。数字签名用于确保数字数据的验证和完整性。
在所有算法当中,数字签名可以是 NIST 标准的 DSA,它使用 DSA 和 SHA-1。可以将使用 SHA-1 消息摘要算法的 DSA 算法指定为 SHA1withDSA。如果使用 RSA,对消息摘要算法则会有多种选择,因此,可以将签名算法指定为 MD2withRSA、MD5withRSA 或 SHA1withRSA。因为没有默认的算法名称,所以必须为其指定名称。
Signature 对象可用来生成和验证数字签名。
F. 两个问题,1.java中什么是函数的signature,2.java中什么是enclosing method
方法的签名可以唯一的确定这个函数
方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成
比如:void test();和void test(int i)是两个不同的方法,但是int test()和float test()是相同的,java会报错的,因为同个类中有两个相同的方法
下面仅仅测试如果返回值不同的情况,如果是参数列表和方法名不同,它们是不同的方法,没有什么好测试的:
publicclassTest{
//Duplicatemethodtest()intypeTest
publicvoidtest(){}
publicinttest(){}
}
测试一下如果继承的子类的返回类型是不同,结果如何:
publicclassTest{
publicvoidtest(){}
}
看看子类的情况:
publicclassSubTestextendsTest{
//.test()
floattest(){}
}
2.JAVA中的闭包。
在JAVA中,闭包是通过“接口+内部类”实现,像C#的delegate一样,JAVA的内部类也可以有匿名内部类。我们现在就来详细认识一下JAVA内部类。
1、内部类。
顾名思义,内部类就是将一个类定义在另一个类的内部。在JAVA中,内部类可以访问到外围类的变量、方法或者其它内部类等所有成员,即使它被定义成private了,但是外部类不能访问内部类中的变量。这样通过内部类就可以提供一种代码隐藏和代码组织的机制,并且这些被组织的代码段还可以自由的访问到包含该内部类的外围上下文环境。
这里提供了一个例子展示这种机制:
publicinterfaceILog{
publicvoidWrite(Stringmessage);
}
publicclassDemoClass1{
privateintlength=0;
//private|public
{
@Override
publicvoidWrite(Stringmessage){
//DemoClass1.this.length=message.length();
length=message.length();
System.out.println("DemoClass1.InnerClass:"+length);
}
}
publicILoglogger(){
returnnewInnerClass();
}
publicstaticvoidmain(String[]args){
DemoClass1demoClass1=newDemoClass1();
demoClass1.logger().Write("abc");
//.new
DemoClass1dc1=newDemoClass1();
InnerClassic=dc1.newInnerClass();
ic.Write("abcde");
}
}
如果你用过javascript的,肯定是很不喜欢这种模仿的实现
1.2、.this
如何通过this显式引用外围类的变量?通过此格式进行引用:{外围类名}.this.{变量名称}。如:
DemoClass1.this.length = message.length();
2、局部内部类。
局部内部类是指在方法的作用域内定义的的内部类。
publicclassDemoClass2{
privateintlength=0;
publicILoglogger(){
//在方法体的作用域中定义此局部内部类
classInnerClassimplementsILog
{
@Override
publicvoidWrite(Stringmessage){
length=message.length();
System.out.println("DemoClass2.InnerClass:"+length);
}
}
returnnewInnerClass();
}
}
因为InnerClass类是定义在logger()方法体之内,所以InnerClass类在方法的外围是不可见的。
3、匿名内部类。
顾名思义,匿名内部类就是匿名、没有名字的内部类,通过匿名内部类可以更加简洁的创建一个内部类。
publicclassDemoClass3{
privateintlength=0;
publicILoglogger(){
returnnewILog(){
@Override
publicvoidWrite(Stringmessage){
length=message.length();
System.out.println("DemoClass3.AnonymousClass:"+length);
}
};
}
}
由此可见,要创建一个匿名内部类,可以new关键字来创建。
格式:new 接口名称(){}
格式:new 接口名称(args...){}
4、final关键字。
闭包所绑定的本地变量必须使用final修饰符,以表示为一个恒定不变的数据,创建后不能被更改。
publicclassDemoClass4{
privateintlength=0;
publicILoglogger(intlevel){//finalintlevel
//final
finalintlogLevel=level+1;
switch(level)
{
case1:
returnnewILog(){
@Override
publicvoidWrite(Stringmessage){
length=message.length();
System.out.println("DemoClass4.AnonymousClass:InfoLog"+length);
System.out.println(logLevel);
}
};
default:
returnnewILog(){
@Override
publicvoidWrite(Stringmessage){
length=message.length();
System.out.println("DemoClass4.AnonymousClass:ErrorLog"+length);
System.out.println(logLevel);
}
};
}
}
publicstaticvoidmain(String[]args){
DemoClass4demoClass4=newDemoClass4();
demoClass4.logger(1).Write("abcefghi");
}
}
从例子中可以看到,logger方法接受了一个level参数,以表示要写的日志等级,这个level参数如果直接赋给内部类中使用,会导致编译时错误,提示level参数必须为final,这种机制防止了在闭包共享中变量取值错误的问题。解决方法可以像例子一样在方法体内定义一下新的局部变量,标记为final,然后把参数level赋值给它:
final int logLevel = level;
或者直接参数中添加一个final修饰符:
public ILog logger(finalint level {
5、实例初始化。
匿名类的实例初始化相当于构造器的作用,但不能重载。
publicILoglogger(finalintlevel)throwsException{
returnnewILog(){
{
//实例初始化,不能重载
if(level!=1)
thrownewException("日志等级不正确!");
}
@Override
publicvoidWrite(Stringmessage){
length=message.length();
System.out.println("DemoClass5.AnonymousClass:"+length);
}
};
}
G. java 怎么实现sign校验
/**
*对Controller进行安全和身份校验
*/
@Around("within(@org.springframework.stereotype.Controller*)&&@annotation(is)")
(ProceedingJoinPointpjp,SecureValidis)
throwsException{
Object[]args=pjp.getArgs();
//Controller中所有方法的参数,前两个分别为:Request,Response
HttpServletRequestrequest=(HttpServletRequest)args[0];
//HttpServletResponseresponse=(HttpServletResponse)args[1];
Stringappid=request.getParameter("appid");
intapp_id=Integer.valueOf(appid);
Stringsignature=request.getParameter("signature");
StringclientSignature=request.getParameter("client_signature");
Stringuri=request.getRequestURI();
Stringprovider=request.getParameter("provider");
if(StringUtils.isEmpty(provider)){
provider="passport";
}
//对appid和signature进行校验
try{
appService.validateAppid(app_id);
booleanisValid=accountService.validSignature(app_id,signature,clientSignature);
if(!isValid)thrownewProblemException(ErrorUtil.ERR_CODE_COM_SING);
}catch(Exceptione){
returnhandleException(e,provider,uri);
}
//继续执行接下来的代码
ObjectretVal=null;
try{
retVal=pjp.proceed();
}catch(Throwablee){
if(einstanceofException){returnhandleException((Exception)e,provider,uri);}
}
//目前的接口走不到这里
returnretVal;
}
请采纳!