1、生成RSA非对称密钥
用了java.security自带的生成器
public static void main(String[] args) throws NoSuchAlgorithmException {
// 创建一个RSA密钥生成器
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
// 设置密钥长度
keyGen.initialize(2048);
// 生成密钥对
KeyPair keyPair = keyGen.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 将公钥和私钥转换为Base64编码的字符串
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());
// 打印公钥和私钥
System.out.println("Public Key: " + publicKeyString);
System.out.println("Private Key: " + privateKeyString);
}
2、测试一把
附加解密后端util
public class RsaUtil {
private static final String RSA_KEY_ALGORITHM = "RSA";
/**
* 公钥加密(用于数据加密)
*
* @param data 加密前的字符串
* @param publicKeyStr base64编码后的公钥
* @return base64编码后的字符串
* @throws Exception throw
*/
public static String encryptByPublicKey(String data, String publicKeyStr) throws Exception {
//Java原生base64解码
byte[] pubKey = Base64.getDecoder().decode(publicKeyStr);
//创建X509编码密钥规范
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
//返回转换指定算法的KeyFactory对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
//根据X509编码密钥规范产生公钥对象
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
//根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
//用公钥初始化此Cipher对象(加密模式)
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//对数据加密
byte[] encrypt = cipher.doFinal(data.getBytes());
//返回base64编码后的字符串
return Base64.getEncoder().encodeToString(encrypt);
}
/**
* 私钥解密(用于数据解密)
*
* @param data 解密前的字符串
* @param privateKeyStr 私钥
* @return 解密后的字符串
* @throws Exception throw
*/
public static String decryptByPrivateKey(String data, String privateKeyStr) throws Exception {
//Java原生base64解码
byte[] priKey = Base64.getDecoder().decode(privateKeyStr);
//创建PKCS8编码密钥规范
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
//返回转换指定算法的KeyFactory对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
//根据PKCS8编码密钥规范产生私钥对象
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//根据转换的名称获取密码对象Cipher(转换的名称:算法/工作模式/填充模式)
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
//用私钥初始化此Cipher对象(解密模式)
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//对数据解密
byte[] decrypt = cipher.doFinal(Base64.getDecoder().decode(data));
//返回字符串
return new String(decrypt);
}
}
3、修改auth模块配置
思路很清晰,原先用BcryptPasswordEncoder,那么继续用这个,只不过在这之前加上RSA解密。
3.1新建RsaBcryptPasswordEncoder
@Slf4j
public class RsaBcryptPasswordEncoder extends BCryptPasswordEncoder implements PasswordEncoder {
private static final String RSA_KEY_ALGORITHM = "RSA";
private static final String PRIVATE_KEY ="pri key";
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
try {
String decryptedPassword = decryptByPrivateKey(rawPassword.toString());
return super.matches(decryptedPassword, encodedPassword);
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
private static String decryptByPrivateKey(String data) throws Exception {
byte[] priKey = Base64.getDecoder().decode(PRIVATE_KEY);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decrypt = cipher.doFinal(Base64.getDecoder().decode(data));
return new String(decrypt);
}
}
需要在解密进行异常捕获,密文不合规之类的
3.2修改WebSecurityConfig
@Bean
public PasswordEncoder passwordEncoder() {
return new RsaBcryptPasswordEncoder();
}
注意:
在 oauth认证服务器配置
configure(ClientDetailsServiceConfigurer clients)
方法中,也有passwordEncoder
4、测试
before
now
refresh
成功