`
liulanghan110
  • 浏览: 1076767 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

用JAVA签发数字证书

    博客分类:
  • JAVA
阅读更多

前一篇http://zhuyuehua.iteye.com/blog/1101041 说到创建TOMCAT下HTTPS项目,现在接着说,如何签发证书。

打开cmd

1.输入D:

 

2.输入cd keys

 

3.输入命令查看创建的密钥库的证书列表

keytool -list -v -keystore mykey.keystore -storepass 123456

如下图:

 



 4. 之前导出过server.cer文件,把这个文件安装到操作系统,过程默认。

 

5.创建一个密钥对,和之前一样,输入如下命令:

 

--创建密钥对

keytool -genkey -dname "CN=tmp, OU=NC, O=Shanghai University, L=ZB, ST=Shanghai,C=CN" -alias client  -keyalg RSA -keystore myclientkey.store -keypass 654321 -storepass 654321 -validity 1000

 

--导出公钥

keytool -export -trustcacerts -alias client  -file client.cer -keystore  myclientkey.store -storepass 654321

 

双击client.cer可以看到:



 该证书不被系统信任,且颁发者和颁发给都是tmp

 

5.签发证书,这里采用的是JAVA程序来签发。可以用OPENSSL签发或者到正式CA机构签发。

 

由于已经把server.cer安装到客户机电脑上,所以客户机操作系统会信任server.cer中的机构签发的证书。

 

这里就用server.cer中的机构来签发client.cer

 

签发代码:

package com.syspro.test;

import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.util.*;
import java.math.*;
import sun.security.x509.*;
public class SignCert {
	
	private String mKeystore = "D:/keys/mykey.keystore"; // 密锁库路径
	private char[] mKeystorePass = "123456".toCharArray();// 密锁库密码
	private char[] mSignPrivateKeyPass = "123456".toCharArray();// 取得签发者私锁所需的密码
	private String mSignCertAlias = "keytest";// 签发者别名
	private String mSignedCert = "D:/keys/client.cer"; // 被签证书
	private String mNewCert = "D:/keys/clientSignKey.cer"; // 签发后的新证书全名
	private int mValidityDay = 3000; // 签发后的新证书有效期(天)

	private PrivateKey mSignPrivateKey = null;// 签发者的私锁
	private X509CertInfo mSignCertInfo = null;// 签发证书信息
	private X509CertInfo mSignedCertInfo = null;// 被签证书信息
	   
	 public void  Sign() throws Exception{
			try {
				/**
				 * 证书签名
				 */
				getSignCertInfo(); // 获取签名证书信息
				signCertificate(); // 用签名证书信息签发待签名证书
				createNewCertificate(); // 创建并保存签名后的新证书
			} catch (Exception e) {
				System.out.println("Error:" + e.getMessage());
			}
	 }
	 
	 /**
	 * 取得签名证书信息
	 * @throws Exception
	 */
	 private void getSignCertInfo() throws Exception
	 {
	 FileInputStream vFin=null;
	 KeyStore vKeyStore=null;
	 java.security.cert.Certificate vCert=null;
	 X509CertImpl vCertImpl=null;
	 byte[] vCertData=null;

	 //获取签名证书密锁库
	 vFin=new FileInputStream(mKeystore); 
	 vKeyStore=KeyStore.getInstance("JKS");
	 vKeyStore.load(vFin,mKeystorePass);
	 //获取签名证书
	 vCert= vKeyStore.getCertificate(mSignCertAlias);
	 vCertData=vCert.getEncoded();
	 vCertImpl=new X509CertImpl(vCertData);
	 //获取签名证书信息
	 mSignCertInfo=(X509CertInfo)vCertImpl.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);
	 mSignPrivateKey=(PrivateKey)vKeyStore.getKey(mSignCertAlias,mSignPrivateKeyPass);
	 vFin.close();
	 }



 	/**
 	 * 取得待签证书信息,并签名待签证书
 	 * 
 	 * @throws Exception
 	 */
 	private void signCertificate() throws Exception {
 		FileInputStream vFin = null;
 		java.security.cert.Certificate vCert = null;
 		CertificateFactory vCertFactory = null;
 		byte[] vCertData = null;
 		X509CertImpl vCertImpl = null;

 		// 获取待签名证书
 		vFin = new FileInputStream(mSignedCert);
 		vCertFactory = CertificateFactory.getInstance("X.509");
 		vCert = vCertFactory.generateCertificate(vFin);
 		vFin.close();
 		vCertData = vCert.getEncoded();
 		// 设置签名证书信息:有效日期、序列号、签名者、数字签名算发
 		vCertImpl = new X509CertImpl(vCertData);
 		mSignedCertInfo = (X509CertInfo) vCertImpl.get(X509CertImpl.NAME + "."
 				+ X509CertImpl.INFO);
 		mSignedCertInfo.set(X509CertInfo.VALIDITY, getCertValidity());
 		mSignedCertInfo.set(X509CertInfo.SERIAL_NUMBER, getCertSerualNumber());
 		mSignedCertInfo.set(X509CertInfo.ISSUER + "."
 				+ CertificateIssuerName.DN_NAME,
 				mSignCertInfo.get(X509CertInfo.SUBJECT + "."
 						+ CertificateIssuerName.DN_NAME));
 		mSignedCertInfo.set(CertificateAlgorithmId.NAME + "."
 				+ CertificateAlgorithmId.ALGORITHM, getAlgorithm());

 	}

 	/**
 	 * 待签签证书被签名后,保存新证书
 	 * 
 	 * @throws Exception
 	 */
 	private void createNewCertificate() throws Exception {
 		FileOutputStream vOut = null;
 		X509CertImpl vCertImpl = null;
 		// 用新证书信息封成为新X.509证书
 		vCertImpl = new X509CertImpl(mSignedCertInfo);
 		// 生成新正书验证码
 		vCertImpl.sign(mSignPrivateKey, "MD5WithRSA");
 		vOut = new FileOutputStream(mNewCert );
 		// 保存为der编码二进制X.509格式证书
 		vCertImpl.derEncode(vOut);
 		vOut.close();

 	}

 	// 辅助方法===========================================================================

 	/**
 	 * 得到新证书有效日期
 	 * 
 	 * @throws Exception
 	 * @return CertificateValidity
 	 */
 	private CertificateValidity getCertValidity() throws Exception {
 		long vValidity = (60 * 60 * 24 * 1000L) * mValidityDay;
 		Calendar vCal = null;
 		Date vBeginDate = null, vEndDate = null;
 		vCal = Calendar.getInstance();
 		vBeginDate = vCal.getTime();
 		vEndDate = vCal.getTime();
 		vEndDate.setTime(vBeginDate.getTime() + vValidity);
 		return new CertificateValidity(vBeginDate, vEndDate);
 	}

 	/**
 	 * 得到新证书的序列号
 	 * 
 	 * @return CertificateSerialNumber
 	 */
 	private CertificateSerialNumber getCertSerualNumber() {
 		Calendar vCal = null;
 		vCal = Calendar.getInstance();
 		int vSerialNum = 0;
 		vSerialNum = (int) (vCal.getTimeInMillis() / 1000);
 		return new CertificateSerialNumber(vSerialNum);
 	}

 	/**
 	 * 得到新证书的签名算法
 	 * 
 	 * @return AlgorithmId
 	 */
 	private AlgorithmId getAlgorithm() {
 		AlgorithmId vAlgorithm = new AlgorithmId(
 				AlgorithmId.md5WithRSAEncryption_oid);
 		return vAlgorithm;
 	}
 	
 	public static void main(String args[]) throws UnsupportedEncodingException
	{
		SignCert s = new SignCert();
		try {
			s.Sign();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

} 

 打开签名完成后的新证书clientSignKey.cer,如下图:

 



 会看到此时,操作系统会信任该证书,而且颁发者变成了server.cer中的localhost

 

再将签名后的数字证书clientSignKey.cer和CA证书server.cer导入myclientkey.store库中,命令如下:注意先后顺序

先倒入CA证书
keytool -import -alias ca -keystore D:\keys\myclientkey.store  -trustcacerts -file D:\keys\server.cer -storepass 654321

注意-alias 和之前的不一样。

再导入签名后的证书:

keytool -import -alias client -keystore D:\keys\myclientkey.store  -trustcacerts -file D:\keys\

clientSignKey.cer -storepass 654321

 

注意-alias 和之前的一样。

 

操作完后修改tomcat的server.xml文件,如下:

  <Connector protocol="org.apache.coyote.http11.Http11NioProtocol" 
				port="8443"  enableLookups="true" 
				disableUploadTimeout="true" acceptCount="100" 
				maxThreads="200" scheme="https" secure="true" 
				SSLEnabled="true"  sslProtocol="TLS" 
				clientAuth="false"
				keystoreFile="D:\keys\myclientkey.store" 
				keystorePass="654321" />

 然后启动tomcat,就会发现不会再提示了。

 

注:由于myclientkey.store的cn不是localhost,所以之前那样的设置打开网站时还是会提示不信任的证书。解决办法是将

myclientkey.store的cn写成localhost(你需要访问的网站地址),当然之前那个CA的密钥库的CN就不要写成localhost了,

随便写个别的就好。

 

 

注意,这样之后httpclient还是不会信任该证书,可以这样操作:

切换到<java-home>\jar\lib\security\目录下:

keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file

clientSignKey.cer

  • 大小: 54.7 KB
  • 大小: 29.9 KB
  • 大小: 28.2 KB
分享到:
评论

相关推荐

    java获取数字证书信息

    在本篇文章中,我们将深入探讨如何使用Java来获取数字证书的信息,包括使用TOMCAT和JDK搭建SSL服务的过程、如何用OpenSSL签发证书以及如何支持第三方CA等内容。 #### 一、使用TOMCAT和JDK搭建SSL服务 ##### 1. ...

    JAVA 用代码生成数字证书源码

    在Java编程环境中,生成数字证书是一项关键的安全技术,主要用于数据加密、身份验证和签名等应用场景。数字证书通常包含了公钥和私钥对,以及证书持有者的相关信息,这些信息经过认证机构(CA)的签名,确保了证书的...

    java安全通信数字证书

    本篇文章将深入探讨Java中如何实现安全通信、生成和使用数字证书。 首先,我们了解两个基础概念:消息摘要和消息验证码。消息摘要是一种算法,通过该算法对原始数据进行处理,生成一个固定长度的摘要值,类似于数据...

    SM2 SM3 X.509 Cert 国密 数字签名 算法 国密证书 生成 签发 证书请求 keystore 纯java.zip

    Java是一种高性能、跨平台的面向...自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。

    Certificate_java_java数字签名_java签名证书_数字证书_

    数字证书是一种电子文档,由可信的第三方机构(称为证书颁发机构,简称CA)签发,用于证明网络实体的身份。它包含了公钥的所有者信息、公钥本身、颁发者的身份以及证书的有效日期。在Java中,这些证书通常存储在JKS...

    JAVA对数字证书的常用操作

    ### JAVA对数字证书的常用操作 #### 一、需要包含的包 在进行数字证书的操作之前,我们需要导入一些必要的Java包。这些包主要用于处理安全相关的类和接口。 ```java import java.security.*; import java.io.*; ...

    java对数字证书常用操作

    在Java编程环境中,数字证书是实现安全套接层(SSL)通信、确保数据传输安全的重要工具。本篇文章将深入探讨Java对数字证书的常用操作,包括导入必要的库、从文件中读取证书、从密钥库中直接读取证书、显示证书信息...

    java生成CA证书

    它们验证申请者的身份,并在确认无误后,用CA的私钥为申请者生成一个数字证书,包含申请者的公钥和身份信息。用户可以通过检查证书上的CA签名来确认公钥的合法性。 4. **Java中的KeyPairGenerator和KeyStore类**:...

    Java实现浏览器CA证书的签名和验证

    通过使用Java技术实现数字证书的签名和验证,不仅可以提高应用的安全性,还可以增强用户对系统的信任。尽管实现过程可能较为复杂,但通过遵循上述步骤,开发者可以有效地提升应用程序的安全级别,特别是在涉及敏感...

    Java 数字签名、数字证书生成源码

    Java 数字签名和数字证书是网络安全领域中的重要概念,它们在确保数据的完整性和认证信息来源的可靠性方面发挥着关键作用。在这个Java源码包中,我们可能找到了用于生成数字签名和数字证书的相关代码,这对于理解和...

    基于Java的数字签名、数字证书生成源码.zip

    3. 签发证书:使用`java.security.cert.X509CertGenerator`生成自签名证书,这里既是CA也是证书持有者,所以用自己的私钥对请求进行签名。 4. 导出证书:证书可以以PEM或DER格式存储,方便使用。 在给定的压缩包...

    JAVA keytool数字证书生成及应用

    例如,你可以用它来创建和管理内部的 Certificate Authority (CA),从而签发和管理组织内部的数字证书。 总之,`JAVA keytool`数字证书生成及应用是一个涵盖密钥对管理、证书创建、导入导出、以及安全配置等多个...

    数字证书应用系统的设计与实现

    【数字证书应用系统设计与实现】的论述集中在构建一个基于Java和Microsoft SQL Server 2008的数字证书系统,该系统旨在加深学习者对数字证书原理和应用的理解,同时改进实验室教学环境。数字证书是网络安全领域的...

    jp0207BB.rar mscrypto.jar Windows下Java如何使用数字证书

    本文将详细探讨如何在Windows操作系统中使用Java来操作和利用数字证书,主要以`mscrypto.jar`为例进行讲解。 首先,理解数字证书是至关重要的。数字证书是一种电子文档,由受信任的证书颁发机构(CA)签发,用于...

    CFCA证书环境Java安装

    CFCA证书环境的Java安装是确保Java应用能够识别并信任CFCA签发的数字证书的关键步骤。下面将详细介绍如何进行这一过程。 首先,你需要了解CFCA证书的基本概念。CFCA是一家权威的数字证书颁发机构,其SSL证书用于...

    Java数字证书的一些实例

    ### Java数字证书实例详解 #### 一、所需导入的包 在进行Java数字证书操作时,需要导入以下包来确保程序能够顺利执行相关的安全和证书处理功能: ```java import java.security.*; import java.io.*; import java...

    电子商务安全与支付(微课版第2版)-实验指导-数字证书.docx

    二、使用Java程序签发数字证书 在这个实验中,我们使用上面确定的CA“wang zhihui”对证书“wzh”进行签发。我们使用J2SDK内部使用的X509CertImpl类来创立新的证书,该类的构造器中传入有关新的证书的各种信息,...

    数字证书及其简单数字签名的实现

    而`SignCert.java`很可能包含了创建、验证数字证书和数字签名的函数。 在`SignCert.java`中,我们可以预期找到如下功能: 1. 生成公钥和私钥对:这通常是通过RSA或ECC等非对称加密算法实现的。 2. 创建数字证书:...

Global site tag (gtag.js) - Google Analytics