0
点赞
收藏
分享

微信扫一扫

前后端DES加解密及Wrong key size错误处理

_LEON_ 2022-04-02 阅读 211
java

前后端DES加解密及Wrong key size错误处理

前端使用 CryptoJS 进行DES加密,后端Java进行解密。

前端

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

function decryptByDES(ciphertext, key) {        
    var keyHex = CryptoJS.enc.Utf8.parse(key);      
    var decrypted = CryptoJS.DES.decrypt({
        ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
    }, keyHex, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });

    return decrypted.toString(CryptoJS.enc.Utf8);
}

Java

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

@Slf4j
public class DesUtil {

    private static String CHARSETNAME="UTF-8";
    private static String ALGORITHM="DES";

    /**
     * 加密数据
     * @param data 待加密数据
     * @param key  密钥
     * @return 加密后的数据
     */
    public static String getEncryptString(String data, String key) {
        try {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(getKeyBytes(key));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            SecretKey securekey = keyFactory.generateSecret(desKey);
            //Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
            byte[] temp = org.apache.commons.codec.binary.Base64.encodeBase64(cipher.doFinal(data.getBytes()));
            return IOUtils.toString(temp, CHARSETNAME);
        } catch (Exception e) {
            log.info("加密异常: {}", ExceptionUtils.getFullStackTrace(e));
            throw new RuntimeException(e);
        }
    }

    private static byte[] getKeyBytes(String key) throws UnsupportedEncodingException {
        byte[] keyBytes = key.getBytes(CHARSETNAME);
        if (keyBytes.length < 8) {
            byte[] bytes = new byte[8];
            System.arraycopy(keyBytes, 0, bytes, 0, keyBytes.length);
            keyBytes = bytes;
        }
        return keyBytes;
    }

    /**
     * 解密数据
     * @param data 待解密数据
     * @param key  密钥
     * @return 解密后的数据
     */
    public static String getDecryptString(String data, String key) {
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(getKeyBytes(key));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
            // 将DESKeySpec对象转换成SecretKey对象
            SecretKey securekey = keyFactory.generateSecret(desKey);
            // Cipher对象实际完成解密操作
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
            return IOUtils.toString(cipher.doFinal(Base64.decodeBase64(data)),CHARSETNAME);
        } catch (Exception e) {
            log.info("解密异常: {}", ExceptionUtils.getFullStackTrace(e));
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        System.out.println(getEncryptString("12321", "vip"));
    }

}

当keyBytes数组的长度小于8时,上面代码块中的私有方法getKeyBytes()对其进行了长度补齐。这是因为DESKeySpec的构造方法会只取keyBytes数组的前8位:

    public DESKeySpec(byte[] var1) throws InvalidKeyException {
        this(var1, 0);
    }

    public DESKeySpec(byte[] var1, int var2) throws InvalidKeyException {
        if (var1.length - var2 < 8) {
            throw new InvalidKeyException("Wrong key size");
        } else {
            this.key = new byte[8];
            System.arraycopy(var1, var2, this.key, 0, 8);
        }
    }

可以看出,当key.getBytes()的长度大于等于8时只取前8位;当其长度小于8时,会抛异常:

Caused by: java.security.InvalidKeyException: Wrong key size
	at javax.crypto.spec.DESKeySpec.<init>(DESKeySpec.java:155)
	at javax.crypto.spec.DESKeySpec.<init>(DESKeySpec.java:131)
	at com.prild.common.util.DesUtil.getEncryptString(DesUtil.java:38)
	... 1 more

举报

相关推荐

0 条评论