AreaServiceTest运行报错

AreaServiceTest运行报错

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: java.lang.RuntimeException: javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
    at com.imooc.o2o.util.DESUtil.getDecryptString(DESUtil.java:88)
    at com.imooc.o2o.util.EncryptPropertyPlaceholderConfigurer.convertProperty(EncryptPropertyPlaceholderConfigurer.java:16)
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.convertProperties(PropertyResourceConfigurer.java:106)
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:83)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:281)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:161)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:686)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:524)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:108)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 24 more

Caused by: javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
    at com.sun.crypto.provider.CipherCore.prepareInputBuffer(CipherCore.java:1005)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:848)
    at com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)
    at javax.crypto.Cipher.doFinal(Cipher.java:2164)
    at com.imooc.o2o.util.DESUtil.getDecryptString(DESUtil.java:83)
    ... 37 more

在调用工具类DESUtil的getDecryptString方法的时候报了如下错误:

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

使用填充密码解密时,输入长度必须是8的倍数

不知道怎么解决这个问题,我本来以为是数据库密码长度的问题,我的密码长度只有4位。但我把jdbc.properties配置文件中的jdbc.password改成8位,依然报这个错。在DESUtil类中的getDecryptString方法起始处打断点,发现传入的方法参数String str确实为我新修改的8位的jdbc.password,但往下运行到

// 解密
byte[] doFinal = cipher.doFinal(bytes);

这一行的时候调用doFinal方法就抛出异常了。。。不知道要改哪里?突然多了几个工具类,但老师没怎么说明。。。

正在回答

登陆购买课程后可参与讨论,去登陆

4回答

同学的做法是正确的。在课程中,加密不是重点,所以没做讲解,也没使用。同学能够自己解决,很棒棒哦,如果还有问题,可以继续提问。

祝:学习愉快~

提问者 WayneChen 2019-11-10 20:38:48

搞懂了。DESUtil工具类中有个main方法是用来生成密文的,要把jdbc.username和jdbc.password的值带入main方法中,运行后获得加密后的值,再把对应的值替换掉原来jdbc.properties中的明文的MySQL数据库用户名和密码就可以了。这样EncryptPropertyPlaceholderConfigurer里的需要加密的字段数组就不用清空,也能运行正常了。


jdbc.properties要写成这样才行,用户名和密码都要使用DESUtil工具类加密后的值:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8
jdbc.username=WnplV/ietfQ=
jdbc.password=aRkgtcKflNM=

老师在视频里好像没说到需要修改一下这个配置,改成加密后的username和password。。。

好帮手慕阿满 2019-11-10 19:41:52

同学你好,DESUtil和EncryptPropertyPlaceholderConfigurer工具类是对数据进行加密,在本次课程中不是重点,所以没做讲解。

问一下同学修改 需要加密的字段数组 去掉"jdbc.username", "jdbc.password"后,保存的数据是明文吗?另外建议同学查看一下spring-dao.xml中是否有如下的bean,如:

http://img1.sycdn.imooc.com//climg/5dc7f76c0965275a08500289.jpg

祝:学习愉快~

  • 提问者 WayneChen #1
    老师好。我的spring-dao.xml文件中有配置这个bean的。Redis中保存的应该是明文。 127.0.0.1:6379> keys * 1) "arealist" 127.0.0.1:6379> get arealist "[{\"areaId\":3,\"areaName\":\"\xe8\xa5\xbf\xe8\x8b\x91\",\"priority\":2,\"createTime\":null,\"lastEditTime\":null},{\"areaId\":2,\"areaName\":\"\xe4\xb8\x9c\xe8\x8b\x91\",\"priority\":1,\"createTime\":null,\"lastEditTime\":null}]" 127.0.0.1:6379> 不知道这个EncryptPropertyPlaceholderConfigurer类里的encryptPropNames成员变量有什么用途?为什么要配置这个?配置的也是jdbc.username和jdbc.password,也就是MySQL数据库相关的,那跟Redis有什么关系呢?有点困惑。。。
    2019-11-10 20:05:40
提问者 WayneChen 2019-11-10 16:37:08

发现把com.imooc.o2o.util.EncryptPropertyPlaceholderConfigurer类中的

// 需要加密的字段数组
private String[] encryptPropNames = {"jdbc.username", "jdbc.password"};

改写成

private String[] encryptPropNames = {};

之后就运行正常了,redis数据库里也正常保存数据。但这样做也就意味着用不了加密,一用加密就报错,怎么办?

问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师