接下来,乐厨号将带你认识并了解java手机加密软件,希望可以给你带来一些启示。

怎么把mysql数据库中现有的数据进行des加密,加密后的结果和java中des加密的结果一样。

怎么把mysql数据库中现有的数据进行des加密,加密后的结果和java中des加密的结果一样。

最近需要对数据进行加密/解密, 因此选用了CryptoJS库, 对数据做DES算法的加密/解密

首选查看官方示例, 将密文进行Base64编码, 掉进一个大坑

<script src="htt p:/ /crypto-js.googlecod e.c om/svn/tags/3.1.2/build/rollups/tripledes.js"></script>

<script>

var encrypted = CryptoJS.DES.encrypt("Message", "Secret Passphrase");

// ciphertext changed every time you run it

// 加密的结果不应该每次都是一样的吗

console.log(encrypted.toString(), encrypted.ciphertext.toString(CryptoJS.enc.Base64));

var decrypted = CryptoJS.DES.decrypt(encrypted, "Secret Passphrase");

console.log(decrypted.toString(CryptoJS.enc.Utf8));

</script>

对这些加密算法不了解, 只能求助Google

des encrypion: js encrypted value does not match the java encrypted value

In cryptoJS you have to convert the key to hex and useit as word just like above (otherwise it will be considered as passphrase)

For the key, when you pass a string, it's treated as a passphrase and used to derive an actual key and IV. Or you can pass a WordArray that represents the actual key.

原来是我指定key的方式不对, 直接将字符串做为参数, 想当然的以为这就是key, 其实不然, CryptoJS会根据这个字符串算出真正的key和IV(各种新鲜名词不解释, 问我也没用, 我也不懂 -_-")

那么我们只需要将key和iv对应的字符串转成CryptoJS的WordArray类型, 在DES加密时做为参数传入即可, 这样对Message这个字符串加密, 每次得到的密文都是YOa3le0I+dI=

var keyHex = CryptoJS.enc.Utf8.parse('abcd1234');

var ivHex = CryptoJS.enc.Utf8.parse('inputvec');

var encrypted = CryptoJS.DES.encrypt('Message', keyHex, { iv: ivHex });

这样是不是就万事OK了 哪有, 谁知道这坑是一个接一个啊.

我们再试试Java这边的DES加密是不是和这个结果一样, 具体实现请参考Simple Java Class to DES Encrypt Strings

果真掉坑里了, Java通过DES加密Message这个字符串得到的结果是8dKft9vkZ4I=和CryptoJS算出来的不一样啊.亲

继续求助Google

C# and Java DES Encryption value are not identical

SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES.(JCA Doc)

This means that in the case of the SunJCE provider,

Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");

and

Cipher c1 = Cipher.getInstance("DES");

are equivalent statements.

原来是CryptoJS进行DES加密时, 默认的模式和padding方式和Java默认的不一样造成的, 必须使用ECB mode和PKCS5Padding, 但是CryptoJS中只有Pkcs7, 不管了, 试试看.

<script src="htt p:/ /crypto-js.googleco de.c om/svn/tags/3.1.2/build/rollups/tripledes.js"></script>

<script src="ht tp:/ /crypto-js.googleco de.c om/svn/tags/3.1.2/build/components/mode-ecb.js"></script>

<script>

var keyHex = CryptoJS.enc.Utf8.parse('abcd1234');

var encrypted = CryptoJS.DES.encrypt('Message', keyHex, {

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

});

console.log(encrypted.toString(), encrypted.ciphertext.toString(CryptoJS.enc.Base64));

</script>

咦.使用Pkcs7能得到和Java DES一样的结果了, 哇塞.好神奇

那我们试试统一Java也改成Cipher.getInstance("DES/ECB/PKCS7Padding")试试, 结果得到一个大大的错误

Error:java.security.NoSuchAlgorithmException: Cannot find any provider supporting DES/ECB/PKCS7Padding

没办法, 继续Google

java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/ECB/PKCS7PADDING

I will point out that PKCS#5 and PKCS#7 actually specify exactly the same type of padding (they are the same!), but it's called #5 when used in this context. :)

这位大侠给出的解释是: PKCS#5和PKCS#7是一样的padding方式, 对加密算法一知半解, 我也只能暂且认可这个解释了.

忙完了DES的加密, 接下来就是使用CryptoJS来解密了. 我们需要直接解密DES加密后的base64密文字符串. CryptoJS好像没有提供直接解密DES密文字符串的方法啊, 他的整个加密/解密过程都是内部自己在玩, 解密时需要用到加密的结果对象, 这不是坑我吗

只好研究下CryptoJS DES加密后返回的对象, 发现有一个属性ciphertext, 就是密文的WordArray, 那么解密的时候, 我们是不是只要提供这个就行了呢

var keyHex = CryptoJS.enc.Utf8.parse('abcd1234');

// direct decrypt ciphertext

var decrypted = CryptoJS.DES.decrypt({

ciphertext: CryptoJS.enc.Base64.parse('8dKft9vkZ4I=')

}, keyHex, {

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

});

console.log(decrypted.toString(CryptoJS.enc.Utf8));

果不其然, 到此为止, 问题全部解决, 豁然开朗.

完整代码请参考CryptoJS-DES.html

Use CryptoJS encrypt message by DES and direct decrypt ciphertext, compatible with Java Cipher.getInstance("DES")

使用jasypt加密配置报错:DecryptionException:Unabletodecrypt

前几天分享了一篇《SpringBoot2.x基础教程:加密配置中的敏感信息》,然后看到群里有小伙伴反应跟着这篇文章出现了这个异常com.ulisesbocchio.jasyptspringboot.exception.DecryptionException:Unabletodecrypt。

具体完整的错误信息如下:

Causedby:com.ulisesbocchio.jasyptspringboot.exception.DecryptionException:Unabletodecrypt:ENC(/AL9nJENCYCh9Pfzdf2xLPsqOZ6HwNgQ3AnMybFAMeOM5GphZlOK6PxzozwtCm+Q).DecryptionofPropertiesfailed,makesureencryption/decryptionpasswordsmatchatcom.ulisesbocchio.jasyptspringboot.resolver.DefaultPropertyResolver.lambda$resolvePropertyValue$0(DefaultPropertyResolver.java:46)~[jasypt-spring-boot-3.0.3.jar:na]atjava.util.Optional.map(Optional.java:215)~[na:1.8.0_151]atcom.ulisesbocchio.jasyptspringboot.resolver.DefaultPropertyResolver.resolvePropertyValue(DefaultPropertyResolver.java:40)~[jasypt-spring-boot-3.0.3.jar:na]atcom.ulisesbocchio.jasyptspringboot.resolver.DefaultLazyPropertyResolver.resolvePropertyValue(DefaultLazyPropertyResolver.java:50)~[jasypt-spring-boot-3.0.3.jar:na]atcom.ulisesbocchio.jasyptspringboot.EncryptablePropertySource.getProperty(EncryptablePropertySource.java:20)~[jasypt-spring-boot-3.0.3.jar:na]atcom.ulisesbocchio.jasyptspringboot.caching.CachingDelegateEncryptablePropertySource.getProperty(CachingDelegateEncryptablePropertySource.java:41)~[jasypt-spring-boot-3.0.3.jar:na]atcom.ulisesbocchio.jasyptspringboot.wrapper.EncryptableMapPropertySourceWrapper.getProperty(EncryptableMapPropertySourceWrapper.java:31)~[jasypt-spring-boot-3.0.3.jar:na]atorg.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:85)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:62)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:588)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.context.support.PropertySourcesPlaceholderConfigurer$1.getProperty(PropertySourcesPlaceholderConfigurer.java:137)~[spring-context-5.3.8.jar:5.3.8]atorg.springframework.context.support.PropertySourcesPlaceholderConfigurer$1.getProperty(PropertySourcesPlaceholderConfigurer.java:133)~[spring-context-5.3.8.jar:5.3.8]atorg.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:85)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.core.env.PropertySourcesPropertyResolver.getPropertyAsRawString(PropertySourcesPropertyResolver.java:74)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:159)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)~[spring-core-5.3.8.jar:5.3.8]atorg.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175)~[spring-context-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:936)~[spring-beans-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1321)~[spring-beans-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)~[spring-beans-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)~[spring-beans-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)~[spring-beans-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)~[spring-beans-5.3.8.jar:5.3.8]atorg.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)~[spring-beans-5.3.8.jar:5.3.8].69commonframesomittedCausedby:org.jasypt.exceptions.EncryptionOperationNotPossibleException:nullatorg.jasypt.encryption.pbe.StandardPBEByteEncryptor.decrypt(StandardPBEByteEncryptor.java:1165)~[jasypt-1.9.3.jar:na]atorg.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:738)~[jasypt-1.9.3.jar:na]atorg.jasypt.encryption.pbe.PooledPBEStringEncryptor.decrypt(PooledPBEStringEncryptor.java:511)~[jasypt-1.9.3.jar:na]atcom.ulisesbocchio.jasyptspringboot.encryptor.DefaultLazyEncryptor.decrypt(DefaultLazyEncryptor.java:57)~[jasypt-spring-boot-3.0.3.jar:na]atcom.ulisesbocchio.jasyptspringboot.resolver.DefaultPropertyResolver.lambda$resolvePropertyValue$0(DefaultPropertyResolver.java:44)~[jasypt-spring-boot-3.0.3.jar:na].94commonframesomitted

直接根据错误信息的描述来判断,就是解密失败了。

下面整理一下可能产生解密失败的几种可能:

第一种:推测解密失败的原因是加密和解密使用的密钥不一致,也就是jasypt.encryptor.password的配置和使用插件时候的参数传的不同。

第二种:没有安装不限长度的JCE版本(UnlimitedStrengthJavaCryptographyExtension)。因为DD以前在用SpringCloudConfig的时候已经装过了,所以在写之前这个案例的时候没有提到这点,应该一些还没有接触SpringCloud的读者通常都是这个原因导致。

我们可以从Oracle的官方网站中下载你所用Java版本对应的JCE安装包,比如:JCE8下载地址。它是一个压缩包,解压后可以看到下面三个文件:

README.txtlocal_policy.jarUS_export_policy.jar

我们需要将local_policy.jar和US_export_policy.jar两个文件复制到$JAVA_HOME/jre/lib/security目录下,覆盖原来的默认内容,这样加密解密的准备工作就完成了。

欢迎关注我的公众号:程序猿DD,分享外面看不到的干货与思考!

JAVA写RSA加密,公钥私钥都是一样的,为什么每次加密的结果不一样

因为rsa是非对称加密,它使用的是随机大素数的抽取,每次随机生成的,所以每次加密的结果不可能一样