`

Java密码学(6)——数字证书

 
阅读更多
  • 概述

消息摘要算法验证数据的完整性,对称加密和非对称加密算法保证了数据的保密性,数字签名算法用于抗否认性服务。

数字证书集合了这些知识:自身带有公钥信息,可以完成加解密操作;带有数字签名,可以鉴别消息来源;带有消息摘要信息,可以验证数据的完整性;含有用户身份信息,具有认证性。

数字证书需由数字证书颁发认证机构(Certificate Authority,CA)签发。签发过程实际上是对申请数字证书的公钥做数字签名,证书的验证过程实际上是对数字证书的公钥做验签,还包含证书有效期的验证。

数字证书的编码格式包括CER、DER、PKCS。

 

  • KeyTool

KeyTool是java中的数字证书管理工具。

1.生成密钥库文件yel.keystore

keytool -genkeypair -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 36000 -alias yel -keystore yel.keystore

参数含义:

 -genkeypair    生成密钥对

-keyalg            密钥算法

-keysize           密钥长度

-sigalg             签名算法

-validity           证书有效期

-alias              别名

-keystore        密钥库文件名

之后提示输入用户相关信息和别名对应的密码(这里输入123456)

最后生成了密钥库文件yel.keystore,里面包括公钥和私钥。一个keystore里面可以有多个证书信息,每个证书用别名区分。

可以用如下命令查看一个keystore里面的所有别名

D:\>keytool -list  -keystore yel.keystore

2.从密钥库导出数字证书yel.cer

D:\>keytool -exportcert -alias yel -keystore yel.keystore -file yel.cer -rfc

参数含义:

-exportcert    导出证书操作

-alias             别名

-keystore       密钥库文件

-file                证书文件

-rfc                以Base64编码输出

之后输入别名对应的密码123456

最后生成了数字证书,里面包含了公钥

 

  • 证书使用

 下面代码实现了从keystore文件获取私钥,从cer文件获取公钥

	/**
	 * 从密钥库得到私钥
	 * @param keyStorePath
	 * @param alias
	 * @param password
	 * @return
	 */
	public static PrivateKey getPrivateKeyByKeystore(String keyStorePath, String alias, String password){
		try {
			KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
			FileInputStream is = new FileInputStream(keyStorePath);
			ks.load(is, password.toCharArray());
			is.close();
			
			return (PrivateKey)ks.getKey(alias, password.toCharArray());
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 从证书得到公钥
	 * @param certificatePath
	 * @return
	 */
	public static PublicKey getPublicKeyByCertificate(String certificatePath){
		try {
			CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
			FileInputStream is = new FileInputStream(certificatePath);
			Certificate certificate = certificateFactory.generateCertificate(is);
			is.close();
			
			return certificate.getPublicKey();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 私钥加解密
	 * @param data
	 * @param privateKey
	 * @param mode
	 *            0-加密,1-解密
	 * @return
	 */
	public static String codeByPrivateKey(String data, PrivateKey privateKey, int mode){
		try {
			Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
			if (mode == 0) {
				cipher.init(Cipher.ENCRYPT_MODE, privateKey);
			} else {
				cipher.init(Cipher.DECRYPT_MODE, privateKey);
			}
			return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data
					.toCharArray())));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} 
		return null;
	}
	
	/**
	 * 公钥加解密
	 * @param data
	 * @param publicKey
	 * @param mode
	 *            0-加密,1-解密
	 * @return
	 */
	public static String codeByPublicKey(String data, PublicKey publicKey, int mode){
		try {
			Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
			if (mode == 0) {
				cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			} else {
				cipher.init(Cipher.DECRYPT_MODE, publicKey);
			}
			return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data
					.toCharArray())));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} 
		return null;
	}
	
	/**
	 * 签名
	 * @param data
	 * @param keyStorePath
	 * @param alias
	 * @param password
	 * @return
	 */
	public static String sign(String data, String keyStorePath, String alias, String password){
		try {
			//获得密钥库  
			KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
			FileInputStream is = new FileInputStream(keyStorePath);
			ks.load(is, password.toCharArray());
			is.close();
			//获得证书
			X509Certificate x509Certificate = (X509Certificate)ks.getCertificate(alias);
			
			Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
			PrivateKey privateKey = getPrivateKeyByKeystore(keyStorePath, alias, password);
			signature.initSign(privateKey);
			signature.update(Hex.decodeHex(data.toCharArray()));
			return Hex.encodeHexString(signature.sign());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 验签
	 * @param data
	 * @param sign
	 * @param certificatePath
	 * @return
	 */
	public static boolean verify(String data, String sign, String certificatePath){
		try {
			//获得证书
			CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
			FileInputStream is = new FileInputStream(certificatePath);
			Certificate certificate = certificateFactory.generateCertificate(is);
			is.close();
			X509Certificate x509Certificate = (X509Certificate)certificate;
			
			Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
			signature.initVerify(x509Certificate);
			signature.update(Hex.decodeHex(data.toCharArray()));
			return signature.verify(Hex.decodeHex(sign.toCharArray()));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

 测试代码

		String password = "123456";
		String alias = "yel";
		String certificatePath = "d:/yel.cer";
		String keyStorePath = "d:/yel.keystore";
		
		PrivateKey privateKey = getPrivateKeyByKeystore(keyStorePath, alias, password);
		System.out.println("从密钥库得到私钥:"+Hex.encodeHexString(privateKey.getEncoded()));
		PublicKey publicKey = getPublicKeyByCertificate(certificatePath);
		System.out.println("从证书得到公钥:"+Hex.encodeHexString(publicKey.getEncoded()));
		String data = "404142434445464748494a4b4c4d4e4f";
		System.out.println("原始数据:"+data);
		String encode = codeByPrivateKey(data, privateKey, 0);
		System.out.println("私钥加密后:"+encode);
		String decode = codeByPublicKey(encode, publicKey, 1);
		System.out.println("公钥解密后:"+decode);
		encode = codeByPublicKey(data, publicKey, 0);
		System.out.println("公钥加密后:"+encode);
		decode = codeByPrivateKey(encode, privateKey, 1);
		System.out.println("私钥解密后:"+decode);
		String sign = sign(data, keyStorePath, alias, password);
		System.out.println("签名结果:"+sign);
		System.out.println("验签结果:"+verify(data, sign, certificatePath));

 运行结果

从密钥库得到私钥:308204bf020100300d06092a864886f70d0101010500048204a9308204a50201000282010100d555cb21768827f01d040c33fe63b279c6abb318441e061c74ee28bb24e190bc4f913aef99f37d951c037a5b6d80743bede3a4caa4e030ed35ad333e0d563b13bf0416794da36ce8e0cebc25fda69d964f3607212dd927598c7bb7d8557de5a0d4c93aeb72600bff67740860e5e3cf6bd5f43986a1665cbfed72eae2f81d5de064da5ecaf188b775e149f8fbf983a6e881815e459df452662353596caedb181031c9172a3330eec9c1930e1475025e29cf7bf8fb477c0462e1251521a06a53171d81c546bb5f3278c8f8c15117b96285dccb8e86bea997f83a5bb493246e811284b6895f54e73f626f9920ba203dbe7992360bfa90481068965851164c8cb89d02030100010282010100a2a88c7dd2339447f6c7ac4a446f5d988e0b423d814a671c71675934ffb4e0b743ef96c1335fbce3e0fd21e0ee07e0180594e983fcdc5751b5f87e3694d2a7aeb198fb4db80da02f9ba0e5420e3968b43f67115e91e79da220840033f95349af2c2ed636c8f9448c93239c73cd34ba651d37de58b15d2be0c6ba352fa34038df475c5fc377c76fc52a7cf42f7f66f9f5d776ea44ff431e63b4571d543ef1742634bd7e7e66bccaf0bc20839f240376c74bf01bc93b15dc077a067c045a4b2df7e40a11f79f5588863417aad6d139bc83a7975bd7ead46677154b959eb66fba892b29df21ca8d81e4db5df6a0e97250f184145e760d1f615801a4d46dbbc7f50102818100f0fdcbf6e2e37565cc7907abde4db1fe0c18373adbd8a423caed395edbe5985d84d246ca5a3bc72ec1f1517b4c815e5646dc96790dd6bcc63b71d18064c7ea6b00a18f33b1df78c7ec1ceef84d0fa51aac06312840ea3f81d6c38e93394b389ae128c7ada674c2b48d77d5ee7680ed2393a6073b15157243c5fb8e14982f88c102818100e29f1065f126e310d7e5584415954583bc9d28c38c69598effe98fdedfb64c80f89d4e4599ab87fc2e040800c17e855127c990b91ee455cfc6bac4f8699629c3b479d702a1931239cff43d341d4ffa633bd252fa5703bd0b15d8c1dafd886b7aca8a789d1a6e9754004008000eb04780ba07ca5f524436a6068e5fcc70142add02818100e653db964a81d51987950184fd824aa521901f714cdfc0f948a0f45d3a54350ce4be48d46beb8852a3206e9d26a0dab62122015b0fa3f6668c381b60d871ce1598d3d0d73aa0f88233a3efae3790c55f399ced6ca8a67a2e314254c957501278cccc3a1438ec8d8f1d4ab4982680d0a5591facf7860e2a58a627e842bcb569c1028181009975732a4509bb3b5da75d85054486c535850ae498818276f64ed7f0e976ce098bd121feb997d146f076246136a6116b2a5131225a8bee9bfb8bdff403b3fee61aa162fad22500738ba16d8c8bc8ebda24d940fd6acd0a47a66c98a14d8c02942cf165c9a4eb7ca8125f49cb9826c0d4a7a4bce29d97b995e5dca57c8fece8350281805635aa9d8d495f125fba73ae3cdec18d6baeeb26074d008bf5034899b94ead620cfc41a2ce10e8a7128c337bd9d013c159ede469f52778af4c512f0e22c03b19797038c25a14e21a80d4e9b3a5da3fdeddcc06c86729e287b3012948af708c44a85024946b6fb116c12772a2de94f73c06d9a927736220c17b781a605d49fbc1
从证书得到公钥:30820122300d06092a864886f70d01010105000382010f003082010a0282010100d555cb21768827f01d040c33fe63b279c6abb318441e061c74ee28bb24e190bc4f913aef99f37d951c037a5b6d80743bede3a4caa4e030ed35ad333e0d563b13bf0416794da36ce8e0cebc25fda69d964f3607212dd927598c7bb7d8557de5a0d4c93aeb72600bff67740860e5e3cf6bd5f43986a1665cbfed72eae2f81d5de064da5ecaf188b775e149f8fbf983a6e881815e459df452662353596caedb181031c9172a3330eec9c1930e1475025e29cf7bf8fb477c0462e1251521a06a53171d81c546bb5f3278c8f8c15117b96285dccb8e86bea997f83a5bb493246e811284b6895f54e73f626f9920ba203dbe7992360bfa90481068965851164c8cb89d0203010001
原始数据:404142434445464748494a4b4c4d4e4f
私钥加密后:59509d4aecb4af0c0f06ffd86ab2399d593895957f0805be798716ae494d3cc0a62ba1389dbdc512994e07e45c09b9ff0b2c77c1a59684d0aa6d98db46870a17bb2645b140a33a34ceb44cb10f0d0b109f8269a75bbc32170e306e48a1bdb2516ed2415d436409f75c9ad8f208334d9084f5950f4fc1d970f74a63d874c8d1946dc7ab484f96232365c49ff84f3d837e8e259331c33df6ecf71f6d79b8b984116572927bb1b8f0e10225c64fa9565b55e1485ec5817347306ba5c2d31fb5c00475e84bbb203f6f1c963ceed3e6ec23f295d472e79bf81600c0587363a13f14a0a521344cfbd5341300b6592ff3119aec4123512e8fdb44aa73b2ce296d4e0a01
公钥解密后:404142434445464748494a4b4c4d4e4f
公钥加密后:0300025c7b7758937c4de72a699d6685d350ce09b6d64328f2c14ccb55df6cb1e331aed84e3267f8b7e876dea580e3435da9f8d6828c75ff05020192e2404ab44fe0d0bfbb20479c728ba3eea98aefc99fec710b42ff4c70b060139811d019801795cb65300ba963a0114b54fd4c1f29b8f455d14e32bb6a4d4d5956b6b49d2d58e92edd700157b7e29c95f89863a701ea7b67d009721b5b7e83a37fc92fb6f39cefab40663059020f59130cbdb0f56afb7573e615fa2f779af2d0a15587f4b497b15c58cfb21951a6ca1f4f0a10638f892d11abc83a8a7523079279021ad8af968debf32fb847aa7142a5d19396a2105bf76589fe11cdac95156d167c815217
私钥解密后:404142434445464748494a4b4c4d4e4f
签名结果:9b43679b84fdcc0bf1dbff5d7a3ac59ea36f91adf1e62f5db5b4d12516d57e6101fe469144b60a042943f3a7687952a5c8059fc840d834394fa821f6b99957c7302d27dcb31775fbae46a743a4b2de21da4a3a76bded1ee0e2bb61e0c20f433e9731b31e99c05ad534799d97ad9d6ecb81316a65ee6ede613561e149efb6d7de3454ee1930d914edf3a610bc8ff9aaa100fb83f356ed40a00432cf2b2ea1d4667a9d34f531d8e262a1ddb63da22d7866b283777810f8e2c150bf588afde186b55778bfd6812eb72a75f77ded07fbb2709ad3781571fa3e917cf94a801074535e700c6cbb542f996257fdd256fccf20244b55da1371589bd8658f62756fba6a12
验签结果:true

 完整代码http://dl.iteye.com/topics/download/b112e7e7-727b-38a3-9d44-6b963dee377e

  • 大小: 56.7 KB
  • 大小: 14.7 KB
分享到:
评论

相关推荐

    java源码包---java 源码 大量 实例

     Java 数字签名、数字证书的相关实例。  关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据...

    JAVA上百实例源码以及开源项目源代码

     Java 数字签名、数字证书的相关实例。  关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据...

    JAVA上百实例源码以及开源项目

     Java 数字签名、数字证书的相关实例。  关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据...

    java源码包4

     Java 数字签名、数字证书的相关实例。  关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据...

    java源码包3

     Java 数字签名、数字证书的相关实例。  关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据...

    java源码包2

     Java 数字签名、数字证书的相关实例。  关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用私钥对信息(info)签名,用指定算法产生签名对象,用私钥初始化签名对象,将待签名的数据...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java 数字签名、数字证书生成源码 2个目标文件 摘要:JAVA源码,系统相关,数字签名,数字证书 Java 数字签名、数字证书的相关实例。 关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用...

    Java安全性编程实例(徐迎晓)

    密码学也是安全机制的基础。 # 第三章 # 解决的主要问题——和源代码相关的安全性 # 编写好的程序给用户后,用户如果能反编译出源代码怎么办? # 定义类、成员变量、方法时如何防止恶意或无意的攻击? # 主要内容...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    Java 数字签名、数字证书生成源码 2个目标文件 摘要:JAVA源码,系统相关,数字签名,数字证书 Java 数字签名、数字证书的相关实例。 关于数字签名:产生RSA密钥对(myKeyPair),得到RSA密钥对,产生Signature对象,对用...

    C#微软培训资料

    1.1 Microsoft.NET——一场新的革命.4 1.2 .NET 与 C#.6 1.3 C#语言的特点.8 1.4 小 结 .11 第二章 运行环境 全面了解.NET.12 2.1 .NET 结构.12 2.2 公用语言运行时环境与公用语言规范.13 2.3 开 发 ...

Global site tag (gtag.js) - Google Analytics