2.Java安全之公钥与私钥-非对称加密


公钥与私钥机制属于非对称 加密的范畴,非对称是相对于对称加密而言的,对称加密用于加密与解密的密钥是同一把,而非对称加密则用于加密与解密的密钥不相同,一个公开,称为公钥;一个保密,称为私钥,公钥与私钥必须成对出现,只有是配对的公钥与私钥才能用于加解密。公钥通过非安全通道发放,私钥则由发放者保留,公钥加密的数据,只能使用其配对的私钥对其解密;反之,私钥加密的数据,只可使用公钥对其解密。

对称加密出现后有效地提升的数据的安全性,但是由于加密与解密用的是同一把密钥,这样除了通信双方需要约定加密算法之外,数据发送方还需要将密钥发送给接收方,这为密钥的管理带来很大不便,为了弥补这一弱势,非对称加密算法就运而生。对于非对称加密来说,其公钥本身就是公开的,大家都知道,所以就不存在公钥管理的问题,只需要将私钥安全保存即可,这就为安全通信带来了极大的便利。

非对称加密算法与对象加密算法相比,密钥管理不复存在,在安全性上有着无法逾越的高度,但其加/解密效率却要比对称加密低得多,因此非对象加密算法往往应用在一些安全性要深圳市相当高的领域,如电子商务平台、银行网关、支付系统等。针对非对称加密算法低效的问题,很多情况下是将对称加密算法与非对称加密算法相结合,使用对称加密算法为数据加/解密,使用公钥与私钥为对象加密算法密钥加/解蜜。利用对称加密算法的高效性,加之非对象加密算法的密钥管理,提升整体加密系统的安全性。而且在算法的设计上,非对象加密算法对待加密数据长度还有着极为严苛的要求。例如,RSA算法要求待加密数据不得超过53个字节。基于上述原因,非对称加密算法主要用于交换对称加密算法与秘密密钥,而非数据交换。

下面是一个Java中使用公钥与私钥的例子:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.xtayfjpk.security;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
 
import javax.crypto.Cipher;
 
import org.junit.Test;
 
public class KeyPairTest {
     private static final String ALGOGRITHM = "RSA" ;
     private static final String PUBLIC_KEY_PATH = "public.key" ;
     private static final String PRIVATE_KEY_PATH = "private.key" ;
     
     @Test
     public void testGenerate() throws Exception {
         //KeyPairGenerator引擎类用于产生密钥对,JDK(7)默认支持的算法有,DiffieHellman、DSA、RSA、EC
         KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGOGRITHM);
         //产生密钥对
         KeyPair keyPair = generator.generateKeyPair();
         //获取公钥
         PublicKey publicKey = keyPair.getPublic();
         //获取私钥
         PrivateKey privateKey = keyPair.getPrivate();
         
         //将公钥与私钥写入文件,以备后用
         writeKey(PUBLIC_KEY_PATH, publicKey);
         writeKey(PRIVATE_KEY_PATH, privateKey);
     }
     
     @Test
     public void testEncryptAndDecrypt() throws Exception {
         Cipher cipher = Cipher.getInstance(ALGOGRITHM);
         //读取私钥,进行加密
         PrivateKey privateKey = (PrivateKey) readKey(PRIVATE_KEY_PATH);
         cipher.init(Cipher.ENCRYPT_MODE, privateKey);
         //加密
         String sendInfo = "我的明文" ;
         byte [] results = cipher.doFinal(sendInfo.getBytes());
         
         //读取公钥,进行解密
         PublicKey publicKey = (PublicKey) readKey(PUBLIC_KEY_PATH);
         cipher.init(Cipher.DECRYPT_MODE, publicKey);
         //解密
         byte [] deciphered = cipher.doFinal(results);
         //得到明文
         String recvInfo = new String(deciphered);
         System.out.println(recvInfo);
     }
     
     public void writeKey(String path, Key key) throws Exception {
         FileOutputStream fos = new FileOutputStream(path);
         ObjectOutputStream oos = new ObjectOutputStream(fos);
         oos.writeObject(key);
         oos.close();
     }
     
     public Key readKey(String path) throws Exception {
         FileInputStream fis = new FileInputStream(path);
         ObjectInputStream bis = new ObjectInputStream(fis);
         Object object = bis.readObject();
         bis.close();
         return (Key) object;
     }
}

在上面的例子中,保存公钥与私钥是直接通过对象序列化机制完成的,与秘密密钥一样,也可以获取编码后的二进制数据(Key.getEncoded())保存

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值