Java 数字签名 PKI Keystore 数字证书 keytool jarsigner
摘要:本文介绍了数字签名的相关基础知识,并介绍了如何用java实现数字签名
数字签名作为一种电子身份的认证的手段,被普遍用于网上银行,安全网络通信等领域.数字签名是电子签名的一种特定形式.本文不对数字签名的原理作介绍,只对相关概念作一些简单的介绍,详细讲解了在java中如何对jar文件进行数字签名. |
数字签名的相关概念
实际上数字签名又称作基于PKI的电子签名, PKI的核心机构是电子认证服务提供者,即通称的认证机构CA,PKI签名的核心元素是由CA签发的数字证书,数字证书就如同日常生活中的身份证一样,用来标识网上实体的身份,CA就是对网上实体进行认证的第三方机构.数字证书就是CA机构对网上实体进行认证而产生的电子证书,它是数据签名的基础技术保障.CA机构对电子证书的有效性,有效期等提供查询服务.数字证书所包含公钥用来对使用对应的私钥加密的数据信息进行验证.
数字签名实现的具体原理是: 1、 将报文按双方约定的HASH算法计算得到一个固定位数的报文摘要。在数学上保证,只要改动报文中任何一位,重新计算出的报文摘要值就会与原先的值不相符。这样就保证了报文的不可更改性。(详见参考资料的"公钥密码技术原理"章节) 2、 将该报文摘要值用发送者的私人密钥加密,然后连同原报文和数字证书(包含公钥)一起发送给接收者而产生的报文即称数字签名。 3、接收方收到数字签名后,用同样的HASH算法对报文计算摘要值,然后与用发送者的公开密钥进行解密解开的报文摘要值相比较,如相等则说明报文确实来自所称的发送者。 4、同时通过证书颁发机构CA确认证书的有效性即可确认发送的真实身份。 |
数字证书的技术实现:
数字证书是公钥的载体,是PKI的核心元素.数字证书符合X.509标准,现行的PIK机制一般为又证书,即一个实体一般有两个证书,两个密码对,一个用于电子签名,一个用于加密通信.按照X.509标准,一个标准和数字证书的格式为:
CA《A》=CA{V,SN,AI,CA,UCA,A,UA,Ap,Ta}
它将包含证书颁发机构和标识及用户的标识,证书ID,有效期等信息(详见参考资料),另外还包含CA对此证书内容的进行了数字签名,以验证此证书的有效性.在验证一个数字证书的过程中,对数字证书的数字签名的验证将递归进行,只到找到双方共同可信任的CA根证书为止.
如何获取数字证书
数字证书可向专门的CA机构申请,有免费的数字证书和付费的数字证书.比如:中国数字认证网就可申请到有效期为一年的免费数字证书.注意申请的证书是以该CA的证书作为申请的个人证书的根证书,所以如果想要申请的证书有效,需要下载并安装相应CA的根证书.另外,其它一些工具也可生成个人使用的数字证书,如微软的makecert
JDK中包含的keytool工具(以下会详细介绍如何使用)都可生成没有经过认证的数字证书.
Java如何实现数字签名
JDK有部分工具和API提供了对数字签名的支持:keytool,jarsigner,policytool等.
KeyTool工具可生成,导入,导出数字证书,支持的证书的格式为当前流行的
生成证书:keytool -genkey -alias mykey -keystore mystore
导入证书:keytool -import -alias abc -file ABCCA.cer -keystore mystore
导出证书: keytool -export -alias mykey -file MJ.cer -keystore mystore
对jar文件进行签名使用的工具是jarsigner:
格式如下:jarsigner -keystore keystoreFile jarfile alias
例如:jarsigner -keystore sylilzyKeystore.dat test.jar sylilzy
验证一个jar文件如下:
jarsigner -verify jarfile
以下步骤演示了一个完整的由获取数字证书到签名jar文件,然后访问该jar文件时显示签名信息的全过程:
上面提到,数字证书可由以下方式生成,第一,去申请一个免费的数字证书,下载后为test.der
也可用keytool -genkey -alias mykey -keystore mystore生成,运行此命令后,提示相关信息,并填写完毕,如下:
E:\temp>keytool -genkey -alias mykey -keystore mystore 输入keystore密码: 111111 您的名字与姓氏是什么? [Unknown]: shi 您的组织单位名称是什么? [Unknown]: eshore 您的组织名称是什么? [Unknown]: de 您所在的城市或区域名称是什么? [Unknown]: gz 您所在的州或省份名称是什么? [Unknown]: gd 该单位的两字母国家代码是什么 [Unknown]: cn CN=shi, OU=eshore, O=de, L=gz, ST=gd, C=cn 正确吗? [否]: y 输入<mykey>的主密码 (如果和 keystore 密码相同,按回车): |
到此,我们则生成了一个名为mystore的keystore文件,该文件中保存有别名为mykey的数字证书.输入以下命令即可查看此数字证书:
E:\temp>keytool -list -alias mykey -keystore mystore |
或者带上-v参数显示详细信息
E:\temp>keytool -list -alias mykey -keystore mystore -v 输入keystore密码: 111111 别名名称: mykey 创建日期: 2006-7-5 输入类型:KeyEntry 认证链长度: 1 认证 [1]: Owner: CN=shi, OU=eshore, O=de, L=gz, ST=gd, C=cn 发照者: CN=shi, OU=eshore, O=de, L=gz, ST=gd, C=cn 序号: 44ab3fb8 有效期间: Wed Jul 05 12:27:36 CST 2006 至: Tue Oct 03 12:27:36 CST 2006 认证指纹: MD5: A1:A9:A7:C6:D8:E5:E5:20:EA:80:59:AF:C2:65:B4:17 SHA1: AC:8D:AA:9D:A7:62:48:70:ED:F4:28:4C:DC:DE:56:CE:41:FE:52:C9 |
以上为创建的一个证书,我们可以将它从keystore文件中导出:
E:\temp>keytool -export -keystore mystore -alias mykey -file my.cer 输入keystore密码: 111111 保存在文件中的认证 <my.cer> |
我们也可将前面从网上申请的电子证书导入keystore文件:
E:\temp>keytool -import -alias sily -file test.der -keystore mystore 输入keystore密码: 111111 Owner: CN=施祖阳, OU=develop, O=eshore, L=广州, ST=广东, C=CN 发照者: CN=CA365 Free Root Certificate, O=CA365, L=Beijing, ST=Beijing, C=CN 序号: 653e1a63bb003fb3 有效期间: Tue Jul 04 12:02:25 CST 2006 至: Wed Jul 04 12:02:25 CST 2007 认证指纹: MD5: 4A:AA:63:2A:8A:E2:8D:76:4B:2B:73:E9:F3:03:CD:6F SHA1: 02:B3:9E:D0:7E:BB:9E:C4:B3:B0:79:19:FA:89:B6:93:DB:0F:4A:88 信任这个认证? [否]: y 认证已添加至keystore中 |
现在查看mystore中已经存了两个证书:
E:\temp>keytool -list -keystore mystore 输入keystore密码: 111111 Keystore 类型: jks Keystore 提供者: SUN 您的 keystore 包含 2 输入 sily, 2006-7-5, trustedCertEntry, 认证指纹 (MD5): 4A:AA:63:2A:8A:E2:8D:76:4B:2B:73:E9:F3:03:CD:6F mykey, 2006-7-5, keyEntry, 认证指纹 (MD5): A1:A9:A7:C6:D8:E5:E5:20:EA:80:59:AF:C2:65:B4:17 |
现在,我们开始利用前面生成的数字证书给jar文件签名.由于applet在浏览器中运行时的权限是受限的,不能对本地文件进行读写,但是如果applet所在的jar文件如果是经过数字签名,并且用户信任该签名,那此applet则可对本地文件进行读写,下面给出一个写本地文件的applet:
package com.applet; import java.applet.Applet; public class TestSecurity extends Applet { /** * */ private static final long serialVersionUID = 1L; public TestSecurity() { System. out .println( "this is good! " ); } public void init() { JButton button = new JButton( "Create a file" ); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { File file = new File( "c:\\a.txt" ); try { file.createNewFile(); JOptionPane. showMessageDialog ( null , " 成功创建文件c:\\a.txt" , "消息" , JOptionPane. INFORMATION_MESSAGE ); } catch (Exception ex) { JOptionPane. showMessageDialog ( null , ex.getMessage(), "错误" , JOptionPane. ERROR_MESSAGE ); } } }); add(button); } }
将此文件编译后生成在com\applet生成两个class文件,用jar打包:
E:\sylilzy\documents\project\tjava\classes>jar -cvf test.jar com 标明清单(manifest) 增加:com/(读入= 0) (写出= 0)(存储了 0%) |
会发现在当前目录下会生成一个"test.jar"文件,将此文件copy到与mystore同一个目录,准备对该文件进行电子签名.
E:\temp>jarsigner -keystore mystore test.jar mykey 输入密钥库的口令短语: 111111 警告: 签名者证书将在六个月内过期。 |
则test.jar已经被签名,编码一个简单的html文件对其进行访问,html如下:
Created with Colorer-take5 Library. Type 'html'
<html><head><metahttp-equiv="Content-Type"content="text/html; charset=GB2312"><title>
HTML Test Page
</title></head><body>
test.Applet1 will appear below in a Java enabled browser.<br><appletcodebase="."code="com.applet.TestSecurity"name="TestApplet"width="400"height="300"hspace="0"vspace="0"align="middle"archive="test.jar"></applet></body></html>
将以上html文件与test.jar文件放在同一目录,用IE打开,则可看到IE弹出安全警告: The application's digital signature is invalid.Do you want to run the application?
用户可查看test.jar的签名信息,如果选择取消息,然后点击create a file 按钮,则提示:access denied(java.io.FilePermission c:\a.txt write)
如果在IE弹出安全警告选择"始终信任此发行者的内容",然后点击运行,再点击create a file 按钮,则提示:成功创建文件c:\a.txt
上面给test.jar签名的数字证书是未经验证的,现在我们使用从网上申请的经过验证的数字证书给test.jar签名,看会出现什么结果:
E:\temp>jarsigner -keystore mystore test.jar sily 输入密钥库的口令短语: 111111 jarsigner: 找不到 sily 的证书链。sily 必须引用包含专用密钥和相应的公共密钥证书链的有效密钥库密钥条目。 |
这是因为sily的证书链不存在导致的,我们需要导入sily的证书链才可形成完整的sily的证书链,可以通过keytool -certreq生成证书链的PKCS#10格式的请求,然后再导入请求的PKCS#7格式的回复即可,由于名为sily的key是从cer文件导入的,它在keystore中是以trusted certificate entries类型存储的,没有私钥,所以不能生成证书链的请求.我们可以将前面名为mykey的key导出证书请求,或者导出mykey的证书,然后将此证书安装至"受信任的根证书颁发机构",然后访问用此证书签名过的文件,则IE将不再弹出安全警告窗口.
相关推荐
Java数字签名源程序是用于实现数据完整性、身份验证和非否认性的关键技术,它在网络安全中扮演着重要角色。本程序是使用JAVA编程语言编写的,遵循了计算机科学中关于密码学的基本原理。数字签名通常与公钥基础设施...
JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字签名JAVA数字...
【Java数字签名提供XML安全】 XML(eXtensible Markup Language)作为一种标准的数据交换格式,在软件开发和数据传输中扮演着重要角色。然而,随着XML的广泛应用,数据的安全性问题日益凸显。为了确保XML文件的完整...
Java作为一种广泛使用的编程语言,提供了丰富的加密和数字签名功能来确保数据的安全传输和存储。本教程将带你快速入门Java中的加密和数字签名编程。 首先,让我们了解什么是加密。加密是一种将明文数据转化为难以...
Java 数字签名是一种用于验证数据完整性和发送者身份的安全机制,它是基于公钥加密技术的。在 Java 平台上,我们可以使用内置的 Keytool 和 Jarsigner 工具来实现数字签名的操作。以下是对这个主题的详细讲解: 一...
java xml数字签名工具类 拿来就能用
Java 数字签名是一种用于验证数据完整性和发送者身份的安全机制,它是基于公钥加密技术的。在Java中,数字签名通常使用Java Cryptography Architecture (JCA) 和 Java Cryptography Extension (JCE) 提供的API来实现...
在JavaApplet中,数字签名是一个至关重要的概念,它确保代码的完整性和来源的可信性,防止恶意篡改。本篇文章将深入探讨JavaApplet的数字签名方法以及如何使用打包签名工具JavaAutoPlug.exe来实现这一过程。 首先,...
"java数字签名和证书应用" 数字签名是指使用某种签名算法对某些内容进行数字签名后得到的数字凭证。证书(Certificate)是数字签名的一种特殊形式,是用某种签名算法对某些内容(比如公钥)进行数字签名后得到的,...
Java数字签名是一种在Java编程环境中实现的网络安全技术,主要用于确保数据的完整性和发送者的身份验证。这个资源包含的代码示例应该提供了关于如何在Java中实施数字签名的详细步骤。 在计算机网络中,数字签名是一...
通过理解和实践这个Java数字签名程序,我们可以更深入地了解数字签名的实现细节,这对于从事信息安全、区块链、加密通信等领域的工作至关重要。同时,对于Java程序员来说,熟悉这些安全相关的库和工具也能够提升他们...
下面将详细介绍这些算法以及它们在Java中的实现,以及如何进行数字签名和数字证书的验证。 1. **SM2算法**:SM2是一种基于椭圆曲线密码学(ECC)的公钥加密算法,用于非对称加密。它提供了密钥交换、签名和验证的...
Java实现的数字签名算法RSA完整示例 Java实现的数字签名算法RSA是一种常用的数字签名算法,主要用于验证数据完整性、认证数据来源、抗否认。下面将详细介绍Java实现的数字签名算法RSA的相关概念、原理、实现方法及...
以下是一个通用的Java数字签名和验证的步骤概述: 1. 导入所需的Java加密库: ```java import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; `...
Java 数字签名是一种用于验证数据完整性和发送者身份的...总的来说,Java数字签名提供了强大的安全功能,确保了在网络通信中的数据安全和身份认证。理解并正确使用数字签名和相关工具是开发安全的Java应用程序的基础。
这个“id_digital.rar”压缩包包含了与Java数字签名相关的源代码文件,可以帮助我们理解并实践这一技术。 首先,我们来看“GenerateKeyPair.java”。这个文件通常包含用于生成公钥和私钥对的代码。在数字签名中,...
Java 数字签名与数字证书是安全领域中的重要概念,它们在软件开发中起着至关重要的作用,尤其是在确保数据完整性和身份验证方面。本资源包含的Java代码工具包提供了生成数字签名和数字证书的源码,这有助于开发者...