Java 如何检查密码是否支持特定的密钥大小?
如何检查所选密码算法转换是否支持特定的密钥长度Java 如何检查密码是否支持特定的密钥大小?,java,encryption,key,Java,Encryption,Key,如何检查所选密码算法转换是否支持特定的密钥长度 boolean checkAlgorithm( String encryptMethod, int keyLength ) { Cipher cipher = Cipher.getInstance(encryptMethod); int maxLength = cipher.getMaxAllowedKeyLength(encryptMethod); if ( keyLength <= maxLength &&
boolean checkAlgorithm( String encryptMethod, int keyLength ) {
Cipher cipher = Cipher.getInstance(encryptMethod);
int maxLength = cipher.getMaxAllowedKeyLength(encryptMethod);
if ( keyLength <= maxLength && SOMETHING_ELSE ) {
return true;
} else {
return false;
}
}
布尔校验算法(字符串加密方法,int-keylegth){
Cipher Cipher=Cipher.getInstance(encryptMethod);
int maxLength=cipher.getMaxAllowedKeyLength(encryptMethod);
如果(keyLength是,当然可以循环使用它们,但是Java没有一个属性(像C#/.NET那样)来返回密码“服务”的所有可能的密钥大小
由于密钥大小通常由标准定义(例如,AES和所有AES候选密钥的128、192和256位),因此在应用程序代码中设置它们为常量相对容易
通常情况下,您不希望动态设置密钥大小。但是,是的,您无法获取此信息(现在添加此信息可能会破坏所有提供程序实现)是令人恼火的
getMaxAllowedKeyLength
不应用于此操作。安装无限制加密扩展时(针对此特定运行时),它将返回Integer.MAX\u值。请注意,它是一个静态方法,因此从对象实例调用它也不正确,只需在需要时使用Cipher.getMaxAllowedKeyLength
如果您想找到答案,只需尝试对称密码的所有密钥大小(从16字节到32字节或64字节)。必须支持的密码和密钥大小列在类本身中(一直到底部)
好的,如果你想试试这个:
package nl.owlstead.stackoverflow;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class FindKeySizes {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
Set<Service> services = provider.getServices();
for (Service service : services) {
if (!service.getType().equalsIgnoreCase("cipher")) {
continue;
}
String alg = service.getAlgorithm();
KeyGenerator skf = null;
Cipher cipher;
try {
// filters out symmetric algorithms
skf = KeyGenerator.getInstance(alg, provider);
} catch (NoSuchAlgorithmException e) {
// OK, that may not exist
}
try {
cipher = Cipher.getInstance(alg, provider);
} catch (NoSuchAlgorithmException e) {
continue;
}
SortedSet<Integer> keySizes = new TreeSet<>();
for (int keySize = Byte.SIZE; keySize <= 512; keySize += Byte.SIZE) {
try {
SecretKey key;
if (skf != null) {
try {
skf.init(keySize);
key = skf.generateKey();
} catch (Exception e) {
continue;
}
} else {
key = new SecretKeySpec(new byte[keySize / Byte.SIZE], alg);
}
cipher.init(Cipher.ENCRYPT_MODE, key);
keySizes.add(keySize);
} catch (Exception e) {
// needed for RuntimeException from providers
if (alg.equalsIgnoreCase("AES") && (keySize == 128)) {
e.printStackTrace(System.err);
}
continue;
}
}
if (!keySizes.isEmpty()) {
System.out.printf("Provider: %s, cipher: %s, key sizes: %s%n",
provider.getName(), alg, keySizes);
}
}
}
}
}
包nl.owlstead.stackoverflow;
导入java.security.NoSuchAlgorithmException;
导入java.security.Provider;
导入java.security.Provider.Service;
导入java.security.security;
导入java.util.Set;
导入java.util.SortedSet;
导入java.util.TreeSet;
导入javax.crypto.Cipher;
导入javax.crypto.KeyGenerator;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.SecretKeySpec;
导入org.bouncycastle.jce.provider.BouncyCastleProvider;
公共类FindKeySize{
公共静态void main(字符串[]args)引发异常{
addProvider(新的BouncyCastleProvider());
Provider[]providers=Security.getProviders();
对于(提供程序:提供程序){
Set services=provider.getServices();
用于(服务:服务){
if(!service.getType().equalsIgnoreCase(“密码”)){
继续;
}
字符串alg=service.getAlgorithm();
KeyGenerator skf=null;
密码;
试一试{
//过滤掉对称算法
skf=KeyGenerator.getInstance(alg,提供者);
}捕获(无算法异常){
//好吧,那可能不存在
}
试一试{
cipher=cipher.getInstance(alg,提供者);
}捕获(无算法异常){
继续;
}
SortedSet keySizes=新树集();
for(int keySize=Byte.SIZE;keySize感谢您的回复。我真的很难过这是不可能的。无论如何,我做得非常相似,但另一方面。我只是在传递密钥(可能受密码支持)进入密码并检查异常,如果没有抛出表示密钥有效的密钥。请注意,有许多密码接受非常高和非常低的密钥大小,增量为8位。这提供了一个想法,如果您尝试使用动态密钥大小,会发生什么情况。通常使用一个算法/密钥大小参数或创建一组在您的协议/应用程序中具有相应密钥大小的算法。我实际上正在开发一个加密工具,我希望为用户定义自己的算法,该方法应检查用户输入是否有效。也许我应该生成参数长度的密钥,并尝试加密指定的字符串(“例如测试”)然后只需检查新字符串是否等于(“Test”),如果不等于(“Test”),则算法存在。只是想…要使用密码,您必须创建一个签名提供程序。因此,无论如何,您最好使用自己的API(或Bouncy Castle轻量级API,而不是包含此功能的API)。您需要自己创建私钥并从Oracle获得证书(!).这可能需要几个月如果他们决定给你一个。。。
package nl.owlstead.stackoverflow;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Provider.Service;
import java.security.Security;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class FindKeySizes {
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Provider[] providers = Security.getProviders();
for (Provider provider : providers) {
Set<Service> services = provider.getServices();
for (Service service : services) {
if (!service.getType().equalsIgnoreCase("cipher")) {
continue;
}
String alg = service.getAlgorithm();
KeyGenerator skf = null;
Cipher cipher;
try {
// filters out symmetric algorithms
skf = KeyGenerator.getInstance(alg, provider);
} catch (NoSuchAlgorithmException e) {
// OK, that may not exist
}
try {
cipher = Cipher.getInstance(alg, provider);
} catch (NoSuchAlgorithmException e) {
continue;
}
SortedSet<Integer> keySizes = new TreeSet<>();
for (int keySize = Byte.SIZE; keySize <= 512; keySize += Byte.SIZE) {
try {
SecretKey key;
if (skf != null) {
try {
skf.init(keySize);
key = skf.generateKey();
} catch (Exception e) {
continue;
}
} else {
key = new SecretKeySpec(new byte[keySize / Byte.SIZE], alg);
}
cipher.init(Cipher.ENCRYPT_MODE, key);
keySizes.add(keySize);
} catch (Exception e) {
// needed for RuntimeException from providers
if (alg.equalsIgnoreCase("AES") && (keySize == 128)) {
e.printStackTrace(System.err);
}
continue;
}
}
if (!keySizes.isEmpty()) {
System.out.printf("Provider: %s, cipher: %s, key sizes: %s%n",
provider.getName(), alg, keySizes);
}
}
}
}
}