Java——加密/解密相关类(java.security、javax.crypto、javax.net.ssl)

Java加密/解密相关类

1、Java与密码学

1.1、Java安全领域组成部分

Java安全领域总共分为4个部分:

  • JCA(Java Cryptography Architecture,Java加密体系结构):JCA提供基本的加密框架,如证书、数字签名,消息摘要和密钥对产生器。
  • JCE(Java Cryptography Extension,Java加密扩展包):JCE在JCA基础上作了扩展,提供了各种加密算法、消息摘要算法和密钥管理等功能,有关JCE的实现主要在javax.crypto包中。
  • JSSE(Java Secure Socket Extension,Java安全套接字扩展包):JSSE提供了基于SSL(Secure Sockets Layer,安全套接字层)的加密功能。在网络的传输过程中,信息会经过多个主机(很有可能其中一台就被窃听),最终传送给接收者,这是不安全的。这种确保网络通信安全的服务就是由JSSE来提供的。
  • JAAS(Java Authentication and Authentication Service,Java鉴别与安全服务):JAAS提供了在Java平台上进行用户身份鉴别的功能。

JCA和JCE是Java平台提供的用于安全和加密服务的两组API。它们并不执行任何算法,它们只是连接应用和实际算法实现程序的一组接口。软件开发商可以根据JCE接口(又称安全提供者接口)将各种算法实现后,打包成一个Provider(安全提供者),动态地加载到Java运行环境中。

根据美国出口限制规定,JCA可出口(JCA和Sun的一些默认实现包含在Java发行版中),但JCE对部分国家是限制出口的。因此,要实现一个完整的安全结构,就需要一个或多个第三方厂商提供的JCE产品,称为安全提供者。BouncyCastle JCE就是其中的一个安全提供者。

安全提供者是承担特定安全机制实现的第三方。有些提供者是完全免费的,而另一些提供者则需要付费。提供安全提供者的公司有Sun、Bouncy Castle等,Sun提供了如何开发安全提供者的细节。Bouncy Castle提供了可以在J2ME/J2EE/J2SE平台得到支持的API,而且BouncyCastle的API是免费的。

JDK1.4版本及其后续版本中包含了上述扩展包,无须进行配置。在此之前,安装JDK后需要对上述扩展包进行相应配置。

1.2、安全提供者体系结构

Java安全体系结构通过扩展的方式,加入了更多的算法实现及相应的安全机制。我们把这些提供者称为安全提供者(以下简称“提供者”)。以下内容是JDK1.7所提供的安全提供者的配置信息。

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio,SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

上述这些提供者均是Provider类(java.security.Provider)的子类。其中sun.security.provider.Sun是基本安全提供者,sun.security.rsa.SunRsaSign是实现RSA算法的提供者。
与上一版本对比,Java7新增了EC算法安全提供者
sun.security.ec.SunEC

Java安全体系不仅支持来自Sun官方提供的安全提供者,同时也可配置第三方安全提供者以扩展相应的算法实现等。

安全提供者实现了两个概念的抽象:引擎算法

  • 引擎可以理解为操作,如加密、解密等。
  • 算法则定义了操作如何执行,如一个算法可以理解为一个引擎的具体实现。当然,一个算法可以有多种实现方式,这就意味着同一个算法可能与多个引擎的具体实现相对应。

安全提供者接口的目的就是提供一个简单的机制,从而可以很方便地改变或替换算法及其实现。在实际开发中,程序员只需要用引擎类实现特定的操作,而不需要关心实际进行运算的类是哪一个。

Provider类和Security类(java.security.Security)共同构成了安全提供者的概念。

2、java.security包详解

java.security包为安全框架提供类和接口。通过该包中的Java实现,仅能完成消息摘要算法的实现(消息摘要处理的MessageDigest、DigestInputStream和DigestOutputStream类),并且其源代码是可见的。而
要实现真正的加密与解密,需要参考javax.crypto包中的内容。当然,这个包中的源代码内容是不可见的。

2.1、Provider类

public abstract class Provider extends Properties

Provider类可能实现的服务包括:

  • 算法(如DSA、RSA、MD5或SHA-1)
  • 密钥的生成、转换和管理设施(如用于特定与算法的密钥)。每个提供者都有一个名称和一个版本号,并且在它每次装入运行时中进行配置
  • 方法详情。

在实际开发中,很少会直接使用Provider类,通常使用的是以下几种方法:

//返回提供者名称,例如SunRsaSign
public String getName()
//返回提供者版本号,例如1.5
public double getVersion()
//返回提供者的信息串,例如Sun RSA signature provider
public String getInfofo()
//输出提供者信息
public String toString()

Provider类继承于Properties类,并覆盖了Properties类的几种常用方法。

线程安全的:

//从输入流中读取属性列表
public synchronized void load(InputStream inStream) throws IOException 
//设置键属性
public synchronized Object put(Object key, Object value)
//将指定Map中的所有映射关系添加到Provider中
public synchronized void putAll(Map<?,?> t)
//返回EntrySet视图
public synchronized Set<Map.Entry<Object,Object>> entrySet()
//移除属性
public synchronized Object remove(Object key)
//清除此提供者,使其不再包含用来查找由该提供者实现的设施的属性
public synchronized void clear()

非线程安全的:

//获取键对应的值,没有则返回null
public Object get(Object key)
//用指定的键在此属性列表中搜索属性
public String getProperty(String key)
//返回枚举
public Enumeration<Object> keys() 
public Enumeration<Object> elements()
//返回Set视图
public Set<Object> keySet()
public Collection<Object> values()

自Java5开始,Provider类中加入了内部类——Service类。Service类封装了服务的属性,并提供一个用于获得该服务的实现实例的工厂方法。以下为Provider类对Service类的调用支持:

//安全服务的描述
public static class Provider.Service
//获取描述此算法或别名的指定类型的此提供者实现的服务
pblic synchronized Provider.Service getService(String type, String, algorithm)
//获取此提供者支持的所有服务的一个不可修改的Set
public synchronized Set<Provider.Service> getServices()

查看Java8的环境中的提供者,%JDK_HOME%/jre/lib/security/java.security文件:

security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=apple.security.AppleProvider

如果需要添加提供者,这需要按照security.provider.<n>=<className>方式配置即可。

2.2、Security类

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

public final class Security

常用方法:

//添加一个提供者到数组末尾
public static int addProvider(Provider provider)
//添加一个提供者到数组指定位置
//这里有一个优先使用的问题,也就是说位置与优先级成正比,提供者位置越靠前,优先级越高。
public static int insertProviderAt(Provider provider, int position)

//移除提供者,参数为提供者的缩写
public static void removeProvider(String name)
//返回指定名称的提供者
public static Provier getProvider(String name)
//获得所有提供者
public static Provider[] getProviders()
for(Provier p: Security.getProviders()) {
	System.out.println(p);
	for(Map.Entry<Object, Object) entry : p.entrySet()) {
		System.out.println("\t" + entry.getKey())
	}
}

2.3、MessageDigest类

MessaeDigest类实现了消息摘要算法,他继承了MessgeDigestSpi类,是Java安全提供者体系结构中最简单的一个引擎类。

public abstract class MessageDigest extends MessageDigestSpi

在Java API的列表中,我们总能看到后缀名带有SPI(Service Provider Interface,服务提供者接口)的类,它们,总是与引擎类形影不离。例如MessageDigestSpi类是MessageDigest类的服务提供者接口。如果要实现自定义的消息摘要算法,则需要提供继承于MessageDigestSpi类的子类实现。MessageDigest类自然是Sun提供给我们的一个很好的用于实现自定义算法的范例。在其他引擎类的实现中(除签名算法类Signature类以外),不再继承相对应的SPI类。

常用方法:

//获得实现指定摘要算法的MessageDigest类实例
//支持MD2,MD5,SHA-1,SHA-256,SHA-384,SHA-512
public static MessageDigest getInstance(String algorithm)
public static MessageDigest getInstance(String algorithm, Provider provider)
public static MessageDigest getInstance(String algorithm, String provider)

//使用指定的字节更新摘要
public void update(byte input)
//只用指定的字节数组更新摘要
public void update(byte[] input)
//根据偏移量更新摘要
public void update(byte[] input, int offset, int len)
//使用缓冲模式更新摘要
public void update(ByteBuffer input)
//完成摘要,在update方法后调用
public byte[] digest()

//如果只需调用一次update方法,可以直接使用带参数的digest
public byte[] digest(byte[] input)
//将消息摘要结果按照指定的偏移量存放在字节数字中
public int digest(byte[] buf, int offset, int len)

//比较两个摘要相等性
public static boolean isEqual(byte[] disgesta, byte[] digestb)

//重置摘要以供再次使用,等同于创建一个新的MessageDigest
public void reset()

//返回摘要以字节为单位的摘要长度
public final int getDigestLength()
//返回算法名称
public final String getAlgorithm()
//返回此信息摘要对象的提供者
public final Provider getProvider()

//返回此信息摘要对象的字符串表示形式
public String toString()
//clone
Object clone()

实现示例:

//待做消息摘要算法的原始信息
byte[] input = "hello".getBytes();
// 初始化MessageDigest对象,使用SHA-1算法
MessageDigest sha = MessageDigest.getInstance("SHA");
//更新摘要信息
sha.update(input);
//获取摘要结果
byte[] output = sha.digest();

MessageDigest、DigestInputStream、DigestOutputStream、Mac均是消息认证技术的引擎类。
MessageDigesta提供核心的诮息摘要实现;DigestInputStream、DigestOutputStream提供以
MessageDigest为核心的消息摘要流实现;Mac提供基于秘密密钥的安全消息摘要实现。Mac与MessageDigest无任何依赖关系。

2.4、DigestInputStream类

通过MessageDigest类,我们实现了消息摘要算法,但是通过字节或字节数组的方式完成摘要操作,使用起来并不是很方便,因此有了消息摘要流,包含消息摘要输入流和消息摘要输出流。

DigestInputStream类继承了FilterInputStream类,可以通过读取输入流的方式完成摘要更新,因此我们称之为消息摘要输入流,在指定的读操作方法内部完成MessageDigest类的update()方法。

public class DigestInputStream extends FilterInputStream

常用方法:

//实例化
public DigestInputStream(InputStream stream, MessageDigest digest) 

//将指定的MessageDigest与此流相关
public void setMessageDigest(MessageDigest digest)

//获取此流对应的MessageDigest对象
public MessageDigest getMessageDigest()

//开启或关闭摘要功能,关闭后就变成普通输入流
public void on(boolean on)

//读取字节并更新消息摘要
public int read() throws IOException

//读入byte数组并更新摘要
public int read(byte[] b, int off, int len) throws IOException

实现示例:

//待做消息摘要算法的原始信息
byte[] input = "hello".getBytes();
// 初始化MessageDigest对象,使用MD5算法
MessageDigest md = MessageDigest.getInstance("MD5");
// 构建DigestInputStream对象
DigestInputStream dis = new DigestInputStream(new ByteArrayInputStream(input), md);
//流输入
dis.read(input, 0, input.length);
//获取摘要结果
byte[] output = dis.getMessageDigest().digest();
//关闭流
dis.close();

2.5、DigestOutputStream类

与DigestInputStream类相对应,DigestOutputStream类继承了FilterOutputStream类,可以通过写人输出流的方式完成摘要更新,因此我们称之为消息摘要输出流,在指定的写操作方法内部完成MessageDigest类的update()方法。

常用方法:

//提供一个输出流,针对虽有通过该流的数据计算出相应的消息摘要
public class DigestOutputStream extends FilterOutputStream

//将指定的MessageDigest与此流相关
public void setMessageDigest(MessageDigest digest)

//获取此流对应的MessageDigest对象
public MessageDigest getMessageDigest()

//开启或关闭摘要功能
public void on(boolean on)

//使用指定的字节更新消息摘要,并将字节写入输出流
public void write(int b)

//使用指定的字节数组更新消息摘要、并将子数组写入输出流
public void write(byte[] b, int off, int len)

实现示例:

//待做消息摘要算法的原始信息
byte[] input = "hello".getBytes();
// 初始化MessageDigest对象,使用MD5算法
MessageDigest md = MessageDigest.getInstance("MD5");
// 构建DigestInputStream对象
DigestOutputStream dos = new DigestOutputStream(new ByteArrayOutputStream(), md);
//流输出
dos.write(input, 0, input.length);
//获取摘要结果
byte[] output = dos.getMessageDigest().digest();
//清空流
dos.flush();
//关闭流
dos.close();

2.6、Key接口

Key接口是所有密钥接口的顶层接口,一切与加密解密有关的操作都离不开Key接口。

public interface Key extends java.io.Serializable

所有的密钥都具有三个特征:

  • 算法:这里指的是密钥的算法,如DES和DSA等,通过getAlgorithm()方法可获得算法名
  • 编码形式:这里指的是密钥的外部编码形式,密钥根据标准格式(如X.509、SubjectPublicKeyInfo或PKCS#8)编码,使用getEncoded()可获得编码格式
  • 格式:这里指的是已编码密钥的格式的名称,使用getFormat()方法可获得格式
//返回此密钥的标准算法名称
public String getAlgorithm()

//返回基本编码格式的密钥,通常为二进制格式,如果此密钥不支持编码,则返回null
public byte[] getEncoded()

//返回此密钥的基本编码格式,如果此密钥不支持编码,则返回null
public String getFormat()

SecretKey、PublicKey、PrivateKey三大接口继承于Key接口,定义了对称密钥和非对称密钥接口。

1)、SecretKey

SecretKey(javax.crypto.SecretKey)接口是对称密钥J顶层接口。DES、AES等多种对称密码算法密钥均可通过该接口提供,PBE(javax.crypto.interfaces.PBE)接口提供PEB算法定义并继承了该接口。Mac算法实现过程中,通过SecretKey接口提供秘密密钥。通常使用的是SecretKey接口的实现类SecretKeySpec(javax.crypto.spec.SecretKeySpec)。

public interface SecretKey extends Key, Destroyable
2)、PublicKey和PrivateKey

PublicKey、PrivateKey接口是非对称密钥顶层接口。

public interface PublicKey extends Key

public interface PrivateKey extends Key, javax.security.auth.Destroyable

DH、RSA、DSA和EC等多种非对称密钥接口均继承了这两个接口。RSA、DSA、EC接口均在java.security.interfaces包中。DH的密钥接口位于javax.crypto.interfaces包中。

2.7、AlgorithmParameters类

AlgorithmParameters类是一个引擎类,它提供密码参数的不透明表示。不透明表示与透明表示的区别在于:

  • 不透明表示:在这种表示中,不可以直接访问各参数域,只能得到与参数集相关联的算法名及该参数集的某类编码。
  • 透明表示:用户可以通过相应的规范类中定义的某个get方法来分别访问每个值。
public class AlgorithmParameters

常用方法:

//使用工厂方法实例化
public static AlgorithmParameters getInstance(String algorithm) throws NoSuchAlgorithmException

//指定提供者
public static AlgorithmParameters getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException

public static AlgorithmParameters getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException

//使用在paramSpec中指定的参数初始化此AlgorithmParameters对象
//AlgorithmParameters对象只能被初始化一次,无法重用
public final void init(AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException

//根据参数的基本编码格式导入指定的参数字节数组并对其解码
public final void init(byte[] params) throws IOException

//根据指定的解码方案从参数字节数组导入参数并对其解码
public final void init(byte[] params, String format) throws IOException

//返回此参数对象的(透明)规范
public final <T extends AlgorithmParameterSpec> T getParameterSpec(Class<T> paramSpec) throws InvalidParameterSpecException

//返回基本编码格式的参数
public final byte[] getEncoded()

//返回以指定方案编码的参数
public final byte[] getEncoded(String format)

//返回此参数对象关联的算法的名称
public final String getAlgorithm()

//返回此参数对象的提供者
public final Provider getProvider()

//返回描述参数的格式化字符串
public final String toString()

实现示例:

//实例化AlgorithmParameters,并指定DES算法
AlgorithmParameters ap = AlgorithmParameters.getInstance("DES");
//使用BigInteger生成参数字节数组
ap.init(new BigInteger("19050619766489163472469").toByteArray());
//获得参数字节数组
byte[] b = ap.getEncoded();
//打印经过BigInteger处理后的字符串,将会得到与19050619766489163472469相同的字符串
System.out.println(new BigInteger(b).toString());

字符串19050619766489163472469是通过AlgorithmParameterGenerator类操作得到的,并不是随意填写的一个数值。

2.8、AlgorithmParameterGenerator类

AlgorithmParameterGenerator类用于生成将在某个特定算法中使用的参数集合,可以把它成为算法参数生成器,同样是一个引擎类。

public class AlgorithmParameterGenerator

常用方法:

//返回生成与指定算法一起使用的参数集的AlgorithmParameterGenerator对象
public static AlgorithmParameterGenerator getInstance(String algorithm)

//实例化时指定提供者
public static AlgorithmParameterGenerator getInstance(String algorithm, String provider)

public static AlgorithmParameterGenerator getInstance(String algorithm, Provider provider)

算法生成器共有两种初始化方式:与算法无关的方式或特定于算法的方式。

  • 与算法无关的初始化:所有参数生成器都共享“大小”概念和一个随机源。AlgorithmParameterGenerator类提供了两个init方法,均包含参数int size,另一个方法则要求提供SecureRandom参数。使用这一方法时,特定于算法的参数生成值(如果有)默认为某些标准值,除非它们可以从指定大小派生。
  • 特定于算法的初始化:使用特定于算法的语义初始化参数生成器对象,这些语义由特定于算法的参数生成值集合表示。有两个initialize()方法具有AlgorithmParameterSpec参数,其中一个方法还有一个
    SecureRandom参数,而另一个方法使用以最高优先级安装的提供者的SecureRandom实现作为随机源。(如果任何安装的提供者都不提供SecureRandom的实现,则使用系统提供的随机源。)
//与算法无关的初始化方法
public final void init(int size)
public final void init(int size, SecureRandom random)

//特定于算法的初始化方法
public final void init(AlgorithmParameterSpec genParamSpec)
public final void init(AlgorithmParameterSpec genParamSpec, SecureRandom random)

//生成算法参数对象
public final AlgorithmParameters generateParameters()

//返回与此参数生成器关联的算法的标准名称
public final String getAlgorithm()

//返回此算法参数生成器对象的提供者
public final Provider getProvider()

实现示例:

//实例化AlgorithmParameterGenerator,并指定DSA算法
AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DSA");
//初始化
apg.init(512);
//生成算法参数对象
AlgorithmParameters ap = apg.generateParameters();
//获得参数字节数组
byte[] b = ap.getEncoded();
//打印
System.out.println(new BigInteger(b).toString());

当使用Java提供的加密组件时,很少会用到AlgorithmParameters和AlgorithmParameterGenerator两个类,当对算法参数要求极为严格的情况下才会考虑使用这种方式。

2.9、KeyPair类

KeyPair类是非对称密钥的扩展,它是密钥对的载体,可以叫做密钥对。

public final class KeyPair implements java.io.Serializable

KeyPair类包含两个信息:公钥和私钥。KeyPair通常由KeyPairGenerator的generateKeyPair()方法来提供。

//根据给定的公钥和私钥构造KeyPair对象
public KeyPair(PublicKey publicKey, PrivateKey privateKey)

//返回此密钥对的公钥
public PublicKey getPublic()

//返回此密钥对的私钥
public PrivateKey getPrivate()

2.10、KeyPairGenerator类

公钥和私钥的生成是由KeyPairGenerator类来实现的,称为密钥对生成器,同样是一个引擎类。

public abstract class KeyPairGenerator extends KeyPairGeneratorSpi

在Java7中,提供了DH、ECDH、ECDSA、DSA和RSA等多种非对称加密算法或签名算法实现。

常用方法:

//返回生成指定算法的公钥/私钥密钥对的实例
public static KeyPairGenerator getInstance(String algorithm)

//指定提供者
public static KeyPairGenerator getInstance(String algorithm, String provider)

public static KeyPairGenerator getInstance(String algorithm, Provider provider) 

密钥对生成器共有两种初始化方式:与算法无关的方式和特定于算法的方式,这一点类似于算法参数生成器:

  • 与算法无关的初始化:所有的密钥对生成器遵循密钥大小和随机源的概念。KeyPairGenerator类提供了两个initialize()方法,这两个方法都含有密钥大小参数,另一个
    方法还要求提供SecureRandom参数。
  • 特定于算法的初始化:对于特定于算法的参数集合已存在的情况(例如,DSA中所谓的公用参数),KeyPairGenerator类提供了两个initialize()方法,都具有AlgorithmParameterSpec参数。其中一个方法还有一个SecureRandom参数,而另一个方法使用以最高优先级安装的提供者的SecureRandom实现作为随机源。(如果任何安装的提供者都不提供SecureRandom的实现,则使用系统提供的随机源。)
//与算法无关的初始化方法
public void initialize(int keysize)
public void initialize(iint keysize, SecureRandom random)


//特定于算法的初始化方法
public void initialize(AlgorithmParameterSpec params)
public void initialize(AlgorithmParameterSpec params, SecureRandom random)

//生成一个KeyPair
public KeyPair generateKeyPair()
public final KeyPair generateKeyPair()

//返回关联的算法的标准名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

//实例化密钥对
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
//初始化
kpg.initialize(1024);
//生成密钥对
KeyPair keyPair = kpg.genKeyPair();

2.11、KeyFactory类

KeyFactory类也是用来生成密钥(公钥和私钥)的引擎类,我们将它称为密钥工厂,它用来生成公钥/私钥,或者说它的作用是通过密钥规范还原密钥。与KeyFactory类相对应的类是SecretKeyFactory类,这个类用于生成秘密密钥。

public class KeyFactory

常用方法

//实例化KeyFacotry
public static KeyFactory getInstance(String algorithm)

//指定提供者
public static KeyFactory getInstance(String algorithm, String provider)

public static KeyFactory getInstance(String algorithm, Provider provider)

//根据提供的密钥规范(密钥材料)生成PublicKey对象
public final PublicKey generatePublic(KeySpec keySpec)

//根据提供的密钥规范(密钥材料)生成PrivateKey对象
public final PrivateKey generatePrivate(KeySpec keySpec)

//返回给定密钥对象的规范(密钥材料)
public final <T extends KeySpec> T getKeySpec(Key key, Class<T> keySpec)

//将提供者可能未知或不收信任的密钥对想转换成此密钥工厂对应的密钥材料
public final Key translateKey(Key key)

//返回关联的算法的标准名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

//实例化KeyPairGeneratoer对象,并指定RSA算法
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
//初始化
keyPairGenerator.initialize(1024);
//生成对象
KeyPair keyPair = keyPairGenerator.genKeyPair();
//获得私钥字节数组
byte[] keyBytes = keyPair.getPrivate().getEncoded();
//由私钥密钥字节数组获得密钥规范
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
//实例化密钥工厂,并指定RSA算法
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

2.12、SecureRandom类

SecureRandom类继承于Random类(java.util.Random),它起到强加密随机数生成器(Random Number Generator,RNG)的作用,称之为安全随机数生成器,它同样是一个引擎类。

public class SecureRandom extends java.util.Random

常用方法:

//默认实例化,默认算法为SHA1PRNG
public SecureRandom()

//给定种子,默认随机数算法实例化
public SecureRandom(byte seed[])

//给定算法实例化
public static SecureRandom getInstance(String algorithm)

//指定算法和其提供者
public static SecureRandom getInstance(String algorithm, String provider)

public static SecureRandom getInstance(String algorithm, Provider provider)

//返回给的那个的种子字节数量,该数量可使用此类来将自身设置为种子的种子生成算法来计算
public byte[] generateSeed(int numBytes)

//生成用户指定的随机字节数,其结果将填充在参数byte[] bytes中
public synchronized void nextBytes(byte[] bytes)

//使用给定long seed中包含的8字节,重新设置此随机对象的种子
public void setSeed(long seed)

//重新设置此随机对象的种子
public synchronized void setSeed(byte[] seed)

//返回给定的种子字节数量,该数量可使用此类来将自身设置为种子的种子生成算法来计算
public static byte[] getSeed(int numBytes)

//返回关联的算法的标准名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

//实例化SecureRandom对象
SecureRandom secureRandom = new SecureRandom();
//实例化KeyGenerator对象
KeyGenerator kg = KeyGenerator.getInstance("DES");
//初始化
kg.init(secureRandom);
//生成对象
SecretKey secretKey = kg.generateKey();

SecureRandom类的另一个用途为:在数字签名Signature类中辅助完成初始化操作。

2.13、Signature类

Signature类用来生成和验证数字签名,同样是一个引擎类。

public abstract class Signature extends SignatureSpi

常用方法:

使用Signature对象签名数据或验证签名包括一下三个阶段:

  1. 初始化
    • 初始化验证签名的公钥
    • 初始化签署签名的私钥
  2. 更新:根据初始化类型,可更新要签名或验证的字节
  3. 签署或验证所有更新字节的签名
//指定算法实例化
public static Signature getInstance(String algorithm)

//指定提供者
public static Signature getInstance(String algorithm, String provider)

public static Signature getInstance(String algorithm, Provider provider)

目前,Signature支持NONEwithDSA和SHA1withDSA两种基于DSA算法的签名算法,同时还支持MD2withRSA、MD5withRSA、SHA1withRSA、SHA256withRSA、SHA384withRSA和SHA512 withRSA六种基于RSA算法的签名算法。

//私钥初始化对象,用于签名
public final void initSign(PrivateKey privateKey)
public final void initSign(PrivateKey privateKey, SecureRandom random)

//公钥/证书初始化对象,用于验签
public final void initVerify(PublicKey publicKey)
public final void initVerify(Certificate certificate)

//更新数据
public final void update(byte b)
public final void update(byte[] data)
public final void update(byte[] data, int off, int len)
public final void update(ByteBuffer data)

//返回所有已更新数据的签名字节
public final byte[] sign()

//完成签名操作,并得到存储在缓冲区中的签名字节长度
public final int sign(byte[] outbuf, int offset, int len)

//验证传入的签名,并返回验证结果
public final boolean verify(byte[] signature)

//从指定的偏移量开始,验证指定的字节数组中传入的签名,并返回验证结果
public final boolean verify(byte[] signature, int offset, int length)

//使用指定的参数集初始化此签名引擎
public final void setParameter(String param, Object value)

//返回与此前面那个对象一起使用的参数
public final void setParameter(AlgorithmParameterSpec params)

//返回关联的算法的标准名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

//待做数字签名的原始信息
byte[] data = "Data Signature".getBytes();
//实例化密钥对生成器,并指定DSA算法
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
//初始化
keyPairGenerator.initialize(1024);
//生成密钥对
KeyPair keyPair = keyPairGenerator.genKeyPair();
//实例化Signature
Signature signature = Signature.getInstance(keyPairGenerator.getAlgorithm());
//初始化
signature.initSign(keyPair.getPrivate());
//更新
signature.update(data);
//签名
byte[] sign = signature.sign();

//初始化验证操作
signature.initVerify(keyPair.getPublic());
//更新
signature.update(data);
//验证签名
boolean verify = signature.verify(sign);
System.out.println(verify);

2.14、SignedObject类

SignedObject类是一个用来创建实际运行时对象的类,在检测不到这些对象的情况下,其完整性不会遭受损害。更明确地说,SignedObject包含另外一个Serializable对象,即要签名的对象及其签名,我们可以称之为签名对象。

签名对象是对原始对象的“深层复制”(以序列化形式),一旦生成了副本,对原始对象的进一步操作就不再影响该副本。

public final class SignedObject implements Serializable

常用方法:

//实例化
public SignedObject(Serializable object, PrivateKey signingKey, Signature signingEngine)

//获取已封装的对象
public Object getObject()

//在已签名对象上按字节数组的形式获取签名
public byte[] getSignature()

//使用指派的验证引擎,通过给定的验证密钥验证SignedObject中的签名是否为内存存储对象的有效签名
public boolean verify(PublicKey verificationKey, Signature verificationEngine)

//获取签名算法的名称
String getAlgorithm()

实现示例:

//待做数字签名的原始信息
byte[] data = "Data Signature".getBytes();
//实例化密钥对生成器,并指定DSA算法
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
//初始化
keyPairGenerator.initialize(1024);
//生成密钥对
KeyPair keyPair = keyPairGenerator.genKeyPair();
//实例化Signature
Signature signature = Signature.getInstance(keyPairGenerator.getAlgorithm());
//实例化SignedObject对象
SignedObject s = new SignedObject(data, keyPair.getPrivate(), signature);
//获取签名
byte[] sign = s.getSignature();
//验证签名
boolean verify = s.verify(keyPair.getPublic(), signature);
System.out.println(verify);

2.15、Timestamp类

Timestamp类用于封装有关签署时间戳的信息,且它是不可更改的。它包括时间戳的日期和时间,以及有关生成和签署时间戳的Timestamping Authority(TSA)的信息。为了区别于一般时间戳((java.sql.Timestamp),我们称之为数字时间戳。

public final class Timestamp implements Serializable

常用方法:

//实例化,参数为时间和证书路径
public Timestamp(Date timestamp, CertPath signerCertPath) 

//比较指定的对象和Timestamp对象是否相同
public boolean equals(Object obj)

//返回Timestamping Authority的证书路径
public CertPath getSignerCertPath()

//返回生成数字时间戳的日期和时间
public Date getTimestamp()

//返回此数字时间戳的散列码
public int hashCode()

//返回描述此数字时间戳的字符串
public String toString()

实现示例:

//实例化,证书工厂,指定类型为X.509
CertificateFactory cf = CertificateFactory.getInstance("X509");
//生成CertPath
CertPath cp = cf.generateCertPath(new FileInputStream("0.cer"));
//实例化数字时间戳
Timestamp t = new Timestamp(new Date(), cp);
System.out.println(t);

2.16、CodeSigner类

CodeSigner类封装了代码签名者的信息,且它是不可变的,我们称之为代码签名。它和数字时间戳(java.security.Timestamp)紧密相连。

public final class CodeSigner implements Serializable

常用方法:

//实例化
public CodeSigner(CertPath signerCertPath, Timestamp timestamp)

//返回签名者的CertPath对象
public CertPath getSignerCertPath()

//返回签名时间戳
public Timestamp getTimestamp()

//指定测试对象与CodeSigner对象是否相等
public boolean equals(Object obj)

//返回此代码签名者的散列码
public int hashCode()

//返回描述此代码签名者的字符串
public String toString()

实现示例:

//实例化,证书工厂,指定类型为X.509
CertificateFactory cf = CertificateFactory.getInstance("X509");
//生成CertPath
CertPath cp = cf.generateCertPath(new FileInputStream("0.cer"));
//实例化数字时间戳
Timestamp t = new Timestamp(new Date(), cp);
//实例化代码签名者
CodeSigner cs = new CodeSigner(cp, t);
//获得对比结果
boolean status = cs.equals(new CodeSigner(cp,t));

2.17、KeyStore类

KeyStore类被称为密钥库,用于管理密钥和证书的存储。KeyStore类是个引擎类,它提供一些相当完善的接口来访问和修改密钥仓库中的信息。

public class KeyStore

常用方法:

//根据类型实例化
public static KeyStore getInstance(String type)

//指定该类型的提供者并实例化
public static KeyStore getInstance(String type, String provider)
public static KeyStore getInstance(String type, Provider provider)

//返回默认类型,即jks
public final static String getDefaultType() 

//返回此密钥库的类型
public final String getType()

//从给定输入流中加载此密钥库
public final void load(InputStream stream, char[] password)

//将此密钥库存储到给定输出流,并用给定密钥保护其完整性
public final void store(OutputStream stream, char[] password)

//获取此密钥库中的条目表
public final int size()

//返回密钥库的提供者
public final Provider getProvider()

//返回所有别名
public final Enumeration<String> aliases()

//检查给定别名是否存在于此密钥库中
public final boolean containsAlias(String alias)

//返回与给定别名关联的密钥,并用给定密码来恢复它
public final Key getKey(String alias, char[] password)

//返回与给定别名关联的证书
public final Certificate getCertificate(String alias)

//返回与给定别名关联的证书链
public final Certificate[] getCertificateChain(String alias)

//返回与给定证书匹配的第一个密钥库条目的别名
public final String getCertificateAlias(Certificate cert)

//返回给定别名标识的条目的创建日期
public final Date getCreationDate(String alias)

//根据别名删除条目
public final void deleteEntry(String alias)

//将给定密钥(受保护的)分配给指定的别名
public final void setKeyEntry(String alias, byte[] key,Certificate[] chain)

//将给定的密钥分配给给定的别名,并用给定密码保护它
public final void setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)

//将给定可信证书分配给给定别名
public final void setCertificateEntry(String alias, Certificate cert)

//判断别名对应的是否为证书
public final boolean isCertificateEntry(String alias)

//判断别名对应是否为密钥
public final boolean isKeyEntry(String alias)

内部接口和类:

public static interface KeyStore.Entry

KeyStore管理不同类型的条目。每种类型的条目都实现KeyStore.Entry接口。提供了三种基本的KeyStore.Entry实现:

//保存私钥和相应证书链的密钥库项
public static final class KeyStore.PrivateKeyEntry
//保存秘密密钥的密钥库项
public static final class KeyStore.SecretKeyEntry
//保存可信的证书的密钥库项
public static final class Keystore.TrustedcertificateEntry

实现示例:

//加载密钥库文件
FileInputStream is = new FileInputStream("jks/test.keystore");
//实例化
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
//加载密钥库
ks.load(is, "123456".toCharArray());
//关闭文件流
is.close();

3、javax.crypto包详解

javax.crypto包为加密操作提供类和接口

3.1、Mac类

Mac属于消息摘要的一种,但它不同于一般消息摘要(如MessageDigest提供的消息摘要实现),仅通过输入数据无法获得消息摘要,必须有一个由发送方和接收方共享的秘密密钥才能生成最终的消息摘要一安全消息摘要。安全消息摘要又称消息认证(鉴别)码(Message Authentication Code,Mac)。

在Java7版本中支持HmacMD5、HmacSHA1、HmacSHA256、HmacSHA384和HmacSHA512算法。

public class Mac implements Cloneable

常用方法:

//返回实现指定摘要算法的Mac对象
public final static Mac getInstance(String algorithm)

//指定算法提供者
public final static Mac getInstance(String algorithm, Provider provider)
public final static Mac getInstance(String algorithm, String provider)

//用给定的密钥初始化此Mac
public final void init(Key key)

//用给定的密钥和算法参数初始化此Mac
public final void init(Key key, AlgorithmParameterSpec params)

//使用指定的字节更新摘要
public final void update(byte input)

//使用指定的字节数组更新摘要
public final void update(byte[] input)

//使用指定的字节数组,从指定的偏移量开始更新摘要
public final void update(byte[] input, int offset, int len)

//使用指定的字节缓冲更新摘要
public final void update(ByteBuffer input)

//完成摘要操作
public final byte[] doFinal()

//使用指定的字节数组对摘要进行最后更新,然后完成摘要计算,返回消息摘要字节数组
public final byte[] doFinal(byte[] input)

//完成摘要操作,按指定的偏移量将摘要信息保存在字节数组中
public final void doFinal(byte[] output, int outOffset)

//重置摘要算法以供再次使用
public final void reset()

//返回以字节为单位的摘要成都,如果提供者不支持此操作并且实现是不可复制的,则返回0
public final int getMacLength()

//返回算法名称,如HmacMD5
public final String getAlgorithm()

//返回此信息摘要对象的提供者
public final Provider getProvider()

实现示例:

//待做安全消息摘要的原始信息
byte[] input = "MAC".getBytes();
// 初始化KeyGenerator对象,使用HmacMD5算法
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
//构建SecretKey
SecretKey secretKey = keyGenerator.generateKey();
//构建Mac对象
Mac mac = Mac.getInstance(secretKey.getAlgorithm());
//初始化Mac对象
mac.init(secretKey);
//获得经过安全消息摘要后的信息
byte[] output = mac.doFinal(input);

3.2、KeyGenerator类

KeyGenerator类与KeyPairGenerator类相似,KeyGenerator类用来生成秘密密钥,称之为秘密密钥生成器。

public class KeyGenerator

Java7版本中提供了Blowfish、AES、DES和DESede等多种对称加密算法实现,以及HmacMD5、HmacSHA1和HmacSHA256等多种安全消息摘要算法实现。

//返回生成指定算法的秘密密钥的KeyGenerator对象
public final static KeyGenerator getInstance(String algorithm)

//指定提供者
public final static KeyGenerator getInstance(String algorithm, Provider provider)
public final static KeyGenerator getInstance(String algorithm, String provider)

KeyGenerator对象可重复使用,也就是说,在生成密钥后,可以重复使用同一个KeyGenerator对象来生成更多的密钥。

生成密钥的方式有两种:与算法无关的方式和特定于算法的方式。这一点与KeyPairGenerator类生成密钥方式相类似。两者之间的唯一不同是对象的初始化:

  • 与算法无关的初始化:所有密钥生成器都具有密钥大小和随机源的概念。KeyGenerator类中有一个init()方法,它带有这两个通用共享类型的参数。还有一个只带有keysize参数的init()方法,它使用具有最高优先级的已安装提供者的SecureRandom实现作为随机源(如果已安装的提供者都不提供SecureRandom实现,则使用系统提供的随机源)。
    KeyGenerator类还提供一个只带随机源参数的init)方法。因为调用上述与算法无关的init()方法时未指定其他参数,所以由提供者决定如何处理要与每个密钥关联的特定于算法的参数(如果有)。
  • 特定于算法的初始化:在已经存在特定于算法的参数集的情况下,有两个带AlgorithmParameterSpec参数的init()方法。其中一个方法还有一个SecureRandom参数,而另一个方法将具有高优先级的已安装提供者的SecureRandom实现作为随机源(如果安装的提供者都不提供SecureRandom实现,则使用系统提供的随机源)。
    如果客户端没有显式地初始化KeyGenerator(通过调用init()方法),那么每个提供者都必须提供(并记录)默认初始化。
//与算法无关嗯初始化方法
public final void init(SecureRanom random)
public final void init(int keysize)
public final void init(int keysize, SecureRanom random)

//特定与算法的初始化方法
public final void init(AlgorithmParameterSpec params)
public final void init(AlgorithmParameterSpec params, SecureRandom random)

//生成一个密钥
public final SecretKey generateKey()

//返回算法名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

// 初始化KeyGenerator对象,使用HmacMD5算法
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
//构建SecretKey
SecretKey secretKey = keyGenerator.generateKey();
//构建Mac对象
Mac mac = Mac.getInstance(secretKey.getAlgorithm());

3.3、KeyAgreement类

KeyAgreement类提供密钥协定协议的功能,它同样是一个引擎类。我们称它为密钥协定,将在DH算法实现中使用到它。

public class KeyAgreement

常用方法:

//返回生成指定算法的秘密密钥的KeyAgreement对象
public final static KeyAgreement getInstance(String algorithm)

//指定提供者
public final static KeyAgreement getInstance(String algorithm, Provider provider)
public final static KeyAgreement getInstance(String algorithm, String provider)

//用给定密钥初始化
public void init(Key key)
public void init(Key key, AlgorithmPaamterSpec params)
public void init(Key key, AlgorithmPaamterSpec params, ScureRandom random)
public void init(Key key, SecureRandom random)

//用给定的密钥执行KeyAgreement的下一个阶段,给定密钥是从密钥协定所涉及的其他某个参与者那里接受的
public Key doPhase(Key key, boolean lastPhase)

//生成共享密钥并在新的缓冲区中返回它
public byte[] generateSecret()

//生成共享密钥,并将其放入缓冲区sharedSecret,从offset(包括)开始
public byte[] generateSecret(byte[] sharedSecret, int offset)

//创建共享秘密密钥并将其作为指定算法的SecretKey对象
public SecretKey generateSecret(Stirng alorithm)

//返回算法名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

//实例化KeyPairGenerator对象,并指定DH算法
KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
//生成KeyPair对象kp1
KeyPair kp1 = kpg.genKeyPair();
//生成KeyPair对象kp2
KeyPair kp2 = kpg.genKeyPair();
//实例化KeyAgreement对象
KeyAgreement keyAgree = KeyAgreement.getInstance(kpg.getAlgorithm());
//初始化
keyAgree.init(kp2.getPrivate());
//执行计划
keyAgree.doPhase(kp1.getPublic(), true);
//生成SecretKey对象
SecretKey secretKey = keyAgree.generateSecret("AES");

3.4、SecretKeyFactory类

SecretKeyFactory类同样属于引擎类,与KeyFactory类相对应,它用于产生秘密密钥,我们称之为秘密密钥工厂。

public class SecretKeyFactory

常用方法:

//返回生成指定算法的秘密密钥的SecretKeyFactory对象
public final static SecretKeyFactory getInstance(String algorithm)

//指定提供者
public final static SecretKeyFactory getInstance(String algorithm, Provider provider)
public final static SecretKeyFactory getInstance(String algorithm, String provider)

//根据提供的密钥规范(密钥材料)生成SecretKey对象
public final SecretKey generateSecret(KeySpec keySpec)

//将一个密钥对象(其提供者未知或可能不受信任)转换为SecretKeyFactory的响应密钥对象
public final SecretKey translateKey(SecretKey key)

//以输入参数的格式返回给定密钥对象的规范(密钥材料)
public final KeySpec getKeySpec(SecretKey key, Class keySpec)

//返回算法名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

//实例化keyGenerator对象,并指定DES算法
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
//生成SecretKey对象
SecretKey secretKey = keyGenerator.generateKey();
//获得秘密密钥的密钥编码字节数组
byte[] key = secretKey.getEncoded();

//由获得的密钥编码字节数组构建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key);
//实例化SecretKeyFactoy
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
//生成SecretKey对象
SecretKey secretKey1 = keyFactory.generateSecret(dks);

3.5、Cipher类

Cipher类为加密和解密提供密码功能。它构成了Java Cryptographic Extension(JCE)框架的核心。在本章的上述内容中,只完成了密钥的处理,并未完成加密与解密的操作。这些核心操作需要通过Cipher类来实现。

public class Cipher

常用方法:

//返回实现指定转换的cipher对象
public static Cipher getInsance(String transformatin)
public static Cipher getInsance(String transformatin, Provider provider)
public static Cipher getInsance(String transformatin, String provider)

//用于将Cipher初始化为解密模式的常量
public final static int DECRYPT_MOE

//用于将Ciher初始化为加密模式的常量
public final static int ENCRYPT_MODE

//用密钥初始化此Cipher对象
public final void init(int opmode, Key key)

//密钥和一组算法参数初始化Cipher对象
public final void init(int opmode, Key key, AlorithmParameters params)
public final void init(int opmode, Key key, AlorithmParameters params, SecureRandom random)
public final void init(int opmode, Key key, AlorithmParameterSpec params)
public final void init(int opmode, Key key, AlorithmParameterSpec params, SecureRandom random)

//用密钥和随机源初始化此Cipher对象
public final void init(int opmode, Key key, SecureRandom random)

//用给定证书公钥初始化Cipher
public final void init(int opmode, Certificate certificate)
public final void init(int opmode, Certificate certificate, SecureRandom random)

//继续多部分加密或解密操作,以处理其他数据部分
public final byte[] update(byte[] input, int inputOffset, int inputLen)
public final byte[] update(byte[] input, int inputOffset, int inputLen, byte[] output, int ouputOffset)
public final int update(ByteBuffer input, ByteBuffer output)

//结束多部分加密或解密操作
public final byte[] doFial()

//按单部分操作加密或解密数据,或者结束一个多部分操作
public final byte[] doFinal(byte[] input)
public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)

//以下方式将操作后的结果存与给定的参数中
public final byte[] doFinal(byte[] output, int outputOffset)
public final byte[] doFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)

//基于缓冲的处理方式
public final int doFinal(ByteBuffer input, ByteBuffer output)

//用于将Cipher初始化为密钥包装模式的常量
public final static int WRAP_MODE

//包装密钥
public final byte[] wrap(Key key)

//用于将Cipher初始化为密钥解包模式的常量
public final static int UNWRAP_MODE

//解包密钥
public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKyType)

//用于表示要解包的密钥为“私钥”的常量
public final static int PRIVATE_KEY
//用于表示要解包的密钥为“公钥”的常量
public final static int PUBLIC_KEY
//用于表示要解包的密钥为“秘密密钥”的常量
public final static int SECRET_KEY

//返回新缓冲区中的初始化向量(IV)
public final byte[] getIV()

//根据所安装的JCE仲裁策略文件,返回指定转换最大密钥长度
public final static int getMaxAllowedKeyLength(String transformation)

//返回块的大小,字节为单位
public final int getBlockSize()

//根据给定的输入长度inputLen(以字节为单位),饭hi保存下一个update或doFinal操作结果所需的输出缓冲区长度(以字节为单位)
public final int getOutputSize(int inputLen)

//根据仲裁策略文件,返回包含最大Cipher参数值的AlgorithmParameterSpec对象
public final static AlgorithmParameterSpec getMaxAllowedParameterSpec(String transformation)

//返回此Cipher使用的豁免(exemption)机制对象
public final Provider getProvider()

//返回算法名称
public final String getAlgorithm()

//返回提供者
public final Provider getProvider()

实现示例:

String str ="hello world";
//实例化KeyGenerator对象,并指定DES算法
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
//生成SecretKey
SecretKey secretKey = keyGenerator.generateKey();
//实例化Cipher对象
Cipher cipher = Cipher.getInstance("DES");

//初始化Cipher对象,用于加密操作
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
//加密
byte[] encrypt = cipher.doFinal(str.getBytes());
//初始化Cipher对象,用于解密操作
cipher.init(Cipher.DECRYPT_MODE, secretKey);
//解密
byte[] decrypt = cipher.doFinal(encrypt);
System.out.println(new String(decrypt));

3.6、CipherInputStream类

CipherInputStream和CipherOutputStream同属Cipher类的扩展,统称为密钥流。按流的输入和输出方式分为密钥输入流和密钥输出流。

public class CipherInputStream extends FilterInputStream 

常用方法:

//根据InputStream和Cipher构造CipherInputStream对象
public CipherInputStream(InputStream is, Cipher c)

//从该输入流读取下一数据字节
public int read()
//从该输入流将b.length个数据字节读入到字节数组中
public int read(byte[] b)
//从该输入流将len个字节数据读入到字节数组中
public int read(byte[] b, int off, int len)

//返回不发生阻塞地从此输入流读取的字节数
pubilc int available()

//跳过不发生阻塞地从该输入流读取的字节中的n个字节的输入
public long skip(long n)

//测试该输入流是否支持mark和reset方法以及哪一种方法确实不受支持
public boolean markSupoorted()

//关闭该输入流并释放任何与该流关联的系统资源
public void close()

实现示例:

//实例化KeyGeneratoer对象,并指定DES算法
KeyGenerator kg = KeyGenerator.getInstance("DES");
//生成SecretKey
SecretKey secretKey = kg.generateKey();
//实例化Cipher对象
Cipher cipher = Cipher.getInstance("DES");

//初始化Cipher对象,用于解密操作
cipher.init(Cipher.DECRYPT_MODE, secretKey);
//实例化CipherInputStream对象
CipherInputStream cis = new CipherInputStream(new FileInputStream("a.txt"), cipher);
//使用DataInputStream对象包装CipherInputStream对象
DataInputStream dis = new DataInputStream(cis);
//读出解密后的数据
String output = dis.readUTF();
//关闭流
System.out.println(output);

3.7、CipherOutputStream类

CipherOutputStream类与CipherInputStream类相似,称为密钥输出流。

public class CipherOutputStream extends FilterOutputStream 

常用方法:

//实例化
public CipherOutputStream(OutputStream os, Cipher c)

//从指定的字节数组中将b.length个字节写入此输出
public void write(byte[] b)
//将指定的字节数组中从off偏移量开始的len个字节写入此输出流
public void wriet(byte[] b, int off, int len)
//将指定的字节写入此输出
public void write(int b)

//强制写出已由封装的密码对象处理的任何缓存输出字节来刷新此输出流
public void flush()

//关闭此输出流释放任何与此流关联的系统资源
public void close()

实现示例:

//实例化KeyGeneratoer对象,并指定DES算法
KeyGenerator kg = KeyGenerator.getInstance("DES");
//生成SecretKey
SecretKey secretKey = kg.generateKey();
//实例化Cipher对象
Cipher cipher = Cipher.getInstance("DES");

//初始化Cipher对象,用于加密操作
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
//待加密的原始数据
String input = "1234567890";
//实例化CiherOutputStream对象
CipherOutputStream cos = new CipherOutputStream(new FileOutputStream("a.txt"), cipher);
//使用DataOutputStream对象包装CipherOutputStream
DataOutputStream dos = new DataOutputStream(cos);
//输出
dos.writeUTF(input);
//清空流
dos.flush();
//关闭流
dos.close();

3.8、SealedObject类

SealedObject类使程序员能够用加密算法创建对象并保护其机密性。

public class SealedObject implements Serializable

常用方法:

//从序列化对象构造一个SealedObject
public SealedObject(Serializable object, Cipher c)

在给定任何Serializable对象的情况下,程序员可以序列化格式(即“深层复制”)封装原始对象的SealedObject,并使用类似于DES的加密算法密封(加密)其序列化的内容,以保护其机密性。加密的内容以后可以解密(使用相应的算法和正确的解密密钥)和反序列化,并生成原始对象。

注意,该Cipher对象在应用于SealedObject之前必须使用正确的算法、密钥、填充方案等进行完全初始化。

已密封的原始对象可以用以下两种方式恢复:

  • 使用采用Cipher对象的getObject()方法:此方法需要一个完全初始化的Cipher对象,用相同的用来密封对象的算法、密钥、填充方案等进行初始化。这样做的好处是解封密封对象的一方不需要知道解密密钥。例如,一方用所需的解密密钥初始化Cipher对象之后,它就会将Cipher对象移交给以后要解封密封对象的另一方。
  • 使用采用Key对象的getObject()方法:在此方法中,getObject()方法创建一个用于适当解密算法的Cipher对象,并用给定的解密密钥和存储在密封对象中的算法参数(如果有)对其进行初始化。这样做的好处是解封此对象的一方不需要跟踪用来密封该对象的参数(如IV、初始化向量)。
//获取原始(封装的)对象,采用Cipher对象的方法
public final Object getObject(Cipher c)

//获取原始(封装的)对象,采用Key对象的方法
public final Object getObject(Key key)
public final Object getObject(Key key, String provider)

//返回用于密封此对象的算法
public final String getAlgorithm()

实现示例:

//待加密的字符串对象
String input = "SealedObject";
//实例化KeyGenerator对象,使用DES算法
KeyGenerator kg = KeyGenerator.getInstance("DES");
//创建秘密密钥
SecretKey key = kg.generateKey();
//实例化用于加密的Cipher对象cipher1
Cipher cipher1 = Cipher.getInstance(key.getAlgorithm());
//初始化
cipher1.init(Cipher.ENCRYPT_MODE, key);
//构建SealedObject对象
SealedObject sealedObject = new SealedObject(input, cipher1);
//实例化用于解密的Cipher对象cipher2
Cipher cipher2 = Cipher.getInstance(key.getAlgorithm());
//初始化
cipher2.init(Cipher.DECRYPT_MODE, key);
//获得解密后的字符串对象
String output = (String) sealedObject.getObject(cipher2);
System.out.println(output);

4、java.security.spec包和javax.crypto.spec包详解

java.security.spec包和javax.crypto.spec包都提供了密钥规范和算法参数规范的类和接口。获得密钥规范后,我们将有机会还原密钥对象。

4.1、KeySpec和AlgorithmParameterSpec

KeySpec和AlgorithmParameterSpec,是java.security.spec包中两个较为重要的接口。这两个接口本身都是空接口,仅用于将所有参数规范分组,并为其提供类型安全。

1)、KeySpec

此接口不包含任何方法或常量。它仅用于将所有密钥规范分组,并为其提供类型安全。所有密钥规范都必须实现此接口。

public interface KeySpec { }

KeySpec的抽象实现类(EncodedKeySpec)构建了用于构建公钥规范和私钥规范的两个实现(X5O9EncodedKeySpec用于构建公钥规范,PKCS8EncodedKeySpec用于构建私钥规范)。

SecretKeySpec接口是KeySpec的实现类,用于构建秘密密钥规范。

2)、AlgorithmParameterSpec

此接口不包含任何方法或常量。它仅用于将所有参数规范分组,并为其提供类型安全。所有参数规范都必须实现此接口。

public interface AlgorithmParameterSpec { }

AlgorithmParameterSpec接口有很多的子接口和实现类,用于特定于算法的初始化。使用起来也很方便,只需要使用指定参数填充构造方法即可获得一个实例化对象。以DSAParameterSpec为例:

//创建一个具有指定参数值的新的DSAParameterSpec
public DSAParameterSpec(BigInteger p, BigInteger q, BigInteger g)

//返回基数g
public c BigInteger getG()

//返回素数q
public BigInteger getP()

//返回子素数q
public BigIneger getQ()

4.2、EncodedKeySpec类

EncodedKeySpec类用编码格式来表示公钥和私钥,我们称之为编码密钥规范。编码密钥规范的实现子类很多,在这里不一一详述,以最为常用的用于表示公钥和私钥的两个实现类为例。

X509 EncodedKeySpec和PKCS8EncodedKeySpeci两个类均为EncodedKeySpecl的子类,X5O9EncodedKeySpec类用于转换公钥编码密钥,PKCS8EncodedKeySpec类用于转换私钥编码密钥。

public abstract class EncodedKeySpec implements KeySpec
//根据给定的编码密钥创建一个新的编码密钥规范
public EncodedKeySpec(byte[] encodedKey)

//返回编码密钥
public byte[] getEncoded()

//返回与此密钥规范相关联的编码格式的名称
public abstract String getFormat()
1)、X509EncodedKeySpec

X5O9EncodedKeySpec类继承EncodedKeySpec类,以编码格式来表示公钥,X509EncodedKeySpec类使用X.509标准作为密钥规范管理的编码格式,该类的命名由此得来。

public class X509EncodedKeySpec extends EncodedKeySpec

常用方法:

//根据给定的编码密钥创建一个新的X509EncodedKeySpec
public X509EncodedKeySpec(byte[] encodedKey)

//返回按照X.509标准进行编码的密钥的字节
public byte[] getEncoded()

//返回与此密钥规范相关的编码格式的名称。将得到"X.509"
public String getFormat()

实现示例:

//实例化KeyPairGenerator对象,并指定DSA算法
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
//初始化
keyGen.initialize(1024);
//生成KeyPair对象
KeyPair keyPair = keyGen.genKeyPair();
//获得公钥
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
//实例化X509EncodedKeySpec
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
//实例化KeyFactory,并指定DSA算法
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
//获得公钥对象
PublicKey publicKey = keyFactory.generatePublic(keySpec);
2)、PKCS8EncodedKeySpec

PKCSEncodedKeySpec类继承EncodedKeySpec类,以编码格式来表示私钥。PKCS8EncodedKeySpec类使用PKCS#8标准作为密钥规范管理的编码格式,该类的命名由此得来。

public class PKCS8EncodedKeySpec extends EncodedKeySpec

常用方法:

//根据给定的编码密钥创建一个新的PKCS8EncodedKeySpec
public X509EncodedKeySpec(byte[] encodedKey)

//返回按照PKCS#8标准进行编码的密钥的字节
public byte[] getEncoded()

//返回与此密钥规范相关的编码格式的名称。将得到"PKCS#8"
public String getFormat()

实现示例

//实例化KeyPairGenerator对象,并指定DSA算法
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
//初始化
keyGen.initialize(1024);
//生成KeyPair对象
KeyPair keyPair = keyGen.genKeyPair();
//获得私钥
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
//实例化PKCS8EncodedKeySpec
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
//实例化KeyFactory,并指定DSA算法
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
//获得私钥对象
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

4.3、SecretKeySpec类

SecretKeySpec类是KeySpec接口的实现类,用于构建秘密密钥规范。可根据一个字节数组构造一个SecretKey,而无须通过一个(基于provider的)SecretKeyFactory。

public class SecretKeySpec implements KeySpec, SecretKey 

此类仅对能表示为一个字节数组并且没有任何与之相关联的密钥参数的原始密钥有用,如DES或Triple DES密钥。

常用方法:

//根据给定的字节数组构造一个密钥,使用key中的始于且包含offset的前len个字节
public SecretkeySpec(byte[] key, int offset, int len, String algorithm)

//根据给定的字节数组构造一个密钥
public SecretKeySpec(byte[] key, String algorithm)

//测试给定对象与此对象的相等性
public boolean equals(Object obj)

//算此对象的散列码值
public int hashCode()

//返回与此密钥相关联的算法名称
public String getAlgorithm()

//返回此密钥的密钥内容
public byte[] getEncoded()

//返回此密钥拜纳姆格式的名称
public String getFormat()

实现示例:

KeyGenerator kg = KeyGenerator.getInstance("RC2");
SecretKey secretKey = kg.generateKey();
byte[] key = secretKey.getEncoded();
//还原密钥
SecretKey k = new SecretKeySpec(key, "RC2");

4.4、DESKeySec类

DESKeySpec类与SecretKeySpec类都是提供秘密密钥规范的实现类。不同之处在于,DESKeySpec类指定了DES算法,SecretKeySpec类则是兼容所有对称加密算法。

DESKeySpec类有很多的同胞,例如,DESedeKeySpec类提供了三重DES加密算法的密钥规范;PBEKeySpec类提供了PBE算法的密钥规范。我们以DESKeySpec类为代表,对其同胞类做相应说明。

public class DESKeySpec implements KeySpec 

常用方法:

//创建一个DESKeySpec对象,使用key中的前8个字节作为DES-EDE的密钥内容
public DESKeySpec(byte[] key)

//创建一个DESKeySpec对象,使用key中始于且包含offset的前8个字节作为DES-EDE的密钥内容
public DESKeySpec(byte[] key, int offset)

//定义以字节为单位的DES密钥长度的常量(8)
public static int DES_KE_LEN

//返回DES密钥内容
public byte[] getKey()

//确定给定的始于且包含offset的DES密钥内容是否是奇偶校验的(parity-adjusted)
public static boolean isParityAdjusted(byte[] key, int offset)

//确定给定的DES密钥内容是否全弱或者半弱的
public static boolean isWeak(byte[] key, int offset)

实现示例:

//实例化KeyGenerator对象,并指定DES算法
KeyGenerator kg = KeyGenerator.getInstance("DES");
//生成SecretKey对象
SecretKey secretKey = kg.generateKey();
//获得密钥编码字节数组
byte[] key = secretKey.getEncoded();
//还原密钥对象
SecretKey secretKey1 = new SecretKeySpec(key, "DES");

三重DES算法:

KeyGenerator kg = KeyGenerator.getInstance("DESede");
SecretKey secretKey = kg.generateKey();
byte[] key = secretKey.getEncoded();
//还原密钥对象
DESedeKeySpec dks = new DESedeKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
SecretKey secretKey1 = keyFactory.generateSecret(dks);

5、java.security.cert包详解

java.security.cert包提供证书解析和管理、证书撤销列表(CRL)和证书路径的类和接口。作为Java加密与解密实现的扩展。

5.1、Certificate类

Certificate类是一个用于管理证书的抽象类。证书有多种类型,如X.509证书、PGP证书和SDSI证书,并且它们都以不同的方式存储柠溪,但却都可以通过继承Certificate类来实现它们。

public abstract class Certificate implements java.io.Serializable

Certificate类提供3种基本操作,要求子类实现如下各项:

//返回证书的编码形式
public abstract byte[] getEncoded()

//验证是否已使用与指定公钥相应的私钥签署了此证书
public abstract voi verify(PublicKey key)

//验证是否已使用与指定公钥相应的私钥签署了此证书
public abstract void verify(PublicKey key, String sigProvider)

//从证书中获取公钥
public abstract PublicKey getPublicKey()

Certificate要求子类必须实现以下方法:

//返回此证书的字符串表示形式
public abstract String toString()

//返回证书类型
public final String getType()

Certificate类覆盖了以下方法:

//根据此证书的编码形式返回该证书的散列码值
public int hashCode()

//比较此证书与指定对象的相等性
public boolean equals(Object other)

5.2、CertificateFactory类

CertificateFactory类是一个引擎类,我们称之为证书工厂,可以通过它将证书导入程序中。

常用方法:

//返回实现指定证书类型的证书工厂
public static final CertificateFactory getInstance(String type)
public static final CertificateFactory getInstance(String type, String provider)
public static final CertificateFactory getInstance(String type, Provider provider)

//根据输入流中的数据初始化证书
public final Certificate generateCertificate(InputStream inStream)
public final Collection<? extends Certificate> generateCertificates (InputStream inStream) 

//生成证书路径对象
public final CertPath generateCertPath(InputStream inStream)
public final CertPath generateCertPath(InputStream inStream, String encoding)
public final CertPath generateCertPath(List<? extends Certificate> certificates)

//生成证书吊销列表
public final Collection<? extends CRL> generateCRLs(InputStream inStream)

//返回此证书工厂支持的CertPath编码的迭代器,默认编码方式优先
public final Iterator<String> getCertPathEncodeings()

//返回此证书工厂的提供者
public final Provider getProvider()

//返回与此证书工厂相关联的提供者
public final String getType()

实现示例:

//实例化,证书类型为X.509
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//获得输入流
FileInputStream in = new FileInputStream("jks/test.cer");
//获得证书
Certificate certificate = certificateFactory.generateCertificate(in);
//关闭流
in.close();
System.out.println(certificate.getType());

5.3、X509Certificate类

X509Certificate类是Cerfificate类的子类,它同样是一个抽象类。

public abstract class X509Certificate extends Certificate implements X509Extension

常用方法:

//获取证书有效期的notAfter日期
public abstract Date getNoAfter()

//获取证书有效期的notBefore日期
public abstract Date getNotBefore()

//检查给定的日期是否处于证书的有效期内
public abstract void checkValidity(Date date)

//检查证书目前是否有效
public abstract void checkValidity()

//获取证书版本号
public abstract int getVersion()

//获取证书的序列号
public abstract BigInteger getSerialNumber()

//从关键BasicConsttraints扩展(OID = 2.5.29.19)中获取证书的限制路径长度
public abstract int getBasicConstraints()

//获取一个表示KeyUsager扩展的各个位的boolean数组
public abstract boolean[] getKeyUsage()

//获取一个不可修改的String列表,表示已扩展的密钥使用扩展中ExtKeyUsageSyntax字段的对象标识符
public List<String> getExtKeyUsageSyntax()

//从IssureAltName扩展中读取一个发布方替换名称的不可变集合
public Collection<List<?>> getIssuerAlternativeNames()

//获取证书的issuerUniqueID值
public abstract boolean[] getIssuerUniquerID()

//以X500Principal的形式返回证书的发布方值
public X500Principal getIssuerX500Principal()

//从SubjectAltName扩展中获取一个主体替换名称的不可变集合
public Collection<List<?>> getSubjectAlternativeNames()

//获取证书的subjectUiquueID值
public abstract boolean[] getSubjectUniqueID()

//以X500Principal的形式发挥证书的主体值
public X500Principal getSubjectX500Principal()

//从证书中获取以DER编码的证书信息
public abstract byte[] getTBSCertificate()

//获取证书签名算法
public abstract String getSigAlgName()

//获取证书的签名算法OID字符串
public abstract String getSigAlgName()

//从证书的签名算法中获取DER编码形式的签名算法参数
public abstract byte[] getSigAlgParams()

//获取证书的signature值(原始签名)
public abstract byte[] getSignature()

实现示例:

//加载密钥库文件
        FileInputStream is = new FileInputStream("jks/test.keystore");
        //实例化KeyStore
        KeyStore ks = KeyStore.getInstance("JKS");
        //加载密钥库
        ks.load(is, "123456".toCharArray());
        //关闭文件输入流
        X509Certificate x509Certificate = (X509Certificate) ks.getCertificate("test");
        //通过证书的签名算法构建Signature
        Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());

5.4、CRL类

证书可能会由于各种原因失效,如由于申请证书的请求有问题或者用户使用该证书做了非法操作,这时证书将立即被置为无效。将证书置为无效的结果就是产生CL(证书撤销列表)。CA负责发布CRL,CRL中列出了该CA已经撤销的证书。验证证书时,首先需要查询此列表,然后再考虑接受证书的合法性。

CRL类作为证书抽象列表的抽象类,可通过扩展该抽象类定义专门的CRL类型。

public abstract class CRL

其子类必须实现一下方法:

//检查给定的证书是否在CRL中
public abstract boolean isRevoked(Certificate cert)

//返回CRL的字符串表示形式
public abstract String toString()

常用方法:

//返回此CRL的类型
public String getType()

//检查给定的证书是否在CRL中
public abstract boolean isRevoked(Certificate cert)

//返回CRL的字符串表示形式
public abstract String toString()

实现示例:

//实例化,指定类型为X.509
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//输入流
FileInputStream is = new FileInputStream("jks/test.keystore");
//实例化CRL
CRL crl = certificateFactory.generateCRL(is);
//关闭流
is.close();

5.5、X509CRLEntry类

X509CRLEntry类可用于撤销证书。

public abstract class X509CRLEntry implements X509Extension

常用方法:

//比较此CRL项与给定对象的相等性
public boolean equals(Object other)

//根据此CRL项的编码形式返回该CRL项的散列码值
public int hashCode()

//返回CRLEntry的ASN.1 DER编码形式
public abstract byte[] getEncoded()

//获取撤销日期
public abstract Date getRevocationDate()

//获取序列号
public abstract BigInteger getSerialNumber()

//判断CRL是否有扩展
public abstract boolean hasExtensions()

5.6、X509CRL类

X509CRL类作为CRL类的子类,已标明了类型为X.509的CRL。

public abstract class X509CRL extends CRL implements X509Extension

常用方法:

//比较此CRL项与给定对象的相等性
public boolean equals(Object other)

//根据此CRL项的编码形式返回该CRL项的散列码值
public int hashCode()

//获取版本号
public abstract int getVersion()

//返回CRLEntry的ASN.1 DER编码形式
public abstract byte[] getEncoded()

//从CRL中获取以DER编码的CRL信息,即tbsCerList
public abstract byte[] getTBSCertList()

//获取thisUpdate
public abstract Date getThisUpdate()

//获取nextUpdate
public abstract Date getNextUpdate()

//获取CRL签名算法
public abstract String getSigAlgName()

//获取CRL签名算法OID字符串
public abstract String getSigAlgOID()

//获取CRL的签名算法中DER编码形式的签名算法参数
public abstract byte[] getSigAlgParams()

//获取CRL的原始签名
pubilc abstract byte[] getSignature()

//获取具有给定证书serialNumber的CRL项(如果有)
public abstract X509CRLEntry getRevokedCertificate(BigInteger serialNumber)

//获取此CRL中的所有项
public abstrat Set<? extends X509CRLEntry> getRevokedCertificates()

//获取给定证书的CRL(如果有)
public X509CRLEntry getRevokedCertificate(X509Certificate certificate)

//验证是否已使用给定公钥相应的私钥签署此CRL
public abstract void verify(PublicKey key)
public abstract void verify(PublicKey key, String sigProvider)

实现示例:

//实例化,指定类型为X.509
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//输入流
FileInputStream is = new FileInputStream("jks/test.keystore");
//获得证书
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(is);
//获得证书撤销列表
X509CRL x509CRL = (X509CRL) certificateFactory.generateCRL(is);
//获得CRL实体
X509CRLEntry x509CRLEntry = x509CRL.getRevokedCertificate(certificate);
//关闭流
is.close();

5.7、CertPath类

CertPath类是一个抽象类,定义了常用于所有CertPath的方法。其子类可处理不同类型的证书(X.509、PGP等)。

所有CertPath对象都包含类型、Certificate列表及其支持的一种或多种编码。由于CertPath类是不可变的,所以构造CertPath后无法以任何外部可见的方式更改它。此规定适用于此类的所有公共字段和方法,以及由子类添加或重写的所有公共字段和方法。

public abstract class CertPath implements Serializable 

常用方法:

//返回此证书路径中的证书列表
public abstract List<? extends Certificate> getCertificates()

//返回此证书路径的编码形式,使用默认的编码
public abstract byte[] getEncoded()

//返回此证书路径的编码形式,使用指定的编码
public abstract byte[] getEnoded(String encoding)

//返回此证书路径支持的编码的迭代,默认编码方式优先
public abstract Iterator<String> getEncodeings()

//返回此证书路径中的Certificate类型,如X.509
public String getType()

//比较此证书路径与给定对象的相等性
public boolean equals(Object other)

//根据此证书路径的散列码值
public int hashCode()

//返回此证书路径的字符串表示形式
public String toString()

实现示例:

//实例化,指定类型为X.509
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//输入流
FileInputStream is = new FileInputStream("jks/test.keystore");
//获得CertPath对象
CertPath certPath = certificateFactory.generateCertPath(is);
//关闭流
is.close();

6、javax.net.ssl包详解

javax.net.ssl包提供用于安全套接字包的类。

6.1、KeyManagerFactory类

KeyManagerFactory类是一个引擎类,它用来管理密钥,称为密钥管理工厂。

public class KeyManagerFactory 

常用方法:

//根据算法名称初始化
public final static KeyManagerFactory getInstance(String algorithm)
public final static KeyManagerFactory getInstance(String algorithm, Provider provider)
public final static KeyManagerFactory getInstance(String algorithm, String provider)

//获取默认的算法名称
public final static String getDefaultAlgorithm()

//使用密钥内容源初始化此KeyManagFactory
public final void init(KeyStore ks, char[] password)

//是使用特定于提供者的密钥内容初始化此KeyManagerFactory
public final void init(ManagerFactoryParameters spec)

//为每类密钥内容返回一个密钥管理器
public final KeyManager[] getKeyMangers()

//返回提供者
public final Provier getProvider()

//返回算法名称
public final String getAlgorithm()

实现示例:

//实例化KeyManagerFactory对象
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
//加载密钥库文件
FileInputStream is = new FileInputStream("jks/test.keystore");
//实例化KeyStore对象
KeyStore ks = KeyStore.getInstance("JKS");
//加载密钥库
ks.load(is, "123456".toCharArray());
//关闭流
is.close();
//初始化KeyManagerFacotry对象
keyManagerFactory.init(ks, "123456".toCharArray());

6.2、TrustManagerFactory类

TrustManagerFactory类是用于管理信任材料的管理器工厂。

public class TrustManagerFactory

常用方法:

//根据算法实例化
public final statiic TrustManagerFactory getInstance(String alorithm)
public final statiic TrustManagerFactory getInstance(String alorithm, Provider provider)
public final statiic TrustManagerFactory getInstance(String alorithm, String provider)

//获取默认的算法名称
public final static String getDefaultAlgorithm()

//用证书授权源和相关的信任材料初始化工厂
public final void init(KeyStore ks)
public final void init(ManagerFctoryParameters spec)

//为每种信任材料返回一个信任管理器
public final TrustManager[] getTrustManagers()

//返回算法名称
public final String getAlgorithm()

//返回提供者
public final Provider getPr哦vi的人()

实现示例:

//实例化TrustManagerFactory对象
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
//加载密钥库文件
FileInputStream is = new FileInputStream("jks/test.keystore");
//实例化KeyStore对象
KeyStore ks = KeyStore.getInstance("JKS");
//加载密钥库
ks.load(is, "123456".toCharArray());
//关闭流
is.close();
//初始化TrustManagerFactory对象
trustManagerFactory.init(ks);

6.3、SSLContext类

SSLContext类用于表示安全套接字上下文,它同样是一个引擎类。

public class SSLContext

常用方法:

//根据协议实例化
public static SSLContext getInstance(String protocol)
public static SSLContext getInstance(String protocol, Provider provider)
public static SSLContext getInstance(String protocol, String provider)

//初始化此上下文
public c final void init(KeyManager[] km, TrustManager[] tm, SecureRandom random)

//返回此上下文的ServerSocketFactory对象
public final SSLServerSocketFactory getServerSocketFactory()

//返回此上下文的SocketFactory对象
public final SSLSocketFactory getSocketFacory()

//返回服务器会话上下文,它表示可提供服务器端SSL套接字握手阶段使用的SSL会话集
public final SSLSessionContext getServerSessionContext()

//返回客户端会话上下文,它表示可提供客户端SSL套接字握手阶段使用的SSL会话集
public final SSLSessionContext getClientSessionContext()

//使用此上下文创建新的SSLEngine
public final SSlEngine createSSLEngine()

//使用此上下文创建新的SSLEngine,并绑定主机和端口
public final SSLEngine createSSLEngine(String peerHost, int peerPort)

//设置默认的SSL上下文
public synchronized static void setDefault(SSLContext context)

//返回默认的SSL上下文
public synchronized static SSLContext getDefault()

//返回此SSL上下文默认参数
public final SSLParamenters getDefaultSSLParameters()

//返回表示此SSL上下文受支持设置的参数
public final SSLparameters getSupportedSSLParameters()

//返回协议
public final String getProtocol()

//返回提供者
public final Provider getProvider()

实现示例:

/**
 * 支持TLS和SSL协议
 */
public static final String PROTOCOL = "TLS";

/**
 * 获得KeyStore
 * @param keyStorePath 密钥库路径
 * @param password 密码
 * @return KeyStore 密钥库
 * @throws Exception
 */
private static KeyStore getKeyStore(String keyStorePath, String password) throws Exception {
    //实例化密钥库
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    //获得密钥库文件流
    FileInputStream is = new FileInputStream(keyStorePath);
    //加载密钥库
    ks.load(is, password.toCharArray());
    //关闭密钥库文件流
    is.close();
    return ks;
}

/**
 * 获得SSLSocketFactory
 * @param password 密码(密钥库密码与信任库密码可能不同)
 * @param keyStorePath 密钥库路径
 * @param trustStorePath 信任库路径
 * @return SSLSocketFactory
 * @throws Exception
 */
private static SSLSocketFactory getSSLSocketFactory(String password, String keyStorePath, String trustStorePath) throws Exception {
    //实例化密钥工厂
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    //获得密钥库
    KeyStore keyStore = getKeyStore(keyStorePath, password);
    //初始化密钥工厂
    keyManagerFactory.init(keyStore, password.toCharArray());
    //实例化信任库
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    //获得信任库
    KeyStore trustStore = getKeyStore(trustStorePath, password);
    //初始化信任库
    trustManagerFactory.init(trustStore);
    //实例化SSL上下文
    SSLContext ctx = SSLContext.getInstance(PROTOCOL);
    //初始化SSL上下文
    ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
    //获得SSLSocketFactory
    return ctx.getSocketFactory();
}

6.4、HttpsURLConection类

HttpsURLConnection类继承于HttpURLConnection类。从字面上看,两个类仅差一个字母。但在含义上,HttpsURLConnection类比HttpURLConnection类更具安全性。

public abstract class HttpsURLConnection extends HttpURLConnection 

常用方法:

//设置SSLSocketFactory
public void setSSLSocketFactory(SSLSocketFactory sf)
public void setDefaultSSLSocketFactory(SSLSocketFactory sf)

//获得SSLSocketFactory
public SSLSocketFactory getSSLSocketFactory()
public SSLSocketFactory getDefaultSSLSocketFactory()

//获得握手期间发送给服务器的证书链
public abstract Certificate[] getLocalCertificates()

//返回服务器的证书链
public abstract Certificate[] getServerCertificates()

//返回握手期间发送到服务器的主体
public Principal getLocalPrincipal()

//返回服务器的主体
public Principal getPeerPrincipal()

//返回在此连接上使用的密码套件
public abstract String getCipherSuite()

//获取此类的新实例所继承的默认HostnameVerifier
public static HostnameVerifier getDefaultHostnameVerifier()

//获取此实例适当的HostnameVerifier
public HostnameVerifier getHostnameVerifier()

//设置此类的新实例所继承的默认HostnameVerifier
public static void setDefaultHostnameVerifier(HostnameVerifier v)

//设置此实例的HostnameVerifier
public void setHostnameVerifier(HostnameVerifier v)

实现示例:

//构建URL对象
URL url = new URL("https://www.baidu.com");
//获取HttpsURLConnection
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//打开输入模式
conn.setDoInput(true);
//打开输出模式
conn.setDoOutput(true);
//调用前面的getSSLSocketFactory()
//设置
conn.setSSLSocketFactory(getSSLSocketFactory(passord, keyStorePath, trustKeyStorePath));
//获得输入流
InputStream is = conn.getInputStream();
//读取数据
//todo
//关闭流
is.close();

6.5、SSLSession接口

SSLSession接口用于保持SSL协议网络交互会话状态。在SSL的会话中,可以获得加密套件(CipherSuite)、数字证书等。

public interface SSLSession 

加密套件中明确给出了加密参数,具体包括:协议、密钥交换算法、加密算法、工作模式和消息摘要算法。如TLS_RSA_WITH_AES_256_CBC_SHA就是一个完成加密套件信息,它表示:使用TLS协议,密钥交换算法为RSA,对称加密算法为AES(密钥长度256位),使用CBC工作模式,并使用SHA消息摘要算法。

//获得加密套件
public String getCipherSuite()

//获得数字证书
public Certificate[] getPeerCertificates()

//获得X.509协议X.509协议链
public X509Certificate[] get PeerCertificateChain()

6.6、SSLSocketFacoty类

SSLSocketFacoty类可以创建SSLSocket,并可获得响应的加密套件。

public abstract class SSLSocketFactory extends SocketFactory

常用方法:

//获得默认的SocketFactory实例
public static SocketFactory getDefault()

//获得加密套件
public abstract String[] getDefaultCipherSuites()

//获得当前SSL链接可支持的加密套件
public abstract String[] getSupportedCipherSuites()

6.7、SSLSocket类

SSLSocket类是基于SSL协议的Socket。用于设置加密套件、处理握手结束事件,并管理SSLSession。

public abstract class SSLSocket extends Socket

常用方法:

//获得可支持的加密套件
public abstract String[] getSupportedCipherSuites()

//设置可用的加密套件
public abstract void setEnabledCipherSuites(String[] suites)

//获得当前可用的加密套件
public abstract String[] getEnabledCipherSuites()

目前,Java环境中支持的协议有SSLv2 Hello、SSLv3、TLSv1、TLSv1.1和TLSv1.2等。通常默认协议是SSLv3和TLSv1。其实TLS协议就是SSL协议的第3个版本。这两个名称实际上是等价的。通过如下方法可以进行协议变更适配:

//设置可用协议
public abstract void setEnabledProtocols(String[] protocols)

//获得可用协议
public abstract String[] getEnabledProtocols()

//获得支持的协议
public abstract String[] getSupportedProtocols()

//建立握手
public absract void startHandshake()

//获得SSL会话实例
public abstract SSLSession getSession()

实现示例:

public static Certificate[] getCerfifcates(String hostname, int port) throws Exception {
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket socket = (SSLSocket) factory.createSocket(hostname, port);
    //握手
    socket.startHandshake();
    //获得session
    SSLSession session = socket.getSession();
    //关闭Socket
    socket.close();
    //获得证书
    return session.getPeerCertificates();
}

如有必要,可以通过如下代码,输出当前网络下的debug日志:

System.setProperty("javax.net.debug", "all");

6.8、SSLServerSocketFactory类

SSLServerSocketFactory类与SSLSocketFactory类相关操作几乎一致,只是所构建的Socket是SSLServerSocket类。

public abstract class SSLServerSocketFactory extends ServerSocketFactory 

常用方法:

//获得默认实例
public static ServerSocketFactory getDefault()

//获得默认加密套件
public abstract String[] getDefaultCipherSuites()

//获得可支持的加密套件
public abstract String[] getSupportedCipherSuites()

6.9、SSLServerSocket类

SSLServerSocketa类是专用于服务器端的SSLSocket,.是ServerSocket的子类。

public abstract class SSLServerSocket extends ServerSocket

常用方法:

//获得可支持的加密套件
public abstract String[] getSupportedCihperSuites()

//设置可用的加密套件
public abstract void setEnabledCipherSuites(String[] suites)

//获得可用的加密套件
public abstract String[] getEnabledCipherSuites()

//设置可用的协议
public abstract void setEnabledProtocols(String[] protocols)

//获得可用的协议
public abstract String[] getEnabledProtocols()

//获得可支持的协议
public abstract String[] getSupportedProtocols()

实现示例:

//获得SSLServerSocketFactory实例
SSLServerSocketFactory socketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
//构建SSLServerSocket实例
SSLServerSocket serverSocket = (SSLServerSocket) socketFactory.createServerSocket(8888);
//服务器端套接字进入阻塞状态,等待来自客户端的连接请求
SSLSocket socket = (SSLSocket) serverSocket.accept();
//通过Socket获得响应的流对象进行操作
//todo
//关闭Socket
socket.close();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于Java的两个通用安全模块设计与实现如下: 加密模块: 功能描述: 加密模块提供了通用的加密算法和相关功能,用于对数据进行保护和安全传输。 它支持对文本、文件等各种型的数据进行加密,并提供了多种常用的加密算法,如AES、DES、RSA等。 实现方式: 设计一个通用的加密工具封装常用的加密算法和相关操作方法,如加密解密、生成密钥等。 使用Java加密相关API,如javax.crypto包下的和接口,来实现不同加密算法的具体功能。 提供灵活的接口和参数配置,使用户能够根据需求选择合适的加密算法和参数,并方便地集成到其他应用。 身份认证模块: 功能描述: 身份认证模块用于验证用户的身份,并授权其访问系统资源或执行特定操作。 它提供了多种身份验证方式,如基于用户名密码的认证、基于数字证书的认证等。 实现方式: 设计一个通用的身份认证管理器,负责用户身份的验证和授权管理。 支持多种认证方式的配置和扩展,使系统能够适应不同的身份验证需求。 集成常用的认证协议和技术,如LDAP、OAuth、OpenID等,以支持各种场景下的身份认证。 这两个安全模块的设计与实现应该具备以下特点: 通用性:能够适用于各种型的应用场景,不局限于特定的应用领域。 灵活性:提供灵活的配置和扩展机制,能够根据实际需求进行定制和扩展。 安全性:保证系统的安全性和可靠性,防范各种安全攻击和威胁。 易用性:具有良好的用户体验和易用的接口,方便开发者和系统管理员进行配置和管理。 通过设计与实现这两个通用安全模块,能够为Java应用提供全面的安全保障,保护用户的数据和系统资源不受未授权访问和恶意攻击。
JAVA开发人员必备是HTML格式的 JavaTM 2 Platform Standard Edition 6 API 规范 本文档是 Java 2 Platform Standard Edition 6.0 的 API 规范。 请参见: 描述 Java 2 Platform 软件包 java.applet 提供创建 applet 所必需的和 applet 用来与其 applet 上下文通信的java.awt 包含用于创建用户界面和绘制图形图像的所有java.awt.color 提供用于颜色空间的java.awt.datatransfer 提供在应用程序之间和在应用程序内部传输数据的接口和java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统都会遇到它,它提供了一种机制,能够在两个与 GUI 显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的各事件的接口和java.awt.font 提供与字体相关和接口。 java.awt.geom 提供用于在与二维几何形状相关的对象上定义和执行操作的 Java 2D java.awt.im 提供输入方法框架所需的和接口。 java.awt.im.spi 提供启用可以与 Java 运行时环境一起使用的输入方法开发的接口。 java.awt.image 提供创建和修改图像的各种java.awt.image.renderable 提供用于生成与呈现无关的图像的和接口。 java.awt.print 为通用的打印 API 提供和接口。 java.beans 包含与开发 beans 有关的,即基于 JavaBeansTM 架构的组件。 java.beans.beancontext 提供与 bean 上下文有关的和接口。 java.io 通过数据流、序列化和文件系统提供系统输入和输出。 java.lang 提供利用 Java 编程语言进行程序设计的基础java.lang.annotation 为 Java 编程语言注释设施提供库支持。 java.lang.instrument 提供允许 Java 编程语言代理检测运行在 JVM 上的程序的服务。 java.lang.management 提供管理接口,用于监视和管理 Java 虚拟机以及 Java 虚拟机在其上运行的操作系统。 java.lang.ref 提供了引用对象,支持在某种程度上与垃圾回收器之间的交互。 java.lang.reflect 提供和接口,以获得关于和对象的反射信息。 java.math 提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的java.net 为实现网络应用程序提供java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的选择器。 java.nio.channels.spi 用于 java.nio.channels 包的服务提供者java.nio.charset 定义用来在字节和 Unicode 字符之间转换的 charset、解码器和编码器。 java.nio.charset.spi java.nio.charset 包的服务提供者java.rmi 提供 RMI 包。 java.rmi.activation 为 RMI 对象激活提供支持。 java.rmi.dgc 为 RMI 分布式垃圾回收提供了和接口。 java.rmi.registry 提供 RMI 注册表的一个和两个接口。 java.rmi.server 提供支持服务器端 RMI 的和接口。 java.security 为安全框架提供和接口。 java.security.acl 此包和接口已经被 java.security取代。 java.security.cert 提供用于解析和管理证书、证书撤消列表 (CRL) 和证书路径的和接口。 java.security.interfaces 提供的接口用于生成 RSA Laboratory Technical Note PKCS#1 定义的 RSA(Rivest、Shamir 和 Adleman AsymmetricCipher 算法)密钥,以及 NIST 的 FIPS-186 定义的 DSA(数字签名算法)密钥。 java.security.spec 提供密钥规范和算法参数规范的和接口。 java.sql 提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)的数据的 API。 java.text 提供以与自然语言无关的方式来处理文本、日期、数字和消息的和接口。 java.text.spi java.text 包的服务提供者java.util 包含 collection 框架、遗留的 collection 、事件模型、日期和时间设施、国际化和各种实用工具(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程很常用的实用工具java.util.concurrent.atomic 的小工具包,支持在单个变量上解除锁的线程安全编程。 java.util.concurrent.locks 为锁和等待条件提供一个框架的接口和,它不同于内置同步和监视器。 java.util.jar 提供读写 JAR (Java ARchive) 文件格式的,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的和接口。 java.util.prefs 此包允许应用程序存储并获取用户和系统首选项和配置数据。 java.util.regex 用于匹配字符序列与正则表达式指定模式的java.util.spi java.util 包的服务提供者java.util.zip 提供用于读写标准 ZIP 和 GZIP 文件格式的javax.accessibility 定义了用户界面组件与提供对这些组件进行访问的辅助技术之间的协定。 javax.crypto加密操作提供和接口。 javax.crypto.interfaces 根据 RSA Laboratories' PKCS #3 的定义,提供 Diffie-Hellman 密钥接口。 javax.crypto.spec 为密钥规范和算法参数规范提供和接口。 javax.imageio Java Image I/O API 的主要包。 javax.imageio.event Java Image I/O API 的一个包,用于在读取和写入图像期间处理事件的同步通知。 javax.imageio.metadata 用于处理读写元数据的 Java Image I/O API 的包。 javax.imageio.plugins.bmp 包含供内置 BMP 插件使用的公共的包。 javax.imageio.plugins.jpeg 支持内置 JPEG 插件的javax.imageio.spi 包含用于 reader、writer、transcoder 和流的插件接口以及一个运行时注册表的 Java Image I/O API 包。 javax.imageio.stream Java Image I/O API 的一个包,用来处理从文件和流产生的低级别 I/O。 javax.management 提供 Java Management Extensions 的核心javax.management.loading 提供实现高级动态加载的javax.management.modelmbean 提供了 ModelMBean 的定义。 javax.management.monitor 提供 monitor 的定义。 javax.management.openmbean 提供开放数据型和 Open MBean 描述符javax.management.relation 提供 Relation Service 的定义。 javax.management.remote 对 JMX MBean 服务器进行远程访问使用的接口。 javax.management.remote.rmi RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。 javax.management.timer 提供对 Timer MBean(计时器 MBean)的定义。 javax.naming 为访问命名服务提供和接口。 javax.naming.directory 扩展 javax.naming 包以提供访问目录服务的功能。 javax.naming.event 在访问命名和目录服务时提供对事件通知的支持。 javax.naming.ldap 提供对 LDAPv3 扩展操作和控件的支持。 javax.naming.spi 提供一些方法来动态地插入对通过 javax.naming 和相关包访问命名和目录服务的支持。 javax.net 提供用于网络应用程序的javax.net.ssl 提供用于安全套接字包的javax.print 为 JavaTM Print Service API 提供了主要和接口。 javax.print.attribute 提供了描述 JavaTM Print Service 属性的型以及如何分这些属性的和接口。 javax.print.attribute.standard 包 javax.print.attribute.standard 包括特定打印属性的javax.print.event 包 javax.print.event 包含事件和侦听器接口。 javax.rmi 包含 RMI-IIOP 的用户 API。 javax.rmi.CORBA 包含用于 RMI-IIOP 的可移植性 API。 javax.rmi.ssl 通过安全套接字层 (SSL) 或传输层安全 (TLS) 协议提供 RMIClientSocketFactory 和 RMIServerSocketFactory 的实现。 javax.security.auth 此包提供用于进行验证和授权的框架。 javax.security.auth.callback 此包提供与应用程序进行交互所必需的,以便检索信息(例如,包括用户名和密码的验证数据)或显示信息(例如,错误和警告消息)。 javax.security.auth.kerberos 此包包含与 Kerberos 网络验证协议相关的实用工具javax.security.auth.login 此包提供可插入的验证框架。 javax.security.auth.spi 此包提供用于实现可插入验证模块的接口。 javax.security.auth.x500 此包包含应该用来在 Subject 存储 X500 Principal 和 X500 Private Crendentials 的javax.security.cert 为公钥证书提供javax.security.sasl 包含用于支持 SASL 的和接口。 javax.sound.midi 提供用于 MIDI(音乐乐器数字接口)数据的 I/O、序列化和合成的接口和javax.sound.midi.spi 在提供新的 MIDI 设备、MIDI 文件 reader 和 writer、或音库 reader 时提供服务提供者要实现的接口。 javax.sound.sampled 提供用于捕获、处理和回放取样的音频数据的接口和javax.sound.sampled.spi 在提供新音频设备、声音文件 reader 和 writer,或音频格式转换器时,提供将为其创建子的服务提供者的抽象javax.sql 为通过 JavaTM 编程语言进行服务器端数据源访问和处理提供 API。 javax.sql.rowset JDBC RowSet 实现的标准接口和基javax.sql.rowset.serial 提供实用工具,允许 SQL 型与 Java 编程语言数据型之间的可序列化映射关系。 javax.sql.rowset.spi 第三方供应商在其同步提供者的实现必须使用的标准和接口。 javax.swing 提供一组“轻量级”(全部是 Java 语言)组件,尽量让这些组件在所有平台上的工作方式都相同。 javax.swing.border 提供围绕 Swing 组件绘制特殊边框的和接口。 javax.swing.colorchooser 包含供 JColorChooser 组件使用的和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的和接口。 javax.swing.plaf 提供一个接口和许多抽象,Swing 用它们来提供自己的可插入外观功能。 javax.swing.plaf.basic 提供了根据基本外观构建的用户界面对象。 javax.swing.plaf.metal 提供根据 Java 外观(曾经代称为 Metal)构建的用户界面对象,Java 外观是默认外观。 javax.swing.plaf.multi 提供了组合两个或多个外观的用户界面对象。 javax.swing.plaf.synth Synth 是一个可更换皮肤 (skinnable) 的外观,在其可委托所有绘制。 javax.swing.table 提供用于处理 javax.swing.JTable 的和接口。 javax.swing.text 提供 HTMLEditorKit 和创建 HTML 文本编辑器的支持javax.swing.text.html 提供 HTMLEditorKit 和创建 HTML 文本编辑器的支持javax.swing.text.html.parser 提供默认的 HTML 解析器以及支持javax.swing.text.rtf 提供一个 (RTFEditorKit),用于创建富文本格式(Rich-Text-Format)的文本编辑器。 javax.swing.tree 提供处理 javax.swing.JTree 的和接口。 javax.swing.undo 允许开发人员为应用程序(例如文本编辑器)的撤消/恢复提供支持。 javax.transaction 包含解组期间通过 ORB 机制抛出的三个异常。 javax.transaction.xa 提供定义事务管理器和资源管理器之间的协定的 API,它允许事务管理器添加或删除 JTA 事务的资源对象(由资源管理器驱动程序提供)。 javax.xml 根据 XML 规范定义核心 XML 常量和功能。 javax.xml.bind 为包含解组、编组和验证功能的客户端应用程序提供运行时绑定框架。 javax.xml.bind.annotation 定义将 Java 程序元素定制成 XML 模式映射的注释。 javax.xml.bind.annotation.adapters XmlAdapter 及其规范定义的子允许任意 Java 与 JAXB 一起使用。 javax.xml.bind.attachment 此包由基于 MIME 的包处理器实现,该处理器能够解释并创建基于 MIME 的包格式的已优化的二进制数据。 javax.xml.bind.helpers 仅由 JAXB 提供者用于: 提供某些 javax.xml.bind 接口的部分默认实现。 javax.xml.bind.util 有用的客户端实用工具javax.xml.crypto 用于 XML 加密的通用javax.xml.crypto.dom javax.xml.crypto 包的特定于 DOM 的javax.xml.crypto.dsig 用于生成和验证 XML 数字签名的javax.xml.crypto.dsig.dom javax.xml.crypto.dsig 包特定于 DOM 的javax.xml.crypto.dsig.keyinfo 用来解析和处理 KeyInfo 元素和结构的javax.xml.crypto.dsig.spec XML 数字签名的参数javax.xml.datatype XML/Java 型映射关系。 javax.xml.namespace XML 名称空间处理。 javax.xml.parsers 提供允许处理 XML 文档的javax.xml.soap 提供用于创建和构建 SOAP 消息的 API。 javax.xml.stream javax.xml.stream.events javax.xml.stream.util javax.xml.transform 此包定义了用于处理转换指令,以及执行从源到结果的转换的一般 API。 javax.xml.transform.dom 此包实现特定于 DOM 的转换 API。 javax.xml.transform.sax 此包实现特定于 SAX2 的转换 API。 javax.xml.transform.stax 提供特定于 StAX 的转换 API。 javax.xml.transform.stream 此包实现特定于流和 URI 的转换 API。 javax.xml.validation 此包提供了用于 XML 文档验证的 API。 javax.xml.ws 此包包含核心 JAX-WS API。 javax.xml.ws.handler 该包定义用于消息处理程序的 API。 javax.xml.ws.handler.soap 该包定义用于 SOAP 消息处理程序的 API。 javax.xml.ws.http 该包定义特定于 HTTP 绑定的 API。 javax.xml.ws.soap 该包定义特定于 SOAP 绑定的 API。 javax.xml.ws.spi 该包定义用于 JAX-WS 2.0 的 SPI。 javax.xml.xpath 此包提供了用于 XPath 表达式的计算和访问计算环境的 object-model neutral API。 org.ietf.jgss 此包提供一个框架,该框架允许应用程序开发人员通过利用统一的 API 使用一些来自各种基础安全机制(如 Kerberos)的安全服务,如验证、数据完整性和和数据机密性。 org.omg.CORBA 提供 OMG CORBA API 到 JavaTM 编程语言的映射,包括 ORB ,如果已实现该,则程序员可以使用此作为全功能对象请求代理(Object Request Broker,ORB)。 org.omg.CORBA_2_3 CORBA_2_3 包定义对 Java[tm] Standard Edition 6 现有 CORBA 接口所进行的添加。 org.omg.CORBA_2_3.portable 提供输入和输出值型的各种方法,并包含 org/omg/CORBA/portable 包的其他更新。 org.omg.CORBA.DynAnyPackage 提供与 DynAny 接口一起使用的异常(InvalidValue、Invalid、InvalidSeq 和 TypeMismatch)。 org.omg.CORBA.ORBPackage 提供由 ORB.resolve_initial_references 方法抛出的异常 InvalidName,以及由 ORB 的动态 Any 创建方法抛出的异常 InconsistentTypeCode。 org.omg.CORBA.portable 提供可移植性层,即可以使一个供应商生成的代码运行在另一个供应商 ORB 上的 ORB API 集合。 org.omg.CORBA.TypeCodePackage 提供用户定义的异常 BadKind 和 Bounds,它们将由 TypeCode 的方法抛出。 org.omg.CosNaming 为 Java IDL 提供命名服务。 org.omg.CosNaming.NamingContextExtPackage 此包包含以下在 org.omg.CosNaming.NamingContextExt 使用的: AddressHelper StringNameHelper URLStringHelper InvalidAddress 包规范 有关 Java[tm] Platform, Standard Edition 6 ORB 遵守的官方规范的受支持部分的明确列表,请参阅 Official Specifications for CORBA support in Java[tm] SE 6。 org.omg.CosNaming.NamingContextPackage 此包包含 org.omg.CosNaming 包的 Exception 。 org.omg.Dynamic 此包包含 OMG Portable Interceptor 规范 http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06 的第 21.9 小节指定的 Dynamic 模块。 org.omg.DynamicAny 提供一些和接口使得在运行时能够遍历与 any 有关联的数据值,并提取数据值的基本成分。 org.omg.DynamicAny.DynAnyFactoryPackage 此包包含 DynamicAny 模块的 DynAnyFactory 接口和异常,该模块在 OMG The Common Object Request Broker: Architecture and Specification http://cgi.omg.org/cgi-bin/doc?formal/99-10-07 的第 9.2.2 小节指定。 org.omg.DynamicAny.DynAnyPackage 此包包含 DynAny 模块的 DynAnyFactory 接口和异常,该模块在 OMG The Common Object Request Broker: Architecture and Specification http://cgi.omg.org/cgi-bin/doc?formal/99-10-07 的第 9.2 小节指定。 org.omg.IOP 此包包含在 OMG 文档 The Common Object Request Broker: Architecture and Specification http://cgi.omg.org/cgi-bin/doc?formal/99-10-07 的 13.6.小节指定的 IOP 模块。 org.omg.IOP.CodecFactoryPackage 此包包含 IOP::CodeFactory 接口指定的异常(作为 Portable Interceptor 规范的一部分)。 org.omg.IOP.CodecPackage 此包根据 IOP::Codec IDL 接口定义生成。 org.omg.Messaging 此包包含 OMG Messaging Interceptor 规范 http://cgi.omg.org/cgi-bin/doc?formal/99-10-07 指定的 Messaging 模块。 org.omg.PortableInterceptor 提供一个注册 ORB 钩子 (hook) 的机制,通过这些钩子 ORB 服务可以截取执行 ORB 的正常流。 org.omg.PortableInterceptor.ORBInitInfoPackage 此包包含 OMG Portable Interceptor 规范 http://cgi.omg.org/cgi-bin/doc?ptc/2000-08-06 的第 21.7.2 小节指定的 PortableInterceptor 模块的 ORBInitInfo 本地接口的异常和 typedef。 org.omg.PortableServer 提供一些和接口,用来生成跨多个供应商 ORB 的可移植应用程序的服务器端。 org.omg.PortableServer.CurrentPackage 提供各种方法实现,这些实现能够访问调用方法的对象的身份。 org.omg.PortableServer.POAManagerPackage 封装 POA 关联的处理状态。 org.omg.PortableServer.POAPackage 允许程序员构造可在不同 ORB 产品间移植的对象实现。 org.omg.PortableServer.portable 提供一些和接口,用来生成跨多个供应商 ORB 的可移植应用程序的服务器端。 org.omg.PortableServer.ServantLocatorPackage 提供定位 servant 的和接口。 org.omg.SendingContext 为值型的编组提供支持。 org.omg.stub.java.rmi 包含用于 java.rmi 包出现的 Remote 型的 RMI-IIOP Stub。 org.w3c.dom 为文档对象模型 (DOM) 提供接口,该模型是 Java API for XML Processing 的组件 API。 org.w3c.dom.bootstrap org.w3c.dom.events org.w3c.dom.ls org.xml.sax 此包提供了核心 SAX API。 org.xml.sax.ext 此包包含适合的 SAX 驱动程序不一定支持的 SAX2 设施的接口。 org.xml.sax.helpers 此包包含“帮助器”,其包括对引导基于 SAX 的应用程序的支持。
Java可以使用javax.crypto来进行AES加密解密。具体实现步骤如下: 1. 生成一个AES密钥 ``` KeyGenerator keygen = KeyGenerator.getInstance("AES"); keygen.init(128); SecretKey key = keygen.generateKey(); ``` 2. 创建Cipher对象,并初始化为加密模式或解密模式 ``` Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); ``` 3. 加密/解密数据 ``` byte[] ciphertext = cipher.doFinal(plaintext); byte[] plaintext = cipher.doFinal(ciphertext); ``` 完整代码示例: ``` import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; public class AESUtil { private static final String CHARSET_NAME = "UTF-8"; private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding"; /** * 随机生成AES密钥 * * @param keySize 密钥长度,单位:位 * @return 生成的密钥 * @throws NoSuchAlgorithmException 异常 */ public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(keySize); SecretKey secretKey = keyGenerator.generateKey(); return secretKey.getEncoded(); } /** * AES加密 * * @param plaintext 明文 * @param key 密钥 * @param iv 初始化向量 * @return 密文 * @throws NoSuchPaddingException 异常 * @throws NoSuchAlgorithmException 异常 * @throws InvalidAlgorithmParameterException 异常 * @throws InvalidKeyException 异常 * @throws BadPaddingException 异常 * @throws IllegalBlockSizeException 异常 */ public static byte[] encrypt(byte[] plaintext, byte[] key, byte[] iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(iv)); return cipher.doFinal(plaintext); } /** * AES解密 * * @param ciphertext 密文 * @param key 密钥 * @param iv 初始化向量 * @return 明文 * @throws NoSuchPaddingException 异常 * @throws NoSuchAlgorithmException 异常 * @throws InvalidAlgorithmParameterException 异常 * @throws InvalidKeyException 异常 * @throws BadPaddingException 异常 * @throws IllegalBlockSizeException 异常 */ public static byte[] decrypt(byte[] ciphertext, byte[] key, byte[] iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(iv)); return cipher.doFinal(ciphertext); } /** * 生成随机的初始化向量 * * @param ivSize 初始化向量长度,单位:位 * @return 生成的初始化向量 */ public static byte[] generateIv(int ivSize) { byte[] iv = new byte[ivSize / 8]; new SecureRandom().nextBytes(iv); return iv; } /** * 将字节数组转换为十六进制字符串 * * @param bytes 字节数组 * @return 十六进制字符串 */ public static String toHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { sb.append(String.format("%02x", b & 0xff)); } return sb.toString(); } /** * 将十六进制字符串转换为字节数组 * * @param hexString 十六进制字符串 * @return 字节数组 */ public static byte[] toByteArray(String hexString) { int len = hexString.length() / 2; byte[] bytes = new byte[len]; for (int i = 0; i < len; i++) { int index = i * 2; bytes[i] = (byte) Integer.parseInt(hexString.substring(index, index + 2), 16); } return bytes; } public static void main(String[] args) throws Exception { // 随机生成16字节的AES密钥和16字节的初始化向量 byte[] key = generateKey(128); byte[] iv = generateIv(128); String plaintextStr = "hello, AES!"; byte[] plaintext = plaintextStr.getBytes(CHARSET_NAME); // AES加密 byte[] ciphertext = encrypt(plaintext, key, iv); String ciphertextHex = toHexString(ciphertext); System.out.println("密文:" + ciphertextHex); // AES解密 byte[] ciphertextBytes = toByteArray(ciphertextHex); byte[] decrypted = decrypt(ciphertextBytes, key, iv); String decryptedStr = new String(decrypted, CHARSET_NAME); System.out.println("明文:" + decryptedStr); } } 相关问题:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值