For investors
股价:
5.36 美元 %For investors
股价:
5.36 美元 %认真做教育 专心促就业
与对称加密算法不同,非对称加密算法需要两个密钥:公钥和私钥。公钥与私钥是一对,如果使用公钥对数据进行加密,那么只能有对应的私钥才能解密;如果使用私钥进行加密,那么只能用对应的公钥才能解密。因为加密和解密是使用的两个不同的密钥。
常见的非对称加密算法:
RSA:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
ECC:椭圆加密算法
特点:
加密和解密使用不同的密钥
如果使用私钥加密, 只能使用公钥解密
如果使用公钥加密, 只能使用私钥解密
处理数据的速度较慢, 因为安全级别高
demo代码:
package encryptAndDecrypt;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.commons.io.FileUtils;
import javax.crypto.Cipher;
import java.io.File;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* @className: RsaDemo
* @description: 非对称加密之RSA
* @author: charon
* @create: 2021-02-25 11:05
*/
public class RsaDemo {
public static void main(String[] args) throws Exception {
String algorithm = "RSA";
// 生成密钥对并保存在本地文件中,这样就可以不用每次都重新申请了。
// 也有系统为了更安全,每次都会新生成密钥,然后将公钥返回给客户端,私钥存入redis中,解密的时候从根据session从redis中取对应的私钥
generateKeyToFile(algorithm, "pub.txt", "pri.txt");
// 获取公钥
PublicKey publicKey = getPublicKey("pub.txt", "RSA");
// 获取私钥
PrivateKey privateKey = getPrivateKey("pri.txt", "RSA");
// 原文
String input = "charon周";
// 加密
String encryptRSA = encryptRSA(input,algorithm,publicKey);
System.out.println("密文:"+ encryptRSA);
// 解密
String decryptRSA = decryptRSA(encryptRSA,algorithm,privateKey);
System.out.println("原文:"+ decryptRSA);
}
/**
* 解密
* @param encryptRSA 密文
* @param algorithm 算法
* @param privateKey 私钥
* @return 原文
*/
private static String decryptRSA(String encryptRSA, String algorithm, PrivateKey privateKey) throws Exception{
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.DECRYPT_MODE,privateKey);
byte[] bytes = cipher.doFinal(Base64.decode(encryptRSA));
return new String(bytes);
}
/**
* 加密
* @param input 原文
* @param algorithm 加密算法
* @param publicKey 公钥
* @return 密文
*/
private static String encryptRSA(String input, String algorithm, PublicKey publicKey) throws Exception{
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
byte[] bytes = cipher.doFinal(input.getBytes());
return Base64.encode(bytes);
}
/**
* 获取私钥
* @param privateKeyPath 私钥文件路径
* @param algorithm 算法
* @return 私钥
*/
public static PrivateKey getPrivateKey(String privateKeyPath, String algorithm) throws Exception {
// 读取文件内容
String strPrivateKey = FileUtils.readFileToString(new File(privateKeyPath), Charset.defaultCharset());
// 创建key工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 创建私钥规则
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decode(strPrivateKey));
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
}
/**
* 获取公钥
* @param publicKeyPath 公钥文件路径
* @param algorithm 算法
* @return 公钥
*/
public static PublicKey getPublicKey(String publicKeyPath, String algorithm) throws Exception{
// 读取文件内容
String strPublicKey = FileUtils.readFileToString(new File(publicKeyPath), Charset.defaultCharset());
// 创建key工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 创建公钥规则
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(strPublicKey));
return keyFactory.generatePublic(x509EncodedKeySpec);
}
/**
* 生成密钥对,并放入本地文件
* @param algorithm
* @param publicKeyPath
* @param privateKeyPath
*/
private static void generateKeyToFile(String algorithm, String publicKeyPath, String privateKeyPath) throws Exception{
// 生成实例
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私钥
PrivateKey privateKey = keyPair.getPrivate();
// 获取私钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
// 生成公钥
PublicKey publicKey = keyPair.getPublic();
// 获取公钥的字节数组
byte[] publicKeyEncoded = publicKey.getEncoded();
// base64编码
String strPrivateKeyEncoded = Base64.encode(privateKeyEncoded);
String strPublicKeyEncoded = Base64.encode(publicKeyEncoded);
// 存到文件中
FileUtils.write(new File(privateKeyPath),strPrivateKeyEncoded, Charset.forName("UTF-8"));
FileUtils.write(new File(publicKeyPath),strPublicKeyEncoded, Charset.forName("UTF-8"));
}
}