package com.yanzuoguang.util.helper;

import com.yanzuoguang.util.contants.SystemContants;
import com.yanzuoguang.util.exception.CodeException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.SecureRandom;

/**
 * DES加密
 *
 * @author 颜佐光
 */
public class DesHelper {

    private static final String ALGORITHM_DES = "des";

    /**
     * DES加密
     *
     * @param key     秘钥key
     * @param content 待加密内容
     * @return byte[]
     */
    public static String DESEncrypt(final String key, final String content) {
        try {
            byte[] from = content.getBytes(SystemContants.UTF8);
            byte[] to = processCipher(from, getSecretKey(key), Cipher.ENCRYPT_MODE, ALGORITHM_DES);
            return RsaHelper.encodeBase64(to);
        } catch (UnsupportedEncodingException ex) {
            throw new CodeException("加密失败:" + ex.getMessage(), ex);
        }
    }

    /**
     * DES解密
     *
     * @param key            秘钥key
     * @param encoderContent 已加密内容
     * @return byte[]
     */
    public static String DESDecrypt(final String key, final String encoderContent) {
        try {
            byte[] from = RsaHelper.decodeBase64(encoderContent);
            byte[] to = processCipher(from, getSecretKey(key), Cipher.DECRYPT_MODE, ALGORITHM_DES);
            return new String(to, SystemContants.UTF8);
        } catch (UnsupportedEncodingException ex) {
            throw new CodeException("解密失败:" + ex.getMessage(), ex);
        }
    }

    /**
     * 根据key生成秘钥
     *
     * @param key 给定key,要求key至少长度为8个字符
     * @return SecretKey
     */
    public static SecretKey getSecretKey(final String key) {
        try {
            DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
            SecretKeyFactory instance = SecretKeyFactory.getInstance(ALGORITHM_DES);
            SecretKey secretKey = instance.generateSecret(desKeySpec);
            return secretKey;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 加密/解密处理
     *
     * @param processData 待处理的数据
     * @param key         提供的密钥
     * @param opsMode     工作模式
     * @param algorithm   使用的算法
     * @return byte[]
     */
    private static byte[] processCipher(final byte[] processData, final Key key,
                                        final int opsMode, final String algorithm) {
        try {
            SecureRandom secureRandom = new SecureRandom();
            Cipher cipher = Cipher.getInstance(algorithm);
            //初始化
            cipher.init(opsMode, key, secureRandom);
            return cipher.doFinal(processData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}