记一次文件编码出现的BUG javax.crypto.BadPaddingException: Given final block not properly padded

1.前景:工作中需要实现一个功能,导出的数据需要加密,不能被明文看到,使用DES加密,对byte数组加密解密操作代码如下

public class DESTool {
  static String transformation = "DESede/ECB/PKCS5Padding";
    static String algorithm = "DESede";
  public byte[] decode(byte[] srcByte, byte[] keyByte, int offset, int length) throws Exception, NoSuchAlgorithmException {
//        DESKeySpec spec = new DESKeySpec(keyByte);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        SecretKey secretKey = new SecretKeySpec(keyByte, algorithm);
//        KeySpec spec = new SecretKeySpec(keyByte, algorithm);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] b = cipher.doFinal(srcByte, offset, length);
        return b;
    }
  public byte[] encode(byte[] srcByte, byte[] keyByte, int offset, int length) throws Exception, NoSuchAlgorithmException {
//        DESKeySpec spec = new DESKeySpec(keyByte);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        SecretKey secretKey = new SecretKeySpec(keyByte, algorithm);
//        KeySpec spec = new SecretKeySpec(keyByte, algorithm);
//        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
//        SecretKey secretKey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] b = cipher.doFinal(srcByte, offset, length);
        return b;
    }
}

2.在使用如上方法进行加解密时,由于文件大小是不确定的,所以使用分批次加解密,一次加解密50*1024个byte

3.自主测试没有问题,但是测试环境上出现问题,堆栈信息如下

Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
    at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DashoA13*..)
    at javax.crypto.Cipher.doFinal(DashoA13*..)

4.网上搜索答案都是说一些linux上SecretKey获取的问题,但是和本人工作中的状况不符,本人工作中windows开发环境上加密导出的文件去测试环境导入是可以正常导入的,并且本人写了测试类,编译成class文件后去测试环境执行class文件,加解密没有问题,所以这个可能性排除

5.于是我要来了测试环境的数据库连接信息,本地连接测试数据库,同时导出未加密的明文文件和加密的密文文件,之后对明文文件加密之后和密文文件逐字节进行对比,对比结果完全一样

6.最后想到加密解密是按自己进行的,会不会是加解密的字节长度导致的,于是我把测试类中加密明文文件时使用的字节数组长度设置为5*1024,而不是50*1024,之后加密,再和密文文件逐字节对比,果然出现了不同,

7.最后经测试,需加密的字节长度和加密结果的字节长度存在以下关系:加密结果字节长度 = (需加密字节长度/8)* 8 + 8;于是我把解密时字节长度改为了50*1024+8,问题解决

8.结论:加密过程中字节长度可能会变化,因此解密时字节长度应该和加密时字节长度存在一定的相关关系,不能随便设置。

原文地址:https://www.cnblogs.com/fiftyonesteps/p/11245517.html

时间: 2024-09-28 14:49:45

记一次文件编码出现的BUG javax.crypto.BadPaddingException: Given final block not properly padded的相关文章

解决Delphi7的自带的UTF-8编码转换函数BUG

Delphi7及其以下版本的 VCL 只支持 Ansi, 所以... WideString 与 UTF8String (定义与 AnsiString 相同) 并没有办法正确的在 VCL 中显示 Delphi7自带的utf-8转换函数遇到其无法识别的字符串就返回空. 用以下转换函数可以解决这个bug unit util_utf8; interface uses Windows; type UTF8String = AnsiString; function AnsiToWide(const S: A

批量编码转化工具(实现文件编码的自动检测)

先看截图 工具对.c,.h,.cpp,.txt文件进行转换,其余类型文件,则仅仅拷贝到转换后的输出路径.这种处理是为了转换前和转换后的项目结构保持不变. 工具中一个重要的部分,是对文件编码的自动检测(选项为Auto的情况) 此部分使用了第三方组件(NonCodeNet) 调用代码如下: public string getFileEncoding(string filePath) { string uni = string.Empty; Stream stream = File.Open(file

Linux下查看文件编码,文件编码格式转换和文件名编码转换

linux相关   2008-10-07 10:46   阅读1392   评论0   字号: 大大  中中  小小  如果你需要在Linux中 操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linux一般都是 UTF-8.下面介绍一下,在Linux中如何查看文件的编码及如何进行对文件进行编码转换. 查看文件编码 在Linux中查看文件编码可以通过以下几种方式: 1.在Vim中可以直接查看文件编码 :set file

Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() 获取文件编码,f.encoding() 获取文件在内存中的编号,f.fileno() 获取文件终端类型(tty.打印机等),f.isatty() 获取文件名,f.name() 判断文件句柄是否可移动(tty等不可移动),f.seekable() 判断文件是否可读,f.readable() 判断文件是

【转载】关于Python脚本开头两行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型

下面的内容来自:http://www.cnblogs.com/blueskylcc/p/5332642.html, 对方也是转的,不过没有找到转载的出处: 1.#!/usr/bin/python 是用来说明脚本语言是 python 的 是要用 /usr/bin下面的程序(工具)python,这个解释器,来解释 python 脚本,来运行 python 脚本的. 2.# -*- coding: utf-8 -*- 是用来指定文件编码为 utf-8 的 详情可以参考:PEP 0263 - Defin

centos 文件编码转码

一直以来centos 下 文件转码都用的是iconv这个命令,最近发现了个enca,比iconv好用多了. iconv示例: iconv -f encoding -t encoding inputfile -o outfile -f  需要转码文件的原编码 -t 需要转为的编码 -o 输出的文件 iconv 弊端,需要知道源文件的原始编码才行. enca: yum -y install enca  #依赖epel源 查看当前文件编码: # enca -L zh_CN host0740960_20

(转)剖析Linux文件编码的查看及修改

Linux文件编码的查看和修改都有不止一种做法,如果你需要在Linux中操作windows下的文件,那么很可能会经常遇到文件编码转换的问题,如何进行这项工作,也应该是经常工作在双系统下的操作者的必须掌握的知识. Windows中默认的文件格式是GBK(gb2312),而Linux一般都是UTF-8.下面介绍一下,在Linux中如何查看文件的编码及如何进行对文件进行编码转换. 查看文件编码 在Linux中查看文件编码可以通过以下几种方式: 1.在Vim中可以直接查看文件编码 :set fileen

python声明文件编码,必须在文件的第一行或第二行

#coding=utf-8和# -*- coding: utf-8 -*-的作用 – 指定文件编码类型 注意的两点: 1.声明必须在文件的第一行或第二行: 2.coding后面必须紧跟冒号或等号,#coding : utf-8是错的. 例: 声明编码前有字符串 1 '''testing user longin''' 2 #coding:utf-8 3 4 print u'''登录相关的测试''' 或 声明编码位于第三行 1 #'test' 2 3 #coding:utf-8 4 5 print

linux下查看文件编码及修改编码

http://blog.csdn.net/jnbbwyth/article/details/6991425 查看文件编码在Linux中查看文件编码可以通过以下几种方式:1.在Vim中可以直接查看文件编码:set fileencoding即可显示文件编码格式.如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱码的问题,那么你可以在~/.vimrc 文件中添加以下内容: set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936 这样,就可以