Spring Security Oauth2密码模式 登录密码RSA加密

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

成功

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值