开发过程中用到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 {
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.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);
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 "main" 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..