获取java.security.InvalidKeyException:密钥必须是 128、192 或 256 位长的双鱼
Getting java.security.InvalidKeyException: Key must be 128, 192, or 256 bit long twofish
下面的代码是用来加密明文的,我用的是IAIK Twofishencryption/decryption代码java下面的示例代码在128位下工作正常密钥但是当我尝试使用 192 位和 156 位密钥时它给出了一个例外 java.security.InvalidKeyException: Key must be 128, 192, or 256 bit long!
-
private static void doCrypto(int cipherMode, String key, File inputFile, File outputFile) throws CryptoException {
try {
SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION, "IAIK");
cipher.init(cipherMode, secretKey);
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
inputStream.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
| IllegalBlockSizeException | IOException ex) {
throw new CryptoException("Error encrypting/decrypting file", ex);
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
对于上述方法,当我提供 128 位密钥时,它工作正常,如下所示,
KeyGenerator keyGen = KeyGenerator.getInstance("Twofish", "IAIK");
keyGen.init(192);
txtSecretKey.setText(iaik.utils.Util.toString(key.getEncoded()));
SekertKey key = key.generateKey();
encrypt(txtSecretKey.getText(), inputFile, encryptedFile);
Caused by: java.security.InvalidKeyException: Key must be 128, 192, or 256 bit long!
at iaik.security.cipher.N.a(Unknown Source)
at iaik.security.cipher.i.a(Unknown Source)
at iaik.security.cipher.a.engineInit(Unknown Source)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1189)
at com.opensourse.crypto.twofish.CryptoUtils.doCrypto(CryptoUtils.java:38)
确保您有来自 here. See 的 "java cryptography extension (jce) unlimited strength jurisdiction policy files 8" 的说明。
仔细检查一些答案总是好的,因为错误“128 位 aes 密钥有效,192/256 密钥无效”是
有限 加密策略的症状。
请 运行 这个小程序并在控制台上向我们展示结果("false" 表示无限制的加密策略...)
import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;
public class Main {
public static void main(String[] args) {
System.out.println("\nTest with Java version: " + Runtime.version());
System.out.println("Java restricted cryptography: " + restrictedCryptography());
}
/**
* Determines if cryptography restrictions apply.
* Restrictions apply if the value of {@link Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method.
* This method is used with the transform <code>"AES/CBC/PKCS5Padding"</code> as this is an often used algorithm that is <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">an implementation requirement for Java SE</a>.
*
* @return <code>true</code> if restrictions apply, <code>false</code> otherwise
*
* code by Maarten Bodewes,
*/
public static boolean restrictedCryptography() {
try {
return Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE;
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e);
}
}
}
在您的主要方法中,您将 SecretKey 转换为显示在 (GUI) 文本字段中的字符串。打印出密钥的内容如下所示:
key in hex: 7b44a1f09136a248a40c8043fa02fbcf
textfield : 7B:44:A1:F0:91:36:A2:48:A4:0C:80:43:FA:02:FB:CF
将文本字段中的此字符串转换回 byte[] 以使用“.getBytes”重新生成 secretKey 将失败,因为冒号字符也将被解码:
SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM)
IAIK-Util-class 提供了一个“.toByteArray”方法,它只忽略“0-9”和 'a-f' 以外的其他字符,请参阅文档
在 http://javadoc.iaik.tugraz.at/iaik_jce/current/iaik/utils/Util.html:
将具有十六进制值的给定字符串转换为字节数组。例如“001122”变成了{0, 0x11, 0x22}。 '0'-'9', 'a'-'z', 和 'A'-'Z' 范围之外的所有字符或干脆忽略.
只需更改 doCrypto-method 中的行,一切正常:
SecretKey secretKey = new SecretKeySpec(iaik.utils.Util.toByteArray(key), ALGORITHM);
下面的代码是用来加密明文的,我用的是IAIK Twofishencryption/decryption代码java下面的示例代码在128位下工作正常密钥但是当我尝试使用 192 位和 156 位密钥时它给出了一个例外 java.security.InvalidKeyException: Key must be 128, 192, or 256 bit long!
-
private static void doCrypto(int cipherMode, String key, File inputFile, File outputFile) throws CryptoException {
try {
SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION, "IAIK");
cipher.init(cipherMode, secretKey);
FileInputStream inputStream = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
inputStream.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(outputFile);
outputStream.write(outputBytes);
inputStream.close();
outputStream.close();
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException
| IllegalBlockSizeException | IOException ex) {
throw new CryptoException("Error encrypting/decrypting file", ex);
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
对于上述方法,当我提供 128 位密钥时,它工作正常,如下所示,
KeyGenerator keyGen = KeyGenerator.getInstance("Twofish", "IAIK");
keyGen.init(192);
txtSecretKey.setText(iaik.utils.Util.toString(key.getEncoded()));
SekertKey key = key.generateKey();
encrypt(txtSecretKey.getText(), inputFile, encryptedFile);
Caused by: java.security.InvalidKeyException: Key must be 128, 192, or 256 bit long!
at iaik.security.cipher.N.a(Unknown Source)
at iaik.security.cipher.i.a(Unknown Source)
at iaik.security.cipher.a.engineInit(Unknown Source)
at javax.crypto.Cipher.init(Cipher.java:1249)
at javax.crypto.Cipher.init(Cipher.java:1189)
at com.opensourse.crypto.twofish.CryptoUtils.doCrypto(CryptoUtils.java:38)
确保您有来自 here. See
仔细检查一些答案总是好的,因为错误“128 位 aes 密钥有效,192/256 密钥无效”是 有限 加密策略的症状。 请 运行 这个小程序并在控制台上向我们展示结果("false" 表示无限制的加密策略...)
import javax.crypto.Cipher;
import java.security.NoSuchAlgorithmException;
public class Main {
public static void main(String[] args) {
System.out.println("\nTest with Java version: " + Runtime.version());
System.out.println("Java restricted cryptography: " + restrictedCryptography());
}
/**
* Determines if cryptography restrictions apply.
* Restrictions apply if the value of {@link Cipher#getMaxAllowedKeyLength(String)} returns a value smaller than {@link Integer#MAX_VALUE} if there are any restrictions according to the JavaDoc of the method.
* This method is used with the transform <code>"AES/CBC/PKCS5Padding"</code> as this is an often used algorithm that is <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#impl">an implementation requirement for Java SE</a>.
*
* @return <code>true</code> if restrictions apply, <code>false</code> otherwise
*
* code by Maarten Bodewes,
*/
public static boolean restrictedCryptography() {
try {
return Cipher.getMaxAllowedKeyLength("AES/CBC/PKCS5Padding") < Integer.MAX_VALUE;
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("The transform \"AES/CBC/PKCS5Padding\" is not available (the availability of this algorithm is mandatory for Java SE implementations)", e);
}
}
}
在您的主要方法中,您将 SecretKey 转换为显示在 (GUI) 文本字段中的字符串。打印出密钥的内容如下所示:
key in hex: 7b44a1f09136a248a40c8043fa02fbcf
textfield : 7B:44:A1:F0:91:36:A2:48:A4:0C:80:43:FA:02:FB:CF
将文本字段中的此字符串转换回 byte[] 以使用“.getBytes”重新生成 secretKey 将失败,因为冒号字符也将被解码:
SecretKey secretKey = new SecretKeySpec(key.getBytes(), ALGORITHM)
IAIK-Util-class 提供了一个“.toByteArray”方法,它只忽略“0-9”和 'a-f' 以外的其他字符,请参阅文档 在 http://javadoc.iaik.tugraz.at/iaik_jce/current/iaik/utils/Util.html:
将具有十六进制值的给定字符串转换为字节数组。例如“001122”变成了{0, 0x11, 0x22}。 '0'-'9', 'a'-'z', 和 'A'-'Z' 范围之外的所有字符或干脆忽略.
只需更改 doCrypto-method 中的行,一切正常:
SecretKey secretKey = new SecretKeySpec(iaik.utils.Util.toByteArray(key), ALGORITHM);