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);
                }
            }
        }
    }
}