java jvm学习笔记八(实现jar包的代码签名)

          欢迎装载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8267669

课程源码:http://download.csdn.net/detail/yfqnihao/4866500

这一节,以实践为主,在跟着我做相应的操作之前,我希望你已经能够理解笔记七所提到的概念,至少你应该对于笔记七的那个大图有所了解。

好了!对于习惯用ecplise的朋友今天不得不逼迫你把jdk的环境搭建出来!下面让我们动手来实践一下对jar进行签名吧!

 第一步,首先配置jdk的环境变量,如果你的电脑已经配置了,那直接跳过这一步

path=%JAVA_HOME%/bin
JAVA_HOME=C:/Java/jdk1.6.0_01
CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar    

配置要这几个jdk的环境参数,好了,配完了,试着在cmd里跑一下java,javac,看看命令是否生效,如果配置成功执行第二步。

 第二步,来写几个简单的类,简单的才是大家的。你完全可以直接copy我的代码,部分看不懂,忽略它,做实验而已,对那个jar文件签名不是签,这个例子的代码逻辑是后面才用到的,不用读

第一个类Doer

package com.yfq.test;

public abstract interface Doer {
    void doYourThing();
}

第二个类

package com.yfq.test.friend;

import java.security.AccessController;
import java.security.PrivilegedAction;

import com.yfq.test.Doer;

public class Friend implements Doer{
    private Doer next;
    private boolean direct;

    public Friend(Doer next,boolean direct){
        this.next=next;
        this.direct=direct;
    }

    @Override
    public void doYourThing() {
        System.out.println("Im a Friend");

        if (direct) {
            next.doYourThing();
        } else {
            AccessController.doPrivileged(new PrivilegedAction() {

                @Override
                public Object run() {
                    next.doYourThing();
                    return null;
                }

            });

        }
    }

}

第三个类

package com.yfq.test.stranger;

import java.security.AccessController;
import java.security.PrivilegedAction;

import com.yfq.test.Doer;

public class Stranger implements Doer {

    private Doer next;
    private boolean direct;

    public Stranger(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    @Override
    public void doYourThing() {
        System.out.println("Im a Stranger");

        if (direct) {
            next.doYourThing();
        } else {
            AccessController.doPrivileged(new PrivilegedAction() {

                @Override
                public Object run() {
                    next.doYourThing();
                    return null;
                }

            });

        }
    }

}

好了,编译一下,用强大的ecplise来编译,项目-右键-Build Project(工具是拿来用的,不要浪费这些强大的功能!)

第三步,打jar包,用ecplise就可以了就有导出jar包的功能,我还是那句老话,有工具不用,不是牛,是蠢。

步骤一,项目-右键-Export-java-JAR file-next

步骤二,展开目录清单-分别对com.yfq.tes.friend和com.yfq.test.stranger打包(friend.jar,stranger.jar),放到哪里就随便你了,只要你记得就好,我这里假设是放在d盘的根目录下

 第四步,用java的keytool生成密钥对,用java的jarsigner做签名(记得笔记七我们说过对hash摘要的加密是非对称加密的吗?这里就需要两把不同的钥匙啦),一步步跟我来。

步骤一,cmd窗口,进入到存放friend.jar和stranger.jar的目录下,假设我的jar文件放在d盘下,直接输入盘符d:就可以了。

步骤二,在cmd窗口中输入keytool -genkey -keystore ijvmkeys.keystore -keyalg RSA -validity 10000 -alias friend.keystore

生成第一个密钥对,这个密钥对的别名是 friend.keystore,采用的加密算法为RSA,密钥对的过期时间是10000天,密钥对存储的文件名ijvmkeys.keystore,而查看ijvmkeys.keystore的密码和friend.keystore密钥对的查看密码我们设置为123456

注意:这里在设置名字和姓氏的时候要特别的注意,不要随便的乱写,否则将导致后面的签名失败,一般我们写完网络域名的形式如:www.keycoding.com这样。

步骤三,在cmd窗口输入,keytool -genkey -keystore ijvmkeys.keystore -keyalg RSA -validity 10000 -alias stranger.keystore

按照步骤2的截图,一步一步输入吧,这个步骤是生成别名为stranger.keystore的密钥对。

好了密钥对生成结束,看看你的jar文件目录下有没有多出一个文件ijvmkeys.keystore,是滴,这里生成了一个用于存放密钥对的文件。

步骤四,查看生成的密钥文件,在cmd窗口输入keytool -list -v -keystore ijvmkeys.keystore

步骤五,对jar进行摘要并对hash摘要进行加密生成签名,放置到jar文件结构的尾部

在cmd窗口输入 
                                           jarsigner -verbose -keystore ijvmkeys.keystore friend.jar friend.keystore
                                           jarsigner -verbose -keystore ijvmkeys.keystore stranger.jar stranger.keystore

步骤六,右键frend.jar和stranger.jar用rar解压器看看它们在META-INF目录下是否生成了两个附加的文件

而关于这两个附加文件的用处,我这里也简单的说明一下,首先从名字上来讲他是八个字符,他默认取我们的密钥对的名字的前八个字符做名字而因为我们的密钥对名字是friend.keystore所以生成的名字将点替换为下滑线。如果你想要自己指定名字在keytool后面加上-sigFile XXXX这个参数

另外FRIEND_K.SF这个文件我们简单的展开

Signature-Version: 1.0
SHA1-Digest-Manifest-Main-Attributes: QHukAYw2MtCop4vlrhjJDDro1fQ=
Created-By: 1.6.0_12 (Sun Microsystems Inc.)
SHA1-Digest-Manifest: YePdyFc1+FVdY1PIcj6WVuTJAFE=

Name: com/yfq/test/friend/Friend$1.class
SHA1-Digest: mj79V3+YKsRAzxGHpyFGhOdY4dU=

Name: com/yfq/test/friend/Friend.class
SHA1-Digest: tqPfF2lz4Ol8eJ3tQ2IBvvtduj0=

它包含了签名的版本,签名者,还有被签名的类名,以及这个类的hash摘要,第四行是整个本文件的摘要,用于jar包的校验
FRIEND_K.DSA 文件,SF 文件被签名且签名被放入 .DSA 文件。.DSA 文件还包含来自密钥仓库的证书或证书链(被编码到其中),它们鉴别与用于签名的私钥对应的公钥。

步骤七,校验jar包在cmd中输入jarsigner -verify friend.jar和jarsigner -verify stranger.jar

到这里jar签名的实验已经完毕!!!!!

查看上面步骤四截图,我们来验证一下在笔记七里说过的话。

1.我们说过hash摘要是一个128的值,对不对呢,看证书指纹那一行,md5:....

你数一数总共有几个十六进制数,32个,一个十六进制数用4个位可以表示完,那么总共是几位,32*4=128,但是后面还有一个sha1的,怎么回事他貌似不止128位,是滴,散列函数多种多样,到底用那个散列函数,md5还是sha1这个就看你喜欢,而要使用哪个散列函数是可以指定的,keytool的参数-keyalg "DSA",这个参数就是用来指定用什么散列算法的,默认的就是DSA,普通的128位散列数已经是安全的了。

2.在 笔记七中,记不记得最下面那个图,有一个认证机构会对解密签名(被加密的hash摘要)的公钥做认证(也就是加密公钥),并发布证书,我们这里没有认证机构,你有没有这个疑问?

keytool程序在生成密钥时,总是会生成一个自签名证书(自签名是指:如果附近没有认证机构,可以用私钥对公钥签名,生成一个自签名证书)

总结:

通过本章我们学习对一个jar进行签名,一个jar可以同时被多个机构或作者签名,看起来实验很复杂其实很简单。如果你还想了解更多关于jar包签名的知识,本人在这里推荐一篇文章(http://blog.csdn.net/yangxt/article/details/1796965),本人自己在学习jar包签名的时候也从这篇文章中收益匪浅,希望它对你有帮助。

申明:以上文章部分描述有借用其他作者的总结,在此只做学习交流之用

时间: 2024-08-05 23:21:57

java jvm学习笔记八(实现jar包的代码签名)的相关文章

java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessController的checkPerssiom方法,访问控制器AccessController的栈检查机制又遍历整个 PerssiomCollection来判断具体拥有什么权限一旦发现栈中一个权限不允许的时候抛出异常否则简单的返回,这个过程实际上比我的描述要复杂 得多,这里我只是简单的一句带过,因为这

java jvm学习笔记十二(访问控制器的栈校验机制)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们会简单的描述一下jvm访问控制器的栈校验机制. 这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来. 第一步,配置系统环境.(copy吧,少年) path=%JAVA_HOME%/bin JAVA_HOME=C:/Java/jdk1.6

java jvm学习笔记十(策略和保护域)

欢迎转载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8271415 前面一节,我们做了一个简单的实验,来说明什么是策略文件,在文章的最后,也顺带的讲了一下什么是策略,还有策略的作用. 为了引出另外一个很重要的概念ProtectionDomain(保护域),所以我们还是要先来回顾一下什么是策略.                         首先,什么是策略,今天的东西纯粹是比较概念的.当然,如果你读过笔记九,今天的东西,就真的是sos

java jvm学习笔记十三(jvm基本结构)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 这一节,主要来学习jvm的基本结构,也就是概述.说是概述,内容很多,而且概念量也很大,不过关于概念方面,你不用担心,我完全有信心,让概念在你的脑子里变成图形,所以只要你有耐心,仔细,认真,并发挥你的想象力,这一章之后你会充满自信.当然,不是说看完本章,就对jvm了解了,jvm要学习的知识实在是非常的多.在你看完本节之后,后续我们还会来学jvm的细节,但是如果你在学习完本节的前提下去学习,再学习其他jvm的细节会事半功

java jvm学习笔记五(实践自己写的类装载器)

 欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类装载器和安全管理器是可以被动态扩展的,或者说,他们是可以由用户自己定制的,今天我们就是动手试试,怎么做这部分的实践,当然,在阅读本篇之前,至少要阅读过笔记三. 下面我们先来动态扩展一个类装载器,当然这只是一个比较小的demo,旨在让大家有个比较形象的概念. 第一步,首先

java jvm学习笔记三(class文件检验器)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,class文件校验器. class文件 校验器,保证class文件内容有正确的内部结构,java虚拟机的class文件检验器在字节码执行之前对文件进行校验,而不是在执行中进行校验class文件校验器要进行四趟独立的扫描来完成校验工作 class文件校验器分成四趟独立的扫描来完

java jvm学习笔记九(策略文件)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8271407 课程源码:http://download.csdn.net/detail/yfqnihao/4866503 什么是java的策略,什么又是策略文件. 今天我换一下笔记的方式,不是直接讲概念,而是先来做一个小例子,相信你做完这个例子之后再看我对例子的讲解,你对策略,策略文件,会豁然开朗的感觉. 例子很简单,简单的才是大家的,下面跟着我(你完全可以copy我的代码). 第一

Java基础学习笔记八 Java基础语法之接口和多态

接口 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”.接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义与实现分离,优化了程序设计.请记住:一切事物均有功能,即一切事物均有接口. 接口的定义 与定义类的class不同,接口定义时需要使用interface关键字.定义接口所在的仍为.java文件,虽然声明时使用的为interface关键字的编译后仍然会产生.class文件.这点可以让我们将接口看做是一种

Java NIO学习笔记八 DatagramChannel

Java NIO DatagramChannel Java NIO DatagramChannel是可以发送和接收UDP数据包的通道.由于UDP是一种无连接网络协议,因此您不能默认读取和写入DatagramChannel其他通道.而是发送和接收数据包. 打开DatagramChannel 打开一个DatagramChannel代码: DatagramChannel channel = DatagramChannel.open(); channel.socket().bind(new InetSo