背景
在對(duì)接三方接口或?qū)崿F(xiàn)開放平臺(tái)操作時(shí)需要對(duì)接口提交參數(shù)通過RSA公鑰進(jìn)行加密,在獲取到請(qǐng)求數(shù)據(jù)后需要使用RSA私鑰對(duì)數(shù)據(jù)進(jìn)行解密操作。
RSA生成工具
幾種方式
1.自定義RsaUtil工具類
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA加解密工具
*
* @author sdevil507
* created on 2021/5/27
*/
@Slf4j
public class RsaUtil {
/**
* 算法
*/
private static final String KEY_ALGORITHM = "RSA";
/**
* 類型
*/
public static final String RSA_TYPE = "RSA/ECB/PKCS1Padding";
/**
* 簽名算法
*/
public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
/**
* 獲取轉(zhuǎn)換后的公鑰
*
* @param publicKey 公鑰字符串
* @return 轉(zhuǎn)換后的公鑰
*/
private static PublicKey getPublicKey(String publicKey) {
try {
byte[] byteKey = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePublic(x509EncodedKeySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 獲取轉(zhuǎn)換后的私鑰
*
* @param privateKey 私鑰字符串
* @return 轉(zhuǎn)換后的私鑰
*/
private static PrivateKey getPrivateKey(String privateKey) {
try {
byte[] byteKey = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 私鑰簽名
*
* @param privateKey 私鑰
* @param plainText 明文
* @return 簽名字符串
*/
public static String sign(String privateKey, String plainText) {
String signStr = null;
byte[] signeBytes;
try {
log.info("簽名前明文:{}", plainText);
PrivateKey key = getPrivateKey(privateKey);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(key);
signature.update(plainText.getBytes());
signeBytes = signature.sign();
signStr = Base64.encodeBase64String(signeBytes);
log.info("簽名后密文:{}", signStr);
} catch (Exception e) {
e.printStackTrace();
}
return signStr;
}
/**
* 公鑰驗(yàn)簽
*
* @param plainText 待驗(yàn)簽明文
* @param signStr 簽名密文
* @return true/false
*/
public static boolean verifySign(String publicKey, String plainText, String signStr) {
boolean verifySignSuccess = false;
try {
PublicKey key = getPublicKey(publicKey);
Signature verifySign = Signature.getInstance(SIGNATURE_ALGORITHM);
verifySign.initVerify(key);
verifySign.update(plainText.getBytes());
verifySignSuccess = verifySign.verify(Base64.decodeBase64(signStr));
log.info("公鑰驗(yàn)簽結(jié)果:{}", verifySignSuccess);
} catch (Exception e) {
e.printStackTrace();
}
return verifySignSuccess;
}
/**
* 明文加密
*
* @param publicKey 公鑰
* @param plainText 明文
* @return 密文
*/
public static String encrypt(String publicKey, String plainText) {
String encryptedBase64 = "";
try {
Key key = getPublicKey(publicKey);
final Cipher cipher = Cipher.getInstance(RSA_TYPE);
cipher.init(Cipher.ENCRYPT_MODE, key);
// 轉(zhuǎn)換
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
encryptedBase64 = Base64.encodeBase64String(encryptedBytes);
} catch (Exception e) {
e.printStackTrace();
}
return encryptedBase64;
}
/**
* 密文解密
*
* @param privateKey 秘鑰
* @param encryptedBase64 密文
* @return 明文
*/
public static String decrypt(String privateKey, String encryptedBase64) {
String decryptedString = "";
try {
Key key = getPrivateKey(privateKey);
final Cipher cipher = Cipher.getInstance(RSA_TYPE);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedBytes = Base64.decodeBase64(encryptedBase64);
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
decryptedString = new String(decryptedBytes);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedString;
}
}
2.使用hutool工具類中的RSA工具類
引入hutool類庫
<dependency>
<groupId>com.xiaoleilu</groupId>
<artifactId>hutool-all</artifactId>
<version>x.x.x</version>
</dependency>
測試代碼
@Test
public void hutoolRsa() {
// 公鑰
String publicKey = "xxx";
// 私鑰
String privateKey = "xxx";
// 明文內(nèi)容
String content = "test123456helloWorld";
// 使用公鑰,私鑰初始化RSA對(duì)象
RSA rsa = new RSA(privateKey, publicKey);
// 公鑰加密
String encryptStr = rsa.encryptBase64(content, KeyType.PublicKey);
System.out.println(encryptStr);
// 私鑰解密
String plainText = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
System.out.println(plainText);
}
可以繼續(xù)封裝實(shí)現(xiàn)自己的簽名/驗(yàn)簽方法