相关文章推荐
朝气蓬勃的紫菜  ·  SPI_InitStructure.SPI_ ...·  3 周前    · 
单身的斑马  ·  [Solved] Issue with ...·  4 月前    · 

开发过程中用到3DES对敏感信息进行加密,秘钥用的是32位的,报出如下异常

Exception in thread "main" java.security.InvalidKeyException: Invalid key length: 32 bytes
    at com.sun.crypto.provider.DESedeCipher.engineGetKeySize(DESedeCipher.java:370)
    at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1067)
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1025)
    at javax.crypto.Cipher.implInit(Cipher.java:801)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
    at javax.crypto.Cipher.init(Cipher.java:1249)
    at javax.crypto.Cipher.init(Cipher.java:1186)
    at com.adtec.des.des_temp.encryptThreeDESECB(des_temp.java:33)
    at com.adtec.des.des_temp.main(des_temp.java:61)

加密代码如下:

* @param src 加密内容 * @param key 秘钥 32位长度 * @return 加密后的内容 * @throws Exception public static byte [] encryptThreeDESECB ( final String src, final String key) throws Exception { SecretKey securekey = new SecretKeySpec(key.getBytes(), "DESede" ); final Cipher cipher = Cipher.getInstance( "DESede/ECB/PKCS5Padding" ); cipher.init(Cipher.ENCRYPT_MODE, securekey); final byte [] b = cipher.doFinal(src.getBytes()); return b;
public static void main(String[] args) throws Exception {
        String key = "11112222333344445555666677778888";
        // 加密流程
        String telePhone = "123456";
        byte[] telePhone_encrypt = null;
        telePhone_encrypt = encryptThreeDESECB(URLEncoder.encode(telePhone, "UTF-8"), key);
        System.out.println(new String(telePhone_encrypt));
        // 解密流程
        String tele_decrypt = decryptThreeDESECB(telePhone_encrypt, key);
        System.out.println("解密:" + tele_decrypt);

感觉不应该有问题啊???
试着将秘钥长度减为24位
这里写图片描述

这就可以了,但这是不可以的,系统不是我一个人操作,我用前24位加密,别人不知道,用后24位解密,就会导致结果不一致,无法解密。

知道我看见了另外一个方法:

* @param src 加密内容 * @param key 秘钥 32位长度 * @return 加密后的内容 * @throws Exception public static byte[] encryptThreeDESECB(final String src, final String key) throws Exception { final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8")); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); final SecretKey securekey = keyFactory.generateSecret(dks); final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, securekey); final byte[] b = cipher.doFinal(src.getBytes()); return b;

其他的一模一样

解密代码也一样

* @param telePhone_encrypt 密文 * @param key 秘钥 32位长度 * @return 解密后明文 * @throws Exception public static String decryptThreeDESECB(byte[] telePhone_encrypt, final String key) throws Exception { // --解密的key final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8")); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); final SecretKey securekey = keyFactory.generateSecret(dks); // --Chipher对象解密 final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, securekey); final byte[] retByte = cipher.doFinal(telePhone_encrypt); return new String(retByte);

仔细看了一下有一行代码有重大嫌疑

 final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));

看一眼源码
这里写图片描述

大概说的是,它用前24位构建DESedeKeySpec对象

再看看其DESedeKeySpec内部是如何实现的,打卡jdk的源码

* Uses the first 24 bytes in <code>key</code>, beginning at * <code>offset</code>, as the DES-EDE key * @param key the buffer with the DES-EDE key * @param offset the offset in <code>key</code>, where the DES-EDE key * starts * @exception InvalidKeyException if the given key has a wrong size DESedeKey(byte[] key, int offset) throws InvalidKeyException { if (key==null || ((key.length-offset)<DESedeKeySpec.DES_EDE_KEY_LEN)) { throw new InvalidKeyException("Wrong key size"); this.key = new byte[DESedeKeySpec.DES_EDE_KEY_LEN]; System.arraycopy(key, offset, this.key, 0, DESedeKeySpec.DES_EDE_KEY_LEN); DESKeyGenerator.setParityBit(this.key, 0); DESKeyGenerator.setParityBit(this.key, 8); DESKeyGenerator.setParityBit(this.key, 16); // Use the cleaner to zero the key when no longer referenced final byte[] k = this.key; CleanerFactory.cleaner().register(this, () -> java.util.Arrays.fill(k, (byte)0x00));

看到一个关键的东西:DESedeKeySpec.DES_EDE_KEY_LEN
这里写图片描述

果然长度是24

从底层源码

if (key==null || ((key.length-offset)<DESedeKeySpec.DES_EDE_KEY_LEN)) {
        throw new InvalidKeyException("Wrong key size");

可以看出,如果秘钥为空或者小于24位会抛出Wrong key size,试一下
这里写图片描述

再试一下超过32位的
这里写图片描述

至此就可以发现了,后面这张加密方法,秘钥长度不能小于24,可以大于24,但是其实现的时候只截取了前24位

总结,推荐使用第二中加密方法,因为是底层截取的,不是我们手动截取的,无论是加密方还是解密方都遵循这个规则

开发过程中用到3DES对敏感信息进行加密,秘钥用的是32位的,报出如下异常Exception in thread &quot;main&quot; java.security.InvalidKeyException: Invalid key length: 32 bytes at com.sun.crypto.provider.DESedeCipher.engineGetKeySize(DESedeCip...
1. AES 1.1. 概念 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。 这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用,已然成为对称密钥加密中最流行的算法之一。详见 百科 高级加密标准 AES 1.2. JAVA实现AES加解密 import lombok.extern.slf4j.Slf4j; import javax.
转载自https://www.cnblogs.com/hzxy-blog/p/9355064.html 前段时间因工作需要,接触到了SM算法。国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。 SM1为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。 SM2为非对称加密,基于ECC。该算法...
1. 异常现象 使用AES进行加密时,报了一个异常:InvalidKeyException: Invalid AES key length: 12 bytes java.security.InvalidKeyException: Invalid AES key length: 12 bytes at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:509) at javax.crypto.Cipher.passCr
在使用OpenSSH 连接使用FreeSSH服务器时 出现了 连接失败: ssh_dispatch_run_fatal: Connection to **** port 22: Invalid key length 这是因为在FreeSSH服务器端 配置SSH时,选择的RSA-key为512bit的 而在OpenSSH 7.6之后 Refuse RSA keys <1024 bits in length and improve reporting for keys that do not
Key length not 128/192/256 bits      一般是使用对称算法加密的时候出现的异常,它的意思是指 key的长度不是 128,192或者256 位,注意!!! 并不是不足,而是不是,这个意思指的是key的长度必须要是128,192或者256 位,知道了这个的话就很好去解决这个问题了 以AES 加密为例: aes.getSecretKey().getEncoded().length 能获取到aes 的 字节长度 (注意是字节) 128 位 对应的是 16
解决AES加密报错:java.security.InvalidKeyException: Invalid AES key length: xx bytes
使用ssh命令登入锐捷交换机,报错提示如下:ssh_dispatch_run_fatal: Connect to x.x.x.x port 22 : Invalid key length C:\Users\Administrator>ssh grmhgdl@x.x.x.x ssh_dispatch_run_fatal: Connection to x.x.x.x port 22: Invalid key length 查看电脑的ssh版本 C:\Users\Administrator&g..