SpringBoot集成數(shù)據(jù)傳輸加密

前言

近期在對開發(fā)框架安全策略方面進行升級優(yōu)化吧黄,提供一些通用場景的解決方案部服,本文針對前后端數(shù)據(jù)傳輸加密進行簡單的分享唆姐,處理流程設計如下圖所示拗慨,本加密方法對原有項目兼容性較好沽瞭,只需要更換封裝好的加密Ajax請求方法坛梁,后端統(tǒng)一攔截判斷是否需要解密即可

image

生成DESKey

生成的DES加密密鑰一定是8的整數(shù)倍的位數(shù)

function getRandomStr() {
    let str = ""
    let array = [
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z",
        "A",
        "B",
        "C",
        "D",
        "E",
        "F",
        "G",
        "H",
        "I",
        "J",
        "K",
        "L",
        "M",
        "N",
        "O",
        "P",
        "Q",
        "R",
        "S",
        "T",
        "U",
        "V",
        "W",
        "X",
        "Y",
        "Z",
    ];
    for (let i = 0; i < 8; i++) {
        str +=  array[Math.round(Math.random() * (array.length - 1))];
    }
    return str;
}

生成RSA密鑰對

RSA密鑰對有很多種格式憨闰,因為需要和前端算法庫互聯(lián)互通闸餐,這里選擇的是1024位刁赦,Padding方式為PKSC1

    public static Map<String, String> createKeysPKSC1(int keySize) {
        // map裝載公鑰和私鑰
        Map<String, String> keyPairMap = new HashMap<String, String>();
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            SecureRandom random = new SecureRandom();
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC");
            generator.initialize(keySize, random);
            KeyPair keyPair = generator.generateKeyPair();
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded()));
            String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
            keyPairMap.put("publicKey", publicKeyStr);
            keyPairMap.put("privateKey", privateKeyStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回map
        return keyPairMap;
    }

前端DES加密

引入crypto.js第三方庫

    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();
    }

前端RSA加密

引入jsencrypt,js第三方庫

    function encryptByRSA(data, publicKey) {
        var encryptor = new JSEncrypt()
        encryptor.setPublicKey(publicKey)
        return encryptor.encrypt(data);;
    }

后端RSA解密

    public static String decryptPKSC1(String data, String privateKeyStr) {
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
            RSAPrivateKey privateKey = getPrivateKeyPKSC1(privateKeyStr);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
        }
    }

后端DES解密

    public static String decrypt(String data, String key) throws IOException,
            Exception {
        if (data == null)
            return null;
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] buf = decoder.decodeBuffer(data);
        byte[] bt = decrypt(buf, key.getBytes("UTF-8"));
        return new String(bt, "UTF-8");
    }

后端自定義攔截器

public class XSSFilter implements Filter, Ordered {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        String contentType = request.getContentType();
        if (StringUtils.isNotBlank(contentType) && contentType.contains("application/json")) {
            XSSBodyRequestWrapper xssBodyRequestWrapper = new XSSBodyRequestWrapper((HttpServletRequest) request);
            chain.doFilter(xssBodyRequestWrapper, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public int getOrder() {
        return 9;
    }
}
public class XSSBodyRequestWrapper extends HttpServletRequestWrapper {

    private String body;

    public XSSBodyRequestWrapper(HttpServletRequest request) {
        super(request);
        try{
            body = XSSScriptUtil.handleString(CommonUtil.getBodyString(request));
            String encrypt = request.getHeader("encrypt");
            if (!StringUtil.isEmpty(encrypt)) {
                String privateKey = RSAEncryptUtil.getSystemDefaultRSAPrivateKey();
                String desEncryptStr = RSAEncryptUtil.decryptPKSC1(encrypt, privateKey);
                JSONObject obj = JSONObject.parseObject(body);
                String encryptParam = obj.getString("encryptParam");
                body = DESEncryptUtil.decrypt(encryptParam, desEncryptStr);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        final ByteArrayInputStream bais = new ByteArrayInputStream(body.getBytes(Charset.forName("UTF-8")));

        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bais.read();
            }

            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }

}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幻妓,一起剝皮案震驚了整個濱河市仔引,隨后出現(xiàn)的幾起案子鄙皇,更是在濱河造成了極大的恐慌先巴,老刑警劉巖其爵,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伸蚯,居然都是意外死亡摩渺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門剂邮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摇幻,“玉大人,你說我怎么就攤上這事挥萌〈乱觯” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵引瀑,是天一觀的道長狂芋。 經(jīng)常有香客問我,道長憨栽,這世上最難降的妖魔是什么帜矾? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮徒像,結果婚禮上黍特,老公的妹妹穿的比我還像新娘。我一直安慰自己锯蛀,他們只是感情好灭衷,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著旁涤,像睡著了一般翔曲。 火紅的嫁衣襯著肌膚如雪迫像。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天瞳遍,我揣著相機與錄音闻妓,去河邊找鬼。 笑死掠械,一個胖子當著我的面吹牛由缆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猾蒂,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼均唉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肚菠?” 一聲冷哼從身側響起舔箭,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚊逢,沒想到半個月后层扶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡烙荷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年镜会,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奢讨。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡稚叹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拿诸,到底是詐尸還是另有隱情扒袖,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布亩码,位于F島的核電站季率,受9級特大地震影響,放射性物質發(fā)生泄漏描沟。R本人自食惡果不足惜飒泻,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吏廉。 院中可真熱鬧泞遗,春花似錦、人聲如沸席覆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至聊倔,卻和暖如春晦毙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耙蔑。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工见妒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人甸陌。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓须揣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親邀层。 傳聞我的和親對象是個殘疾皇子返敬,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容