[JAVA加解密]数字证书

数字 证书的格式普遍采用的是 X.509V3国际标准,一个标准的X.509数字证书包含以下一些内容:
证书的版本信息;
  证书的序列号,每个证书都有一个唯一的证书序列号;
  证书所使用的签名算法;
  证书的发行机构名称,命名规则一般采用X.500格式;
  证书的有效期,通用的证书一般采用UTC时间格式,它的计时范围为1950-2049;
  证书所有人的名称,命名规则一般采用X.500格式;
  
证书所有人的公开密钥
  证书发行者对证书的签名。

就是说主要包含签发机构的签名和证书所有人的公钥

数据交互时,证书所有人将自己的数字证书授权给一些人,这些人可以通过签发机构的公钥确认签发机构,证书所有人的公钥认证数据




一、数字证书:

一个字,太麻烦了

消息摘要算法----完整性

对称非对称加密-保密性

数字签名----------抗否认性


数字证书----------集合多种密码学算法:

自带:

①公钥信息-----------------完成加解密

②数字签名-----------------鉴别消息来源

③摘要信息-----------------完整性

④用户身份信息-----------认证性


为发布公钥提供了一种途径,成为加密算法及公钥载体


数字证书采用了公钥基础设施:

非对称加密算法:数据加密/解密->数据机密性

数字签名算法:数据签名、验证->数据完整性、抗否认性

消息摘要算法:数字证书摘要->数字证书完整性


二、现在我们用keytool产生的密钥库和证书为例:

注意几个点:

1、keytool最后产生了zlex.cer和zlex.keystore两个东西

2、数字证书(certificate)直接能得到公钥;

3、要得到私钥要用密钥库及密码;

private static PublicKey getPublicKeyByCertificate(String certificatePath) throws CertificateException, IOException{
		Certificate certificate = getCertificate(certificatePath);
		return certificate.getPublicKey();
	}

private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias,String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException{
		KeyStore ks = getKeyStore(keyStorePath,password);
		return (PrivateKey)ks.getKey(alias, password.toCharArray());
	}


由数字证书工厂CertificateFactory加载数字证书:工厂需要的参数是文件流

private static Certificate getCertificate(String certificatePath) throws CertificateException, IOException{
		CertificateFactory certificateFactory = CertificateFactory.getInstance(CERT_TYPE);
		FileInputStream is = new FileInputStream(certificatePath);
		Certificate certificate = certificateFactory.generateCertificate(is);
		is.close();
		return certificate;
	}


加载密钥库:ks.load(文件流,密码)

private static KeyStore getKeyStore(String keyStorePath, String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());//!!!
		FileInputStream is = new FileInputStream(keyStorePath);
		ks.load(is, password.toCharArray());
		is.close();
		return ks;
	}

注意getInstance后面是默认参数!!别傻到习惯性的来个定义好的常量


密钥库获得数字证书构建数字签名对象:

	public static byte[] sign(byte[] data,String keyStorePath,String alias,String password) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException, InvalidKeyException, SignatureException{
		X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath,alias,password);
		Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
		PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);
		signature.initSign(privateKey);
		signature.update(data);
		return signature.sign();
	}
	

Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());


总的来说,我们能从密钥库拿到私钥、数字证书;数字证书带有公钥,能产生数字签名


三、实现:

1.Junit测试用例:

public class CertificateCoderTest extends TestCase {
	private String password = "123456";
	private String alias="www.zlex.org";
	private String certificatePath="F:/Java/jdk1.8.0/bin/zlex.cer";
	private String keyStorePath="F:\\Java\\jdk1.8.0\\bin\\zlex.keystore";
	
	@Test
	public void test1() throws InvalidKeyException, CertificateException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException, UnrecoverableKeyException, KeyStoreException{
		System.err.println("公钥加密,私钥解密");
		String inputStr = "数字证书";
		byte[] data = inputStr.getBytes();
		
		byte[] encrypt = CertificateCoder.encryptByPublicKey(data, certificatePath);
		System.err.println("加密前:\n"+inputStr);
		byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt, keyStorePath, alias, password);
		String outputStr = new String(decrypt);
		
		System.err.println("解密后:\n"+outputStr);
		assertEquals(data,decrypt);
		
	}

}

我们能看到实现简单了很多,却同时保证了数据机密性,完整性,不可否认性。这些都是数字证书的功劳;

再有就是路径的输入方法:斜杠/斜杠/

或 反斜杠\\反斜杠\\  第一个为转义字符

除号为斜杠



2.数字证书实现类:

public abstract class CertificateCoder {
	public static final String CERT_TYPE="X.509";
	
	private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias,String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException{
		
		KeyStore ks = getKeyStore(keyStorePath,password);
	
		return (PrivateKey)ks.getKey(alias, password.toCharArray());
	}

	private static KeyStore getKeyStore(String keyStorePath, String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());//!!!
		FileInputStream is = new FileInputStream(keyStorePath);
		ks.load(is, password.toCharArray());
		is.close();
		return ks;
	}
	
	private static Certificate getCertificate(String certificatePath) throws CertificateException, IOException{
		CertificateFactory certificateFactory = CertificateFactory.getInstance(CERT_TYPE);
		FileInputStream is = new FileInputStream(certificatePath);
		Certificate certificate = certificateFactory.generateCertificate(is);
		is.close();
		return certificate;
	}
	
	private static Certificate getCertificate(String keyStorePath,String alias,String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
		KeyStore ks = getKeyStore(keyStorePath,password);
		return ks.getCertificate(alias);
	}
	
	
	private static PublicKey getPublicKeyByCertificate(String certificatePath) throws CertificateException, IOException{
		Certificate certificate = getCertificate(certificatePath);
		return certificate.getPublicKey();
	}
	
	public static byte[] encryptByPrivateKey(byte[] data,String keyStorePath,String alias,String password) throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);
		Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);
		return cipher.doFinal(data);
	}

	public static byte[] decryptByPublicKey(byte[] data,String certificatePath) throws CertificateException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		PublicKey publicKey = getPublicKeyByCertificate(certificatePath);
		Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}
	
	public static byte[] decryptByPrivateKey(byte[] data,String keyStorePath,String alias,String password) throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		
		PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);
		
		Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, privateKey);
		System.err.println("in de by private");
		return cipher.doFinal(data);
	}
	
	public static byte[] encryptByPublicKey(byte[] data,String certificatePath) throws CertificateException, IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
		PublicKey publicKey = getPublicKeyByCertificate(certificatePath);
		Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		return cipher.doFinal(data);
	}
	
	public static byte[] sign(byte[] data,String keyStorePath,String alias,String password) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException, UnrecoverableKeyException, InvalidKeyException, SignatureException{
		X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath,alias,password);
		Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
		PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);
		signature.initSign(privateKey);
		signature.update(data);
		return signature.sign();
	}
	
	public static boolean verify(byte[] data,byte[] sign, String certificatePath) throws NoSuchAlgorithmException, CertificateException, IOException, InvalidKeyException, SignatureException{
		X509Certificate x509Certificate = (X509Certificate)getCertificate(certificatePath);
		Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
		signature.initVerify(x509Certificate);
		signature.update(data);
		return signature.verify(sign);
	}
	
	
}





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值