3.2.2 Security

Security类的任务就是管理Java程序中所用到的提供者类。Security类是一个终态类,除了它的私有构造方法,其余均为静态方法。


//管理提供者

public final class Security

extends Object


❑方法详述

Security类最主要的工作就是对提供者的管理。

我们可以通过如下方法向系统中追加一个新的提供者:


//将提供者添加到下一个可用位置。在提供者数组尾部追加新的提供者。

public static int addProvider(Provider provider)


或者,我们直接指定这个提供者位于提供者列表中的位置,请看如下方法:


//在指定的位置添加新的提供者。位置计数从1开始。

public static int insertProviderAt(Provider provider, int position)


这里有一个优先使用的问题,也就是说位置与优先级成正比,提供者位置越靠前,优先级越高。

能够向系统添加提供者,就能将其移除系统,可以使用如下方法:


//移除带有指定名称的提供者。其余提供者在提供者数组中的位置将可能上移。

public static void removeProvider(String name)


当然,移除时需要提供提供者的缩写名称,如缩写BC指的是Bouncy Castle提供者。

与移除方法相类似,从系统中获得一个提供者可使用如下方法:


//返回使用指定的名称安装的提供者(如果有)。

public static Provider getProvider(String name)


当然,也可以使用如下方法直接获得全部提供者:


//返回包含所有已安装的提供者的数组(拷贝)。

public static Provider[]getProviders()


在获得全部提供者的前提下,我们也可以对提供者做一些过滤,可使用如下方法:


/返回包含满足指定的选择标准的所有已安装的提供者的数组(拷贝),如果尚未安装此类提供者,则返回null。/

public static Provider[]getProviders(Map<String, String>filter)

/返回包含满足指定的选择标准的所有已安装的提供者的数组(拷贝),如果尚未安装此类提供者,则返回null。/

public static Provider[]getProviders(String filter)


大家对%JDK_HOME%\jre\lib\security\java.security文件中的配置应该还有些印象吧?以下方法可以用来设置该文件的相关配置:


//设置安全属性值。

public static void setProperty(String key, String datum)

//获取安全属性值

public static String getProperty(String key)


要取到java.security文件中security.provider.1对应的值(sun.security.provider.Sun),或者对它进行设置就可以使用上述方法来实现。

除此之外,我们还可以通过下述方法获得指定加密服务所对应的可用算法或类型的名称:

/返回Set视图,这些Set视图中的字符串包含了指定的Java加密服务的所有可用算法或类型的名称(例如,Signature、MessageDigest、Cipher、Mac、KeyStore)。/


public static Set<String>getAlgorithms(String serviceName)


❑实现示例

我们可以通过代码查看当前环境中的安全提供者信息,如代码清单3-1所示:

代码清单3-1 打印当前系统所配置的全部安全提供者


//遍历目前环境中的安全提供者。

for(Provider p:Security.getProviders()){

//打印当前提供者信息。

System.out.println(p);

//遍历提供者Set实体。

for(Map.Entry<Object, Object>entry:p.entrySet()){

//打印提供者键值。

System.out.println("\t"+entry.getKey());

}

}


在上述程序执行后,我们将在控制台中看到以下内容:


SUN version 1.6

Alg.Alias.Signature.SHA1/DSA

Alg.Alias.Signature.1.2.840.10040.4.3

Alg.Alias.Signature.DSS

SecureRandom.SHA1PRNG ImplementedIn

KeyStore.JKS

Alg.Alias.MessageDigest.SHA-1

MessageDigest.SHA

KeyStore.CaseExactJKS

CertStore.com.sun.security.IndexedCollection ImplementedIn

Alg.Alias.Signature.DSA

KeyFactory.DSA ImplementedIn

KeyStore.JKS ImplementedIn

AlgorithmParameters.DSA ImplementedIn

Signature.NONEwithDSA

Alg.Alias.CertificateFactory.X509

CertStore.com.sun.security.IndexedCollection

Provider.id className

Alg.Alias.Signature.SHA-1/DSA

CertificateFactory.X.509 ImplementedIn

Signature.SHA1withDSA KeySize

KeyFactory.DSA

CertPathValidator.PKIX ImplementedIn

Configuration.JavaLoginConfig

Alg.Alias.Signature.OID.1.2.840.10040.4.3

Alg.Alias.KeyFactory.1.2.840.10040.4.1

MessageDigest.MD5 ImplementedIn

Alg.Alias.Signature.RawDSA

Provider.id name

Alg.Alias.AlgorithmParameters.1.2.840.10040.4.1

CertPathBuilder.PKIX ValidationAlgorithm

Policy.JavaPolicy

Alg.Alias.AlgorithmParameters.1.3.14.3.2.12

Alg.Alias.Signature.SHA/DSA

Alg.Alias.KeyPairGenerator.1.3.14.3.2.12

MessageDigest.SHA-384

Signature.SHA1withDSA ImplementedIn

AlgorithmParameterGenerator.DSA

Signature.NONEwithDSA SupportedKeyClasses

MessageDigest.SHA-512

……


在此,本书没有将控制台获得的信息全部展示出来。在Java 5以前,上述提供者的信息还不到1张A4纸,但到了Java 6后,提供者的信息变得相当庞大。如果将上述完整的信息打印到A4纸上,可以密密麻麻地打印出20多页。这同样说明,在Java 6的环境中,对于加密算法的选择有了更广泛的空间。