public abstract class CipherSpi extends Object
Cipher
类。
该类中的所有抽象方法必须由希望提供特定密码算法的实现的每个加密服务提供商来实现。
为了创建的实例Cipher
,它封装了这个实例CipherSpi
类,应用程序调用的一个getInstance
种的工厂方法Cipher
引擎类,并指定请求的转换 。 可选地,应用程序还可以指定提供者的名称。
转换是描述要在给定输入上执行的操作(或操作集)的字符串,以产生一些输出。 转换总是包括加密算法的名称(例如, DES ),并且可以跟随有反馈模式和填充方案。
转换形式如下:
(在后一种情况下,使用模式和填充方案的提供者特定的默认值)。 例如,以下是有效的转换:
Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
提供者可以为算法/模式/填充的每个组合提供单独的类,或者可以决定提供表示对应于算法或算法/模式或算法//填充 (注意双斜杠)的子变换的更多通用类,其中情况下所请求模式和/或填充由自动设定getInstance
的方法Cipher
,其调用engineSetMode
种engineSetPadding
的提供者的子类的方法CipherSpi
。
提供者主类中的Cipher
属性可能具有以下格式之一:
// provider's subclass of "CipherSpi" implements "algName" with
// pluggable mode and padding
Cipher.
algName
// provider's subclass of "CipherSpi" implements "algName" in the
// specified "mode", with pluggable padding
Cipher.
algName/mode
// provider's subclass of "CipherSpi" implements "algName" with the
// specified "padding", with pluggable mode
Cipher.
algName//padding
// provider's subclass of "CipherSpi" implements "algName" with the
// specified "mode" and "padding"
Cipher.
algName/mode/padding
例如,提供者可以提供的一个子类CipherSpi
实现DES / ECB / PKCS5Padding,一个实现DES / CBC / PKCS5Padding,一个实现DES / CFB / PKCS5Padding,和又一一个实现DES / OFB / PKCS5Padding。 该提供商将有以下Cipher
在其主类的属性:
Cipher.
DES/ECB/PKCS5Padding
Cipher.
DES/CBC/PKCS5Padding
Cipher.
DES/CFB/PKCS5Padding
Cipher.
DES/OFB/PKCS5Padding
另一个提供者可以针对上述各种模式(即ECB的一个类别,一个用于CBC ,一个用于CFB ,另一个用于OFB ), PKCS5Padding的一个类以及从CipherSpi
分类的通用DES类来CipherSpi
。 该提供商将有以下Cipher
在其主类的属性:
Cipher.
DES
Cipher
引擎类的getInstance
工厂方法遵循这些规则,以便实例化一个提供者对“ 算法 ”形式的转换的CipherSpi
实现:
CipherSpi
为指定的“ 算法 ”。 如果答案为YES,则实例化该类,对于其模式和填充方案默认值(由提供者提供)使用。
如果答案为否,则抛出NoSuchAlgorithmException
异常。
Cipher
引擎类的getInstance
工厂方法遵循这些规则,以便实例化一个提供者对“ 算法/模式/填充 ”形式的转换的CipherSpi
实现:
CipherSpi
为指定的“ 算法/模式/填充 ”转型。 如果答案为YES,则将其实例化。
如果答案为否,请转到下一步。
CipherSpi
为副变换“ 算法/模式 ”。 如果答案为YES,则将其实例化,并在新实例上调用engineSetPadding(padding)
。
如果答案为否,请转到下一步。
CipherSpi
为副变换“ 算法//填充 ”(注意双斜杠)。 如果答案为YES,则将其实例化,并在新实例上调用engineSetMode(mode)
。
如果答案为否,请转到下一步。
CipherSpi
为副变换“ 算法 ”。 如果答案为YES,则将其实例化,并在新实例上调用engineSetMode(mode)
和engineSetPadding(padding)
。
如果答案为否,则抛出NoSuchAlgorithmException
异常。
KeyGenerator
, SecretKey
Constructor and Description |
---|
CipherSpi() |
Modifier and Type | Method and Description |
---|---|
protected abstract byte[] |
engineDoFinal(byte[] input, int inputOffset, int inputLen)
在单一部分操作中加密或解密数据,或完成多部分操作。
|
protected abstract int |
engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
在单一部分操作中加密或解密数据,或完成多部分操作。
|
protected int |
engineDoFinal(ByteBuffer input, ByteBuffer output)
在单一部分操作中加密或解密数据,或完成多部分操作。
|
protected abstract int |
engineGetBlockSize()
返回块大小(以字节为单位)。
|
protected abstract byte[] |
engineGetIV()
返回新缓冲区中的初始化向量(IV)。
|
protected int |
engineGetKeySize(Key key)
以位为单位返回给定键对象的键大小。
|
protected abstract int |
engineGetOutputSize(int inputLen)
给定输入长度
inputLen (以字节为单位),返回输出缓冲区需要保存下一个
update 或
doFinal 操作结果的字节长度。
|
protected abstract AlgorithmParameters |
engineGetParameters()
返回与此密码一起使用的参数。
|
protected abstract void |
engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random)
使用密钥,一组算法参数和随机源初始化此密码。
|
protected abstract void |
engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random)
使用密钥,一组算法参数和随机源初始化此密码。
|
protected abstract void |
engineInit(int opmode, Key key, SecureRandom random)
用密钥和随机源初始化此密码。
|
protected abstract void |
engineSetMode(String mode)
设置此密码的模式。
|
protected abstract void |
engineSetPadding(String padding)
设置这个密码的填充机制。
|
protected Key |
engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType)
打开以前包装的钥匙。
|
protected abstract byte[] |
engineUpdate(byte[] input, int inputOffset, int inputLen)
继续进行多部分加密或解密操作(取决于如何初始化该密码),处理另一个数据部分。
|
protected abstract int |
engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
继续进行多部分加密或解密操作(取决于如何初始化该密码),处理另一个数据部分。
|
protected int |
engineUpdate(ByteBuffer input, ByteBuffer output)
继续进行多部分加密或解密操作(取决于如何初始化该密码),处理另一个数据部分。
|
protected void |
engineUpdateAAD(byte[] src, int offset, int len)
使用所提供的缓冲区的子集,继续进行附加认证数据(AAD)的多部分更新。
|
protected void |
engineUpdateAAD(ByteBuffer src)
继续进行附加认证数据(AAD)的多部分更新。
|
protected byte[] |
engineWrap(Key key)
包裹钥匙
|
protected abstract void engineSetMode(String mode) throws NoSuchAlgorithmException
mode
- 密码模式
NoSuchAlgorithmException
- 如果请求的密码模式不存在
protected abstract void engineSetPadding(String padding) throws NoSuchPaddingException
padding
- 填充机制
NoSuchPaddingException
- 如果请求的填充机制不存在
protected abstract int engineGetBlockSize()
protected abstract int engineGetOutputSize(int inputLen)
inputLen
(以字节为单位),返回输出缓冲区需要保存下一个update
或doFinal
操作的结果的字节长度。
此呼叫考虑到来自前一个update
呼叫,填充和update
标记的任何未处理(缓冲)数据。
下一个update
或doFinal
调用的实际输出长度可能小于此方法返回的长度。
inputLen
- 输入长度(字节)
protected abstract byte[] engineGetIV()
这在基于密码的加密或解密的上下文中是有用的,其中IV是从用户提供的密码短语导出的。
protected abstract AlgorithmParameters engineGetParameters()
返回的参数可能与用于初始化此密码的参数相同,或者如果该密码需要算法参数但未被任何初始化,则可能包含底层密码实现使用的默认值和随机参数值的组合。
protected abstract void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException
根据opmode的值,将密码初始化为以下四个操作之一:加密,解密,密钥包装或密钥解opmode
。
如果此密码需要不能从给定的key
导出的任何key
,则底层加密实现应该自动生成所需参数(使用提供者特定的默认值或随机值),如果它被初始化为加密或密钥包装,以及提高一个InvalidKeyException
如果它被初始化解密或密钥解包。 生成的参数可以使用engineGetParameters
或engineGetIV
(如果参数是IV)检索。
如果该密码需要不能从输入参数导出的算法参数,并且没有合理的提供者特定的默认值,则初始化必然会失败。
如果这个密码(包括其底层反馈或填充方案)需要任何随机字节(例如,用于参数生成),它将从random
得到它们。
请注意,当一个Cipher对象被初始化时,它将失去所有先前获取的状态。 换句话说,初始化一个Cipher相当于创建一个新的Cipher实例并对其进行初始化。
opmode
-此cipher的操作模式(这是下列之一:
ENCRYPT_MODE
,
DECRYPT_MODE
,
WRAP_MODE
或
UNWRAP_MODE
)
key
- 加密密钥
random
-
random
的来源
InvalidKeyException
- 如果给定的密钥不适合初始化该密码,或者需要不能从给定密钥确定的算法参数。
UnsupportedOperationException
- 如果
opmode
是
WRAP_MODE
或
UNWRAP_MODE
未被密码实现。
protected abstract void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException
根据opmode的值,密码被初始化为以下四个操作之一:加密,解密,密钥包装或密钥解opmode
。
如果此密码需要任何算法参数,并且params
为null,则底层加密实现应该自动生成必需的参数(使用特定于提供者的默认值或随机值),如果它被初始化为加密或密钥包装,并提出一个InvalidAlgorithmParameterException
if正在为解密或密钥解包进行初始化。 可以使用engineGetParameters
或engineGetIV
(如果参数为IV)检索生成的参数。
如果该密码需要不能从输入参数导出的算法参数,并且没有合理的提供者特定的默认值,则初始化必然会失败。
如果这个密码(包括其底层反馈或填充方案)需要任何随机字节(例如,用于参数生成),它将从random
。
请注意,当一个Cipher对象被初始化时,它将失去所有先前获取的状态。 换句话说,初始化一个Cipher相当于创建一个新的Cipher实例并对其进行初始化。
opmode
-此cipher的操作模式(这是下列之一:
ENCRYPT_MODE
,
DECRYPT_MODE
,
WRAP_MODE
或
UNWRAP_MODE
)
key
- 加密密钥
params
- 算法参数
random
-
random
的来源
InvalidKeyException
- 如果给定的密钥不适合初始化此密码
InvalidAlgorithmParameterException
- 如果给定的算法参数不适合该密码,或者该密码需要算法参数,并且
params
为空。
UnsupportedOperationException
- 如果
opmode
是
WRAP_MODE
或
UNWRAP_MODE
未被密码实现。
protected abstract void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException
根据opmode的值,将密码初始化为以下四个操作之一:加密,解密,密钥包装或密钥解opmode
。
如果此密码需要任何算法参数,并且params
为null,则底层加密实现应该自动生成所需参数(使用特定于提供者的默认值或随机值),如果正在初始化加密或密钥包装,并提出一个InvalidAlgorithmParameterException
if正在为解密或密钥解包进行初始化。 可以使用engineGetParameters
或engineGetIV
(如果参数为IV)检索生成的参数。
如果该密码需要不能从输入参数导出的算法参数,并且没有合理的提供者特定的默认值,则初始化必然会失败。
如果这个密码(包括其底层反馈或填充方案)需要任何随机字节(例如,用于参数生成),它将从random
。
请注意,当一个Cipher对象被初始化时,它将失去所有先前获取的状态。 换句话说,初始化一个Cipher相当于创建一个新的Cipher实例并对其进行初始化。
opmode
-此cipher的操作模式(这是下列之一:
ENCRYPT_MODE
,
DECRYPT_MODE
,
WRAP_MODE
或
UNWRAP_MODE
)
key
- 加密密钥
params
- 算法参数
random
-
random
的来源
InvalidKeyException
- 如果给定的密钥不适合初始化此密码
InvalidAlgorithmParameterException
- 如果给定的算法参数不适合该密码,或者该密码需要算法参数,并且
params
为空。
UnsupportedOperationException
- 如果
opmode
是
WRAP_MODE
或
UNWRAP_MODE
未被密码实现。
protected abstract byte[] engineUpdate(byte[] input, int inputOffset, int inputLen)
第一inputLen
字节在input
缓冲区中,从inputOffset
以下,被处理,并且结果被存储在新的缓冲器。
input
- 输入缓冲区
inputOffset
-
input
中输入开始的偏移量
inputLen
- 输入长度
protected abstract int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException
input
缓冲区中的第inputLen
个字节(起始于inputOffset
)被处理,结果存储在output
缓冲区中,从outputOffset
开始。
如果output
缓冲区太小而不能保存结果,则抛出ShortBufferException
。
input
- 输入缓冲区
inputOffset
-
input
中的输入开始的偏移量
inputLen
- 输入长度
output
- 结果的缓冲区
outputOffset
-
output
中存储结果的偏移量
output
中的字节数
ShortBufferException
- 如果给定的输出缓冲区太小,不能保存结果
protected int engineUpdate(ByteBuffer input, ByteBuffer output) throws ShortBufferException
所有input.remaining()
起始字节input.position()
进行处理。 结果存储在输出缓冲区中。 返回时,输入缓冲区的位置将等于其限制; 其限制将不会改变。 输出缓冲区的位置将提前n,其中n是此方法返回的值; 输出缓冲区的限制将不会改变。
如果output.remaining()
字节不足以保存结果,则抛出ShortBufferException
。
子类应该考虑覆盖此方法,如果它们可以比字节数组更有效地处理ByteBuffers。
input
- 输入ByteBuffer
output
- 输出ByteByffer
output
中存储的字节数
ShortBufferException
- 如果输出缓冲区中没有足够的空间
NullPointerException
- 如果任一参数是
null
protected abstract byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException
第一inputLen
字节在input
缓冲区中,从inputOffset
以下,并且可能在上一次期间已缓存的任何输入字节update
操作,进行处理,填充(如果要求)被施加。 如果正在使用诸如GCM / CCM的AEAD模式,则在加密的情况下附加认证标签,或者在解密的情况下验证认证标签。 结果存储在一个新的缓冲区。
完成后,此方法将此密码对象重置为先前通过调用engineInit
。 也就是说,该对象被复位并且可用于加密或解密(取决于这是在调用所指定的操作模式engineInit
)更多的数据。
注意:如果发生任何异常,则可能需要重新设置此密码对象,然后才能再次使用。
input
- 输入缓冲区
inputOffset
-
input
中的输入开始的偏移量
inputLen
- 输入长度
IllegalBlockSizeException
- 如果该密码是块密码,则不会请求填充(仅在加密模式下),并且由该密码处理的数据的总输入长度不是块大小的倍数;
或者如果此加密算法无法处理提供的输入数据。
BadPaddingException
- 如果该密码处于解密模式,并且已经请求了(un)填充,但是解密的数据不受适当的填充字节的限制
AEADBadTagException
- 如果该密码在AEAD模式(例如GCM / CCM)中进行解密,并且接收到的认证标签与计算值不匹配
protected abstract int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
input
缓冲区中第inputLen
个字节(包括起始值为inputOffset
)以及前一个update
操作中可能已经被缓存的任何输入字节都被处理,并应用填充(如果请求)。 如果正在使用诸如GCM / CCM的AEAD模式,则在加密的情况下附加认证标签,或者在解密的情况下验证认证标签。 结果存储在output
缓冲区中,从outputOffset
开始。
如果output
缓冲区太小而不能保存结果,则抛出一个ShortBufferException
。
完成后,此方法将此密码对象重置为先前通过调用engineInit
。 也就是说,该对象被复位并且可用于加密或解密(取决于这是在调用所指定的操作模式engineInit
)更多的数据。
注意:如果发生任何异常,则可能需要重新设置此密码对象,然后才能再次使用。
input
- 输入缓冲区
inputOffset
-
input
中的输入开始的偏移量
inputLen
- 输入长度
output
- 结果的缓冲区
outputOffset
- 存储结果的
output
中的偏移量
output
中的字节数
IllegalBlockSizeException
- 如果该密码是块密码,则不会请求填充(仅在加密模式下),并且由该密码处理的数据的总输入长度不是块大小的倍数;
或者如果此加密算法无法处理提供的输入数据。
ShortBufferException
- 如果给定的输出缓冲区太小,不能保存结果
BadPaddingException
- 如果该密码处于解密模式,并且已经请求了(un)填充,但是解密的数据不受适当的填充字节的限制
AEADBadTagException
- 如果该密码在AEAD模式(例如GCM / CCM)中解密,并且接收到的认证标签与计算值不匹配
protected int engineDoFinal(ByteBuffer input, ByteBuffer output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException
所有input.remaining()
起始字节input.position()
进行处理。 如果正在使用诸如GCM / CCM的AEAD模式,则在加密的情况下附加认证标签,或者在解密的情况下验证认证标签。 结果存储在输出缓冲区中。 返回时,输入缓冲区的位置将等于其限制; 其限制将不会改变。 输出缓冲区的位置将提前n,其中n是此方法返回的值; 输出缓冲区的限制将不会改变。
如果output.remaining()
字节不足以保存结果,则抛出ShortBufferException
。
完成后,此方法将此密码对象重置为先前通过调用engineInit
。 也就是说,该对象被复位并且可用于加密或解密(取决于这是在调用所指定的操作模式engineInit
)更多的数据。
注意:如果发生任何异常,则可能需要重新设置此密码对象,然后才能再次使用。
子类应该考虑覆盖此方法,如果它们可以比字节数组更有效地处理ByteBuffers。
input
- 输入ByteBuffer
output
- 输出ByteByffer
output
中的字节数
IllegalBlockSizeException
- 如果该密码是块密码,则不会请求填充(仅在加密模式下),并且由该密码处理的数据的总输入长度不是块大小的倍数;
或者如果此加密算法无法处理提供的输入数据。
ShortBufferException
- 输出缓冲区空间不足
BadPaddingException
- 如果该密码处于解密模式,并且已经请求了(un)填充,但是解密的数据不受适当的填充字节的限制
AEADBadTagException
- 如果该密码在AEAD模式(如GCM / CCM)中解密,并且接收的认证标签与计算值不匹配
NullPointerException
- 如果任一参数是
null
protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException
这个具体的方法已经添加到这个以前定义的抽象类中。 (为了向后兼容,它不能是抽象的。)提供者可以覆盖它来包装密钥。 如果给定的键无法被包装,这样的覆盖应该会引发IllegalBlockSizeException或InvalidKeyException(在指定的情况下)。 如果此方法未被覆盖,则会始终抛出UnsupportedOperationException异常。
key
- 要包装的关键。
IllegalBlockSizeException
- 如果该密码是块密码,则不请求填充,并且要包装的密钥的编码长度不是块大小的倍数。
InvalidKeyException
- 如果使用该密码将密钥包装是不可能或不安全的(例如,硬件保护密钥正在传递给仅软件密码)。
UnsupportedOperationException
- 如果不支持此方法。
protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException
这个具体的方法已经添加到这个以前定义的抽象类中。 (为了向后兼容,它不能是抽象的。)提供者可以覆盖它以解开以前包装的密钥。 如果给定的包装密钥无法解开,这样的覆盖应该会抛出InvalidKeyException。 如果此方法未被覆盖,则会始终抛出UnsupportedOperationException异常。
wrappedKey
- 要解开的关键。
wrappedKeyAlgorithm
- 与包裹密钥相关联的算法。
wrappedKeyType
- 包装密钥的类型。
这是一个SECRET_KEY
, PRIVATE_KEY
,或PUBLIC_KEY
。
NoSuchAlgorithmException
-如果没有安装供应商可以创建类型的键
wrappedKeyType
为
wrappedKeyAlgorithm
。
InvalidKeyException
-如果
wrappedKey
不表示类型的包装的密钥
wrappedKeyType
为
wrappedKeyAlgorithm
。
UnsupportedOperationException
- 如果不支持此方法。
protected int engineGetKeySize(Key key) throws InvalidKeyException
这个具体的方法已经添加到这个以前定义的抽象类中。 如果提供者不被覆盖,它会抛出一个UnsupportedOperationException
。
key
- 关键对象。
InvalidKeyException
- 如果
key
无效。
protected void engineUpdateAAD(byte[] src, int offset, int len)
当使用AEAD(GCM / CCM)等模式运行时,调用此方法可以为密码提供AAD。 如果此密码在GCM或CCM模式下运行,则必须在密文开始操作之前(通过update
和doFinal
方法)提供所有AAD。
src
- 包含AAD的缓冲区
offset
-
src
中AAD输入开始的偏移量
len
- AAD字节数
IllegalStateException
- 如果此密码处于错误状态(例如,尚未初始化),则不接受AAD,或者在GCM或CCM模式下运行,并且
update
方法中的一个已被调用用于主动加密/解密操作
UnsupportedOperationException
- 如果此方法尚未被实现覆盖
protected void engineUpdateAAD(ByteBuffer src)
当使用AEAD(GCM / CCM)等模式运行时,调用此方法可以为密码提供AAD。 如果此密码在GCM或CCM模式下运行,则必须在密文开始操作之前(通过update
和doFinal
方法)提供所有AAD。
所有src.remaining()
起始字节src.position()
进行处理。 返回时,输入缓冲区的位置将等于其限制; 其限制将不会改变。
src
- 包含AAD的缓冲区
IllegalStateException
- 如果此密码处于错误状态(例如尚未初始化),则不接受AAD,或者在GCM或CCM模式下运行,并且
update
方法之一已被调用用于主动加密/解密操作
UnsupportedOperationException
- 如果此方法尚未被实现覆盖