• 前端登陆加密和后端解密


    实现了前端对数据进行加密后传输,后端对加密的数据进行解密,然后去数据库对比。因为要解密所以采用对称加密算法。不讨论哪个对称加密算法好,这里采用DES,在实现的过程中发现要找一个js版本的DES加密,并且java能DES解密的还真不容易。

    加解密思路
    由于是对称加密,所以加解密的密钥就非常重要。这里采用uuid作为加解密的密钥,而且每次请求页面时生成的uuid都不一样,保证每次的密钥都不知道是什么。

    看后端生成密钥的过程

    @RequestMapping(value = "/login.html", method = RequestMethod.GET)
    public String login(Model model, HttpSession session) {
        logger.info("登录页面");
        session.setAttribute(SessionParam.LOGIN_KEY, UUIDGenerator.getUUID());
        model.addAttribute("title", "用户登录");
        return "admin/login";
    }

    在进入login页面的时候将生成的uuid放进session中。

    // 密码进行两次md5
    var passwordMd5 = CryptoJS.MD5(password);
    passwordMd5 = CryptoJS.MD5(passwordMd5);
    // console.info("md5:" + passwordMd5);
    $(this).val("正在登录...");
    $(this).attr("disabled", true);
    // 用户名des加密
    username = encryptByDES(username, key);
    // 填充表单并提交表单
    $("#postUsername").val(username);
    $('#postPassword').val(passwordMd5);
    $('#postForm').submit();

    // DES加密
    function encryptByDES(message, key) {
        var keyHex = CryptoJS.enc.Utf8.parse(key);
        var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
            mode : CryptoJS.mode.ECB,
            padding : CryptoJS.pad.Pkcs7
        });
        return encrypted.toString();
    }

    当表单准备好之后,对密码进行两次MD5,用户名则采用DES加密,加密的密钥就是session中保存的那个uuid

    后端再对传过来的用户名进行解密,因为数据库本来就存的是密码的两次MD5的值,所以只对用户名进行加密,因为即使密码被获取到,也不知道是什么。

    后端过程

    // 得到加密密钥
    logger.info("-----原始数据:username:{} password:{}-----", username, password);
    String key = session.getAttribute(SessionParam.LOGIN_KEY) + "";
    logger.info("-----加解密key:{}-----", key);
    try {
        username = DESUtil.decryption(username, key);
    } catch (Exception e) {
        logger.info("-----解密出错:{}-----", e.getMessage());
    }
    logger.info("解密后:username:{} password:{}", username, password);

    截图



    JAVA DES
    分享一个js前端加密,java后端加密的小程序

    package com.jrbac.util;

    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.spec.InvalidKeySpecException;

    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;

    /**
     * DES加解密工具类
     *
     * @author 程高伟
     *
     * @date 2016年6月15日 上午10:02:50
     */
    public class DESUtil {
        private static final String DES_ALGORITHM = "DES";

        /**
         * DES加密
         *
         * @param plainData
         *            原始字符串
         * @param secretKey
         *            加密密钥
         * @return 加密后的字符串
         * @throws Exception
         */
        public static String encryption(String plainData, String secretKey) throws Exception {

            Cipher cipher = null;
            try {
                cipher = Cipher.getInstance(DES_ALGORITHM);
                cipher.init(Cipher.ENCRYPT_MODE, generateKey(secretKey));

            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {

            }

            try {
                // 为了防止解密时报javax.crypto.IllegalBlockSizeException: Input length must
                // be multiple of 8 when decrypting with padded cipher异常,
                // 不能把加密后的字节数组直接转换成字符串
                byte[] buf = cipher.doFinal(plainData.getBytes());

                return Base64Utils.encode(buf);

            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
                throw new Exception("IllegalBlockSizeException", e);
            } catch (BadPaddingException e) {
                e.printStackTrace();
                throw new Exception("BadPaddingException", e);
            }

        }

        /**
         * DES解密
         *
         * @param secretData
         *            密码字符串
         * @param secretKey
         *            解密密钥
         * @return 原始字符串
         * @throws Exception
         */
        public static String decryption(String secretData, String secretKey) throws Exception {

            Cipher cipher = null;
            try {
                cipher = Cipher.getInstance(DES_ALGORITHM);
                cipher.init(Cipher.DECRYPT_MODE, generateKey(secretKey));

            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                throw new Exception("NoSuchAlgorithmException", e);
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
                throw new Exception("NoSuchPaddingException", e);
            } catch (InvalidKeyException e) {
                e.printStackTrace();
                throw new Exception("InvalidKeyException", e);

            }

            try {

                byte[] buf = cipher.doFinal(Base64Utils.decode(secretData.toCharArray()));

                return new String(buf);

            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
                throw new Exception("IllegalBlockSizeException", e);
            } catch (BadPaddingException e) {
                e.printStackTrace();
                throw new Exception("BadPaddingException", e);
            }
        }

        /**
         * 获得秘密密钥
         *
         * @param secretKey
         * @return
         * @throws NoSuchAlgorithmException
         * @throws InvalidKeySpecException
         * @throws InvalidKeyException
         */
        private static SecretKey generateKey(String secretKey)
                throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
            DESKeySpec keySpec = new DESKeySpec(secretKey.getBytes());
            keyFactory.generateSecret(keySpec);
            return keyFactory.generateSecret(keySpec);
        }

        static private class Base64Utils {

            static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
                    .toCharArray();
            static private byte[] codes = new byte[256];

            static {
                for (int i = 0; i < 256; i++)
                    codes[i] = -1;
                for (int i = 'A'; i <= 'Z'; i++)
                    codes[i] = (byte) (i - 'A');
                for (int i = 'a'; i <= 'z'; i++)
                    codes[i] = (byte) (26 + i - 'a');
                for (int i = '0'; i <= '9'; i++)
                    codes[i] = (byte) (52 + i - '0');
                codes['+'] = 62;
                codes['/'] = 63;
            }

            /**
             * 将原始数据编码为base64编码
             */
            static private String encode(byte[] data) {
                char[] out = new char[((data.length + 2) / 3) * 4];
                for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
                    boolean quad = false;
                    boolean trip = false;
                    int val = (0xFF & (int) data[i]);
                    val <<= 8;
                    if ((i + 1) < data.length) {
                        val |= (0xFF & (int) data[i + 1]);
                        trip = true;
                    }
                    val <<= 8;
                    if ((i + 2) < data.length) {
                        val |= (0xFF & (int) data[i + 2]);
                        quad = true;
                    }
                    out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
                    val >>= 6;
                    out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
                    val >>= 6;
                    out[index + 1] = alphabet[val & 0x3F];
                    val >>= 6;
                    out[index + 0] = alphabet[val & 0x3F];
                }

                return new String(out);
            }

            /**
             * 将base64编码的数据解码成原始数据
             */
            static private byte[] decode(char[] data) {
                int len = ((data.length + 3) / 4) * 3;
                if (data.length > 0 && data[data.length - 1] == '=')
                    --len;
                if (data.length > 1 && data[data.length - 2] == '=')
                    --len;
                byte[] out = new byte[len];
                int shift = 0;
                int accum = 0;
                int index = 0;
                for (int ix = 0; ix < data.length; ix++) {
                    int value = codes[data[ix] & 0xFF];
                    if (value >= 0) {
                        accum <<= 6;
                        shift += 6;
                        accum |= value;
                        if (shift >= 8) {
                            shift -= 8;
                            out[index++] = (byte) ((accum >> shift) & 0xff);
                        }
                    }
                }
                if (index != out.length)
                    throw new Error("miscalculated data length!");
                return out;
            }
        }
    }

    CryptoJS DES和MD5

  • 相关阅读:
    Intent.ACTION_TIME_TICK 广播
    Android ContentObserver
    android:duplicateParentState属性解释
    Android CursorAdapter
    android AndroidManifest.xml 多个android.intent.action.MAIN (
    PreferenceActivity详解
    WORD和WPS中英文混合的内容间距离很大怎么办?
    Android 屏幕适配
    OC第四课
    PL/SQL联系oracle成功可以sql解决的办法是检查表的名称无法显示
  • 原文地址:https://www.cnblogs.com/airen123/p/10036969.html
Copyright © 2020-2023  润新知