如何查看我的JVM支持哪些算法[加密算法]?

32

我正在使用Jasypt进行加密。这是我的代码:

public class Encryptor {    
    private final static StandardPBEStringEncryptor pbeEncryptor = new StandardPBEStringEncryptor();
    private final static String PASSWORD = "FBL";
    private final static String ALGORITHM = "PBEWithMD5AndTripleDES";

    static{
        pbeEncryptor.setPassword( PASSWORD );
        //pbeEncryptor.setAlgorithm( ALGORITHM );       
    }

    public static String getEncryptedValue( String text ){
        return pbeEncryptor.encrypt( text );
    }

    public static String getDecryptedValue( String text ){
        return pbeEncryptor.decrypt( text );
    }

}

取消注释setAlgorithm这一行会抛出异常:

org.jasypt.exceptions.EncryptionOperationNotPossibleException: 加密发生了异常。可能的原因是您正在使用强加密算法,但在此Java虚拟机中尚未安装Java密码扩展(JCE)无限制强度的治理策略文件。

API文档说:

设置用于加密的算法,比如PBEWithMD5AndDES。

这个算法必须被您的JCE提供者支持(如果您指定了一个,或者默认的JVM提供者如果您没有指定),如果它被支持,您也可以为它指定模式和填充,比如ALGORITHM/MODE/PADDING。

参见:http://www.jasypt.org/api/jasypt/apidocs/org/jasypt/encryption/pbe/StandardPBEStringEncryptor.html#setAlgorithm%28java.lang.String%29

现在,当您注释掉“setAlgorithm”时,它将使用默认的算法[我猜它是md5],并且它将正常工作。这意味着md5由我的JVM支持。现在,如何找出我的JVM支持哪些其他加密算法。

谢谢!

6个回答

44
以下将列出所有的提供商和支持的算法。您正在使用哪个版本的Java?除非您使用的是旧版本,否则JCE应该已经作为标准包含在内了。

以下将列出所有的提供商和支持的算法。您正在使用哪个版本的Java?除非您使用的是旧版本,否则JCE应该已经作为标准包含在内了。

import java.security.Provider;
import java.security.Security;

public class SecurityListings {
    public static void main(String[] args) {
        for (Provider provider : Security.getProviders()) {
            System.out.println("Provider: " + provider.getName());
            for (Provider.Service service : provider.getServices()) {
                System.out.println("  Algorithm: " + service.getAlgorithm());
            }
        }

    }
}

编辑: 你不使用javax.crypto包中的标准内容的原因是什么?

1)使用以下方法生成一个Key

Key key = SecretKeyFactory.getInstance(algorithm).generateSecret(new PBEKeySpec(password.toCharArray()));

2)使用以下内容创建Cipher

cipher = Cipher.getInstance(algorithm);  

3) 使用密钥初始化您的密码

cipher.init(Cipher.ENCRYPT_MODE, key);  

4) 进行加密操作:

byte[] encrypted = cipher.doFinal(data)

4
使用 System.out.println(" " + service); 代替 System.out.println(" Algorithm: " + service.getAlgorithm());,您将能够看到可用的加密级别。例如,以下内容表示支持128位AES加密,但不支持256位AES加密:SunJCE:Cipher.AES - > com.sun.crypto.provider.AESCipher ... SupportedModes = ECB | CBC | PCBC | CTR | CTS | CFB | OFB | CFB8 | CFB16 | CFB24 | CFB32 | CFB40 | CFB48 | CFB56 | CFB64 | OFB8 | OFB16 | OFB24 | OFB32 | OFB40 | OFB48 | OFB56 | OFB64 | CFB72 | CFB80 | CFB88 | CFB96 | CFB104 | CFB112 | CFB120 | CFB128 | OFB72 | OFB80 | OFB88 | OFB96 | OFB104 | OFB112 | OFB120 | OFB128}。 - Gary S. Weaver
代码列出了许多无法使用的算法。这些代码并不是很有帮助。 - Jonas

4
现在,Jasypt命令行工具提供了一个名为listAlgorithms.bat(Windows系统)和listAlgorithms.sh(Linux系统)的脚本来执行此操作。

您可以在此处找到有关如何下载和使用它的说明:http://www.jasypt.org/cli.html#Listing_algorithms


3

2

我尝试了@Qwerky发布的代码,但它并没有太大帮助。我已经添加了最新的BouncyCastle提供者,但得到的结果非常令人困惑。这个更好地展示了提供者、版本、算法类型和名称。

for (Provider provider : Security.getProviders()) {
    System.out.println("Provider: " + provider.getName() + " version: " + provider.getVersion());
    for (Provider.Service service : provider.getServices()) {
        System.out.printf("  Type : %-30s  Algorithm: %-30s\n", service.getType(), service.getAlgorithm());
    }
}

1

Qwerky提出了一个“待定”问题:为什么要使用Jasypt而不是javax.crypto?

嗯,我建议使用Jasypt,因为它对于初学者来说是一种简单的加密方式,并且对于有经验的用户来说高度可配置。

使用Jasypt,您可以在很少了解JCE和密码学的情况下快速开始利用javax.crypto。无论您想管理用户密码还是加密/解密数据,该框架都提供了一个简单的抽象来回答这个问题。

同时,该框架公开了JCE规范的所有可能性,以允许有经验的用户完全控制。

除此之外,Jasypt还提供了许多开箱即用的功能,用于处理存储在数据库中的敏感数据等常见问题。


如果他想问一个问题,他不应该把它放在回答中。这不是一个讨论的主题。 - Michael W

0

使用Java 8及以上版本,

Stream.of(Security.getProviders()).flatMap(mapper -> Stream.of(mapper.getServices())).flatMap(Set::stream)
                .map(Provider.Service::getAlgorithm).distinct().sorted().forEach(System.out::println);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接