鍍金池/ 問答/Java  HTML/ java端采用DES/CBC/PKCS5Padding 加密,js解密不了。go

java端采用DES/CBC/PKCS5Padding 加密,js解密不了。google搜了好多方法沒能解決

發(fā)送一段java 的DES加密和解密

    /**
     * 加密
     */
             private static byte[] iv = {1, 2, 3, 4, 5, 6, 7, 8};
    public static String encryptDES(String encryptString, String encryptKey) {
    try {
        IvParameterSpec zeroIv = new IvParameterSpec(iv);
        SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
        byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
        return Base64.encode(encryptedData);
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }

    }

    /**
     * 解密
     */
    public static String decryptDES(String decryptString, String decryptKey) {
    try {
        byte[] byteMi = Base64.decode(decryptString);
        IvParameterSpec zeroIv = new IvParameterSpec(iv);
        SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
        byte decryptedData[] = cipher.doFinal(byteMi);

        return new String(decryptedData);
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }

    }

現(xiàn)在的javascript解密庫是用crypto-js

但是沒找到能支持DES/CBC/PKCS5Padding的算法。怎么辦

回答
編輯回答
夕顏

js如果有DES/CBC的話,Padding可以自己實(shí)現(xiàn)哈。

2018年6月25日 03:39
編輯回答
卟乖

可以請(qǐng)教下作者最后是怎么解決的嗎,我的Java端代碼和你一樣?

2018年7月4日 07:23
編輯回答
舊酒館

看了一下,Crypto-js是支持des-cbc加密的。
Pkcs5Pkcs7在塊大小為8時(shí)特殊情況,本質(zhì)上是一樣的。Crypto-js默認(rèn)padding是Pkcs7,可以直接使用。
給個(gè)例子:

#加密,key: testtest iv:abcdefgh
echo message | openssl enc -a -des-cbc -K 7465737474657374 -iv 6162636465666768
#輸出:kEiztbNAuirF25k0FAcylA==
//解密
var key = CryptoJS.enc.Utf8.parse('testtest');
var iv = CryptoJS.enc.Utf8.parse('abcdefgh');
CryptoJS.DES.decrypt("kEiztbNAuirF25k0FAcylA==", key, {
    iv : iv,
    mode: CryptoJS.mode.CBC,    //可省略
    padding: CryptoJS.pad.Pkcs7 //可省略
}).toString(CryptoJS.enc.Utf8);
//輸出:message

回答你評(píng)論中的問題。
首先,你這里des加密出來的結(jié)果,是用base64編碼表示的,base64編碼里,合法字符范圍是[A-Za-z0-9+=/],空格根本就不是合法字符,是不應(yīng)該出現(xiàn)的。所以不是Cryptojs的問題。

那么到底是哪里出了問題呢,首先來看看你給的第一端密文:

echo DrXWLKRt5byd6XcRGCk66G3BEQ0V7KA9gVZl0kaj/2WK9T+wWarVG7CUtN2H33VDZgVZ3DEuG4O3ja179eyPe6+//9I8w/JxQ2lvLNV4+PaD+in2ltgf3A== | openssl enc -d -a -des-cbc -K 55494a443839486b -iv 3132333435363738 | xxd
#輸出
0000000: 5844 4440 0a1f 1f02 3030 3032 3135 3037  XDD@....00021507
0000010: 2e76 6f64 2e6d 7971 636c 6f75 642e 636f  .vod.myqcloud.co
0000020: 6d2f 3230 3030 3231 3530 375f 6638 6131  m/200021507_f8a1
0000030: 3733 6134 6131 3837 3131 6536 3934 3564  73a4a18711e6945d
0000040: 3739 3730 3130 3738 6434 3862 2e66 3230  79701078d48b.f20
0000050: 2e6d 7034                                .mp4

可以看到XXD@后面出現(xiàn)了0a1f1f02這一段,在utf-8編碼下,0x0a被解釋為換行,其他的被解釋為控制字符無法顯示。解密過程正常,輸出也正常,說明解密出來的就是原文(如果密文有問題,應(yīng)該是報(bào)錯(cuò),一點(diǎn)都解密不出來),至于為什么會(huì)包含這些奇怪的字符,就要問問你們后端怎么弄出來的這段了,是不是把非utf-8編碼的字符強(qiáng)行連接在一起了。

那么這個(gè)空格又是如何出現(xiàn)的呢?我們把解密后的密文重新加密回去:

echo DrXWLKRt5byd6XcRGCk66G3BEQ0V7KA9gVZl0kaj/2WK9T+wWarVG7CUtN2H33VDZgVZ3DEuG4O3ja179eyPe6+//9I8w/JxQ2lvLNV4+PaD+in2ltgf3A== | openssl enc -d -a -des-cbc -K 55494a443839486b -iv 3132333435363738 | openssl enc -a -des-cbc -K 55494a443839486b -iv 3132333435363738
#輸出
DrXWLKRt5byd6XcRGCk66G3BEQ0V7KA9gVZl0kaj/2WK9T+wWarVG7CUtN2H33VD
ZgVZ3DEuG4O3ja179eyPe6+//9I8w/JxQ2lvLNV4+PaD+in2ltgf3A==

注意到這里出現(xiàn)了換行,這時(shí)因?yàn)?code>openssl會(huì)調(diào)用base64命令進(jìn)行編碼,為了兼容某些舊程序,會(huì)自動(dòng)進(jìn)行換行。之后在網(wǎng)絡(luò)傳輸過程中或者你們后端做了替換或者你們的復(fù)制粘貼過程中,這個(gè)換行符變成了空格。從你給的第二段密文也可以看出,是同樣的60個(gè)字符一個(gè)空格。這里的換行寬度和java的不一樣,但是道理是一樣的。

所以,解決方案就是,在前端或者后端移除空白字符。

Base64.encodeBase64String(text, Base64.NO_WRAP)
encrypted_msg.replace(/\s/g, '');
2017年8月14日 09:26