系统登录的时候的密码如何做到以加密的形式进行登录【java.security包下的api】工具类。

发布时间:2024年01月24日
/*
     * @description: 将普通的publicKey转化得到一个RSAPublicKey
     * @author: zkw
     * @date: 2024/1/24 16:17
     * @param: publicKey 普通的publicKey
     * @return: RSAPublicKey 得到一个新的RSAPublicKey
     **/
    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通过X509编码的Key指令获得公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }


    /*
     * @description: 将明文字符串利用RSAPublicKey公钥加密成一个密文
     * @author: zkw
     * @date: 2024/1/24 16:24
     * @param: data 待加密的明文字符串
     * @param: publicKey RSAPublicKey
     * @return: String 密文字符串
     **/
    public static String publicEncrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
        } catch (Exception e) {
            throw new RuntimeException("error......", e);
        }
    }

    /*
     * @description: 将普通的privateKey转化得到一个RSAPrivateKey
     * @author: zkw
     * @date: 2024/1/24 16:41
     * @param: privateKey 普通的privateKey
     * @return: RSAPrivateKey 得到一个新的RSAPrivateKey
     **/
    public static RSAPrivateKey getPrivateKey(String privateKey) {
        // 通过PKCS#8编码的Key指令获得私钥对象
        KeyFactory keyFactory;
        RSAPrivateKey rsaPrivateKey;
        try {
            keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
            rsaPrivateKey = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        } catch (Exception e) {
            throw new ServiceException(Codes.PASSWORD_DECRYPTION_EXCEPTION);
        }
        return rsaPrivateKey;
    }

    /*
     * @description: 将密文使用私钥进行解密 解密出明文
     * @author: zkw
     * @date: 2024/1/24 16:42
     * @param: cipherText 密文
     * @param: privateKey RSAPrivateKey私钥
     * @return: String 明文
     **/
    private static String privateDecrypt(String cipherText, RSAPrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(cipherText), privateKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
            throw new ServiceException(Codes.PASSWORD_DECRYPTION_EXCEPTION);
        }
    }

rsaSplitCodec()方法

private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
        int maxBlock = 0;
        if (opmode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try {
            while (datas.length > offSet) {
                if (datas.length - offSet > maxBlock) {
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                } else {
                    buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        byte[] resultDatas = out.toByteArray();
        IOUtils.closeQuietly(out);
        return resultDatas;
    }

四个方法我直接贴出来,两个方法是关于公钥的,两个方法是关于私钥的

我们写一个测试方法,看看明文加密之后的密文,在经过解密后的明文是否一致。

public static void method(String clearPassword) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //【前端通过js】 1、生成一个普通的PublicKey,一般这里前端会生成,同时也需要转化成一个RSAPublicKey,然后再对输入的明文字符串进行加密成一个密文,这里我不知道前端怎么写,我们就以后端的思路去代替
        KeyPair keyPair = KeyPairGenerator.getInstance(RSA_ALGORITHM).generateKeyPair();
        String publicKey = new String(java.util.Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
        RSAPublicKey rsaPublicKey = getPublicKey(publicKey);
        String cipherText = publicEncrypt(clearPassword, rsaPublicKey);//密文字符串

        //【后端通过代码】2、生成一个普通的PrivateKey
        String privateKey = new String(java.util.Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));

//        //3、将普通的privateKey转化为一个新的RSAPrivateKey
        RSAPrivateKey rsaPrivateKey = getPrivateKey(privateKey);
//
//        //4、对前端传过来的密文利用RSA私钥进行解密
        String res = privateDecrypt(cipherText, rsaPrivateKey);
        System.out.println("加密之前的明文:" + clearPassword);
        System.out.println("加密之后的密文:" + cipherText);
        System.out.println("================================");
        System.out.println("解密之后的明文:" + res);
    }

运行结果:

所以以后在登录的时候呢,前端会对界面输入的明文密码进行公钥加密成密文密码,然后再传给后端,后端就会利用私钥进行解密解密出明文密码,然后与数据库的进行比较。

总结:

使用java.security包下的api进行密码的加密传输(公加私解)

给大家画个流程图:

最后:

如果大家觉得这篇文章对大家有所帮助的话,希望能给个免费的赞赞,也祝各位码农在未来的IT道路上能越走越远。谢谢。

文章来源:https://blog.csdn.net/weixin_44826783/article/details/135828271
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。