Java 实现 RSA 非对称加密算法
- 前言
- 一、非对称加密算法简介
- 二、RSA 加解密代码实例
- 1.生成 RSA 密钥
- 2.RSA 加解密
- 3.测试代码
- 三、RSA 签名验签代码实例
- 2.RSA 签名验签
- 3.测试代码
前言
文章字数比较多,可直接查看代码:源码地址,文中描述有误的地方欢迎各位大神指导。
一、非对称加密算法简介
非对称加密算法又称现代加密算法,是计算机通信安全的基石,保证了加密数据不会被破解。与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密(privatekey),因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。公钥和私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。常见算法:RSA、ECC。
加解密和签名验签区别:
既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。
注意: 公钥加密、私钥解密,私钥签名、公钥验签。
二、RSA 加解密代码实例
1.生成 RSA 密钥
代码如下:
public static KeyPair generateKeyPair(int keysize) {
try {
// 获取指定算法的密钥对生成器(RSA)
KeyPairGenerator generator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
// 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源)
generator.initialize(keysize);
// 随机生成一对密钥(包含公钥和私钥)
return generator.generateKeyPair();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
2.RSA 加解密
代码如下:
/**
* RSA 加密
*
* @param publicKeyBytes 公钥
* @param plain 原文
* @return 密文
*/
public static byte[] rsaEncrypt(byte[] publicKeyBytes, byte[] plain) {
try {
// RSA
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(publicKeyBytes);
PublicKey publicKey = keyFactory.generatePublic(pubX509);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(plain);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 解密
*
* @param privateKeyBytes 私钥
* @param encrypted 密文
* @return 原文
*/
public static byte[] rsaDecrypt(byte[] privateKeyBytes, byte[] encrypted) {
try {
// RSA
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encrypted);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
3.测试代码
代码如下:
public static void main(String[] args) {
String plain = "123";
KeyPair keyPair = generateKeyPair(2048);
byte[] encrypt = rsaEncrypt(keyPair.getPublic().getEncoded(), plain.getBytes());
byte[] decrypt = rsaDecrypt(keyPair.getPrivate().getEncoded(), encrypt);
System.err.println(new String(decrypt));
}
三、RSA 签名验签代码实例
2.RSA 签名验签
代码如下:
/**
* rsaSign.
*
* @param privateKeyBytes 私钥
* @param plain 明文
* @return String 签名
*/
public static String rsaSign(byte[] privateKeyBytes, String plain) throws Exception {
final KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
final PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
final PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
final Signature signature = Signature.getInstance(RSA_SIGN_ALGORITHM);
signature.initSign(privateKey);
signature.update(plain.getBytes(StandardCharsets.UTF_8));
final byte[] signed = signature.sign();
return new String(Base64.encodeBase64URLSafe(signed), StandardCharsets.UTF_8);
}
/**
* rsaVerify.
*
* @param publicKeyBytes 公钥
* @param plain 原文
* @param sign 签名
* @return boolean
*/
public static boolean rsaVerify(byte[] publicKeyBytes, String plain, String sign)
throws Exception {
final KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
final X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(publicKeyBytes);
final PublicKey publicKey = keyFactory.generatePublic(pubX509);
final Signature signature = Signature.getInstance(RSA_SIGN_ALGORITHM);
signature.initVerify(publicKey);
signature.update(plain.getBytes(StandardCharsets.UTF_8));
return signature.verify(Base64.decodeBase64URLSafe(sign));
}
3.测试代码
代码如下:
public static void main(String[] args) throws Exception {
final String sign = rsaSign(privateKey, plain);
System.err.println(sign);
final boolean verify = rsaVerify(publicKey, plain, sign);
System.err.println(verify);
}