DES解密解密文件和字符串及报错解决

使用Base64(加密字符串)

import cn.hzjykj.util.Base64; 
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.Key;
import java.security.Security;
private static byte[] iv = new byte[8];
    private static String _KEY = "Jinyi-hz";
    public static String encryptDES(String encryptString) throws Exception{
        IvParameterSpec zoreIv = new IvParameterSpec(iv);
        SecretKeySpec key = new SecretKeySpec(_KEY.getBytes(),"DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE,key,zoreIv);
        byte[] encryptedData = cipher.doFinal(encryptString.getBytes("UTF-8"));
        return Base64.encode(encryptedData);
    }
    public static String decryptDES(String decryptString) throws Exception{
        new Base64();
        byte[] byteMi = Base64.decode(decryptString);
        IvParameterSpec zeroIv = new IvParameterSpec(iv);
        SecretKeySpec key = new SecretKeySpec(_KEY.getBytes("UTF-8"),"DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE,key,zeroIv);
        byte decryptedData[] = cipher.doFinal(byteMi);
        return new String(decryptedData,"UTF-8");
    }
  public static void main(String[] args) throws Exception {

        String gbkStr = new String("������GBK���ַ�".getBytes("GBK"), "GBK");
        System.out.println("GBK:" + gbkStr);
        String utf8Str = new String(gbkStr.getBytes("GBK"), "ISO8859_1");
        utf8Str = new String(utf8Str.getBytes("ISO8859_1"), "UTF-8");
        System.out.println("UTF-8:" + utf8Str);
        String t = new String(utf8Str.getBytes("UTF-8"), "ISO8859_1");
        t = new String(t.getBytes("ISO8859_1"), "GBK");
        System.out.println("GBK:" + t);

        String tt = encryptDES(t);
        System.out.println(tt);
        System.out.println(decryptDES(tt));
    }

new String,通过String.getBytes(加密文件)

import javax.crypto.Cipher;
import java.io.*;
import java.security.Key;
import java.security.Security;

/**
 * 获取秘钥
 * @author zrx
 * @date 2020/4/22
 */
public class MySecurity {
    private static String strDefaultKey = "hnztzwma";
    private Cipher encryptCipher = null;
    private Cipher decryptCipher = null;
    private Key getKey(byte[] arrBTmp) throws Exception{
        // 创建一个空的8位字节数组,默认值为0
        byte[] arrB = new byte[8];
        // 将原始字节数组转化为8位
        for (int i=0;i<arrBTmp.length;i++){
            arrB[i] = arrBTmp[i];
        }
        // 生成秘钥
        Key key = new javax.crypto.spec.SecretKeySpec(arrB,"DES");
        return key;
    }
    public MySecurity() throws Exception{
        this(strDefaultKey);
    }
    public MySecurity(String strKey) throws Exception{
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        Key key = getKey(strKey.getBytes());
        encryptCipher = Cipher.getInstance("DES");
        encryptCipher.init(Cipher.ENCRYPT_MODE,key);
        decryptCipher = Cipher.getInstance("DES");
        decryptCipher.init(Cipher.DECRYPT_MODE,key);
    }


    public byte[] encrypt(byte[] arrB) throws Exception{
        return encryptCipher.doFinal(arrB);
    }
    public byte[] decrypt(byte[] arrB) throws Exception{
        return decryptCipher.doFinal(arrB);
    }

    /**
     * 文件加密
     * @param file
     * @return
     * @throws Exception
     */
    public static byte[] getBytesFromFile(java.io.File file) throws Exception{
        InputStream is = new FileInputStream(file);
        // 获取文件大小
        long length = file.length();
        // 限制要读取的文件的大小不能能超过Integer.MAX_VALUE
        if (length>Integer.MAX_VALUE){
            return null; // 文件太大,退出程序
        }
        // 创建字节数组
        byte[] bytes = new byte[(int)length];
        // 将文件信息读入数组
        int offset = 0;
        int numRead = 0;
        while (offset<bytes.length && (numRead = is.read(bytes,offset,bytes.length-offset))>=0){
            offset+=numRead;
        }
        // 确认是否将所有信息读入数组
        if (offset<bytes.length){
            throw new IOException("Could not completely read file "+file.getName());
        }
        // 关闭流
        is.close();
        return bytes;
    }

    /**
     * 将字节数组写入文件
     * @param inByte
     * @param pathAndNameString
     * @return
     * @throws IOException
     */
    public static File writeBytesToFile(byte[] inByte,String pathAndNameString) throws IOException{
        File file = null;
        try {
            file = new File(pathAndNameString);
            file.createNewFile();
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(inByte);
            fos.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 文件加密
     * @param srcFile 要加密的源文件
     * @param destFile 加密后的文件
     * @throws Exception
     */
    public void encryptFile(String srcFile,String destFile) throws Exception{
        File infile = new File(srcFile); // 加密前文件
        byte[] myFileA = getBytesFromFile(infile);
        writeBytesToFile(encrypt(myFileA),destFile);
    }

    /**
     * 文件解密
     * @param srcFile 要解密的源文件
     * @param destFile 解密后的文件
     * @throws Exception
     */
    public void decryptFile(String srcFile,String destFile) throws Exception{
        File infile = new File(srcFile);
        byte[] myfileA = getBytesFromFile(infile);
        writeBytesToFile(decrypt(myfileA),destFile);
    }
    public static void main(String[] args) throws Exception {
        try {
            MySecurity des = new MySecurity();
            // 加密文件测试
            des.encryptFile("D:\\file.txt","D:\\enFile.txt");
            // 解密文件测试
            des.decryptFile("D:\\enFile.txt","D:\\deFile.txt");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
 }

错误: Input length must be multiple of 8 when decrypting with padded cipher

  1. 为什么数组转字符串,字符串然后转数组会出现前后两个字节数组的值会有不同,因为并不是每个字节数和编码集上的字符都有对应关系,如果一个字节数在编码集上没有对应编码,new String(byte[])后,往往解出来的会是一些乱码无意义的符号,例如:��
    但是解码的时候�这个字符也是一个字符,在编码表中也有固定的字节数用来表示,所有解码出来的值必定是编码表中对应的值,除非你的字节数组中的字节数正好在编码表中有对应的值,否则编码解码后的字节数组会不一样。

【解决办法】

  1. 可以用base64对参生成的数组进行编码,然后再解码,这样不会想new String(byte[]).getBytes()那样造成数组前后不一致,base64对数据的处理是不会造成误差的。
  2. 直接返回数组,然后再用数组解密
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: DES是一种对称加密算法,可以对字符串进行加密解密DES算法的核心是将明文与密钥进行一系列排列、置换、代替、移位等操作,最终生成密文。 要使用DES字符串c进行加密,首先需要确定密钥。DES密钥长度为56位,密钥可以是任意56位的二进制数或者8个字节的字符串。在确定密钥之后,就可以使用DES算法对字符串c进行加密了。 具体地,首先将字符串c进行补位,使之长度为8的整数倍(不足的部分补零),然后将补位过后的字符串分成若干个8字节的块,对每个块进行加密加密时,先使用初始置换表对明文进行置换,然后将结果分为左右两半,通过16个轮函数对左右两半进行逐轮迭代,最终得到密文。 对于密文的解密,只需要使用相同的密钥和算法,逆向进行加密过程,即可得到明文。 需要注意的是,在实际应用中,DES算法已经被认为不安全,不建议使用。现代加密算法,如AES等,已被广泛使用。 ### 回答2: Des(Data Encryption Standard)是一种对称加密算法,它的核心是将明文划分成64位的块,并通过一系列的置换、替换、移位等运算,结合密钥进行加密解密过程则是将密文通过逆向操作恢复成原始明文。 对字符串c进行Des解密时,首先需要确定一个密钥k。然后将字符串c按照64位一组的方式进行划分,如果最后一组不足64位则需要进行补齐,常用的补齐方式是PKCS7。接着,使用密钥k对每个64位的明文块进行Des加密,得到相应的密文块。如果最后一组不足64位,则需要进行补齐。对于解密过程,同样也是按照64位一组的方式,使用密钥k对每个密文块进行Des解密,得到相应的明文块。如果最后一组不足64位,则需要去除补齐的内容。 需要注意的是,在对字符串c进行加密之前,应该先将其转换成二进制形式进行操作。在实际应用中,Des算法已经逐渐被更加安全和高效的AES算法取代,但Des算法仍然被广泛应用于一些遗留系统中。 ### 回答3: DES是一种对称加密算法,即同样的密钥可以同时用于加密解密加密时,将要加密字符串划分成一定长度的数据块,经过多轮复杂的运算和替换后,输出密文。解密时,同样使用相同的密钥,将密文输入,经过反向的运算和替换后,得到明文。 对于给定的字符串c,要进行DES解密,需要先确定一个密钥。密钥长度为64位,通常使用8个字符作为密钥,经过转换后得到一个64位的二进制数。然后,需要将要加密字符串c按照固定长度分段,通常为64位。如果c的长度不足64位,则需要补充至64位,常用的方法是填充0或者填充随机字符串。对于最后一段不足64位的字符串,则需要进行特殊处理。 在加密过程中,将密钥和明文输入到DES算法中,经过多轮的加密操作,最终输出密文。在解密过程中,将密钥和密文输入到DES算法中,经过反向的操作,最终得到明文。需要注意的是,加密解密的过程使用相同的密钥,否则无法正确解密出明文。 DES算法虽然已经被AES等更加安全的加密算法所替代,但仍然在某些领域得到广泛应用,如银行卡密码、数字证书等。在实际使用中,需要注意密钥的保护、数据的完整性、加密算法的性能等问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值