非对称加密算法
加密和解密使用不同的密钥,这种算法称为非对称加密算法
特点:
- 必须有两个密钥,一个公钥,一个私钥
- 公钥和私钥是一对,称为密钥对
- 如果使用公钥加密,必须使用私钥解密
- 如果使用私钥加密,必须使用公钥解密
- 处理数据速度慢
- 安全级别高
-举个例子:
-
首先生成密钥对, 公钥为(5,14), 私钥为(11,14)
-
现在A希望将原文2发送给B
-
A使用公钥加密数据. 2的5次方mod 14 = 4 , 将密文4发送给B
-
B使用私钥解密数据. 4的11次方mod14 = 2, 得到原文2
-分类:
- RSA
- ECC
开始代码讲解!!
1.怎样生成公钥和私钥?
准备工作:
- 定义加密算法
String algorithm = “RSA”;
- 创建密钥对生成器对象
KeyPairGenerator类用于生成公钥和私钥对。密钥对生成器使用getInstance工厂方法构造。其参数为算法algorithm
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
- 调用keyPairGenerator的generateKeyPair()方法生成一个密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
- 调用keyPair的getPrivate()方法 开始生成私钥
PrivateKey privateKey = keyPair.getPrivate();
- 调用keyPair的getPublic()方法 开始生成公钥
PublicKey publicKey = keyPair.getPublic();
- 接着一一获取私钥公钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
byte[] publicKeyEncoded = publicKey.getEncoded();
- 最后再对公钥私钥进行Base64编码
String privateKeyString = Base64.encode(privateKeyEncoded);
String publicKeyString = Base64.encode(publicKeyEncoded);
- 把私钥公钥打印康康~~
System.out.println(privateKeyString);
System.out.println(publicKeyString);
2.怎么用私钥/公钥进行加密?
准备工作:
- 设置原文
String input = “aa”;
- 创建加密对象,参数为加密算法
Cipher cipher = Cipher.getInstance(algorithm);
- 初始化加密,第一个参数为加密模式,第二个参数为使用私钥加密
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
- 接着调用cipher的doFinal()方法去执行加密算法,其参数为原文的字节数组
byte[] bytes = cipher.doFinal(input.getBytes());
- 最后使用Base64编码输出就ok辣!!
System.out.println(Base64.encode(bytes));
让我们看看输出结果
3.我们试试使用私钥能不能解密呢?
- 解密也需要调用cipher的初始化方法init(),其第一个参数为解密模式,第二个参数为私钥
cipher.init(Cipher.DECRYPT_MODE,publicKey); - 对密文进行解密,不需要使用base64,因为原文不会乱码
byte[] bytes1 = cipher.doFinal(bytes);
System.out.println(new String(bytes1));
让我们看看输出结果~~
出错,所以只能使用私钥加密,公钥解密!
4.使用公钥解密!
- 解密也需要调用cipher的初始化方法init(),其第一个参数为解密模式,第二个参数为公钥
cipher.init(Cipher.DECRYPT_MODE,publicKey);
- 调用cipher的doFinal()方法来进行解密,其参数为密文的字节数组
byte[] bytes1 = cipher.doFinal(bytes);
System.out.println(new String(bytes1));
让我们来看看输出结果~~
嚯!原文出来啦!
同理,用公钥加密还用公钥解密还是会报错,所以只能使用一个加密,另一个解密哈!
5.保存私钥公钥
前面代码每次都会生成 加密和解密 ,咱们需要把加密和解密的方法全部到本地的根目录下面。
- 使用到FileUtils.writeStringToFile()将字符串写入文件,传入三个参数,第一个参数为new File(私钥文件的路径),第二个参数为私钥Base64编码,第三个参数为使用到U