add Cipher

This commit is contained in:
Looly 2024-01-06 02:20:49 +08:00
parent 30fafaa5de
commit 9992d776da
8 changed files with 404 additions and 178 deletions

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto;
/**
* 密码接口提供统一的API用于兼容和统一JCE和BouncyCastle等库的操作
*
* @author Looly
* @since 6.0.0
*/
public interface Cipher {
/**
* 获取算法名称
*
* @return 算法名称
*/
String getAlgorithmName();
/**
* 获取块大小当为Stream方式加密时返回0
*
* @return 块大小
*/
int getBlockSize();
/**
* 初始化模式和参数
*
* @param mode 模式如加密模式或解密模式
* @param parameters Cipher所需参数包括KeyRandomIV等信息
*/
void init(CipherMode mode, Parameters parameters);
/**
* 执行运算可以是加密运算或解密运算
*
* @param data 被处理的数据
* @return 运算结果
*/
byte[] process(byte[] data);
/**
* Cipher所需参数包括KeyRandomIV等信息
*/
interface Parameters { }
}

View File

@ -1,136 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto;
import org.dromara.hutool.core.lang.wrapper.Wrapper;
import javax.crypto.Cipher;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
/**
* {@link Cipher}包装类提供初始化模式等额外方法<br>
* 包装之后可提供自定义或默认的
* <ul>
* <li>{@link AlgorithmParameterSpec}</li>
* <li>{@link SecureRandom}</li>
* </ul>
*
* @author looly
* @since 5.7.17
*/
public class CipherWrapper implements Wrapper<Cipher> {
private final Cipher cipher;
/**
* 算法参数
*/
private AlgorithmParameterSpec params;
/**
* 随机数生成器可自定义随机数种子
*/
private SecureRandom random;
/**
* 构造
*
* @param algorithm 算法名称
*/
public CipherWrapper(final String algorithm) {
this(SecureUtil.createCipher(algorithm));
}
/**
* 构造
*
* @param cipher {@link Cipher}
*/
public CipherWrapper(final Cipher cipher) {
this.cipher = cipher;
}
/**
* 获取{@link AlgorithmParameterSpec}<br>
* 在某些算法中需要特别的参数例如在ECIES中此处为IESParameterSpec
*
* @return {@link AlgorithmParameterSpec}
*/
public AlgorithmParameterSpec getParams() {
return this.params;
}
/**
* 设置 {@link AlgorithmParameterSpec}通常用于加盐或偏移向量
*
* @param params {@link AlgorithmParameterSpec}
* @return this
*/
public CipherWrapper setParams(final AlgorithmParameterSpec params) {
this.params = params;
return this;
}
/**
* 设置随机数生成器可自定义随机数种子
*
* @param random 随机数生成器可自定义随机数种子
* @return this
*/
public CipherWrapper setRandom(final SecureRandom random) {
this.random = random;
return this;
}
/**
* 获取被包装的{@link Cipher}
*
* @return {@link Cipher}
*/
@Override
public Cipher getRaw() {
return this.cipher;
}
/**
* 初始化{@link Cipher}为加密或者解密模式
*
* @param mode 模式{@link Cipher#ENCRYPT_MODE} {@link Cipher#DECRYPT_MODE}
* @param key 密钥
* @return this
* @throws InvalidKeyException 无效key
* @throws InvalidAlgorithmParameterException 无效算法
*/
public CipherWrapper initMode(final int mode, final Key key)
throws InvalidKeyException, InvalidAlgorithmParameterException {
final Cipher cipher = this.cipher;
final AlgorithmParameterSpec params = this.params;
final SecureRandom random = this.random;
if (null != params) {
if (null != random) {
cipher.init(mode, key, params, random);
} else {
cipher.init(mode, key, params);
}
} else {
if (null != random) {
cipher.init(mode, key, random);
} else {
cipher.init(mode, key);
}
}
return this;
}
}

View File

@ -0,0 +1,134 @@
/*
* Copyright (c) 2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.wrapper.Wrapper;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
/**
* 提供{@link javax.crypto.Cipher}的方法包装
*
* @author Looly
*/
public class JceCipher implements Cipher, Wrapper<javax.crypto.Cipher> {
private final javax.crypto.Cipher cipher;
/**
* 构造
*
* @param algorithm 算法名称
*/
public JceCipher(final String algorithm) {
this(SecureUtil.createCipher(algorithm));
}
/**
* 构造
*
* @param cipher {@link javax.crypto.Cipher}
*/
public JceCipher(final javax.crypto.Cipher cipher) {
this.cipher = cipher;
}
@Override
public javax.crypto.Cipher getRaw() {
return this.cipher;
}
@Override
public String getAlgorithmName() {
return this.cipher.getAlgorithm();
}
@Override
public int getBlockSize() {
return this.cipher.getBlockSize();
}
@Override
public void init(final CipherMode mode, final Parameters parameters) {
Assert.isInstanceOf(JceParameters.class, parameters, "Only support JceParameters!");
try {
init(mode.getValue(), (JceParameters) parameters);
} catch (final InvalidAlgorithmParameterException | InvalidKeyException e) {
throw new CryptoException(e);
}
}
/**
* 执行初始化参数操作
*
* @param mode 模式
* @param jceParameters {@link JceParameters}
* @throws InvalidAlgorithmParameterException 无效算法参数
* @throws InvalidKeyException 无效key
*/
public void init(final int mode, final JceParameters jceParameters) throws InvalidAlgorithmParameterException, InvalidKeyException {
final javax.crypto.Cipher cipher = this.cipher;
if (null != jceParameters.parameterSpec) {
if (null != jceParameters.random) {
cipher.init(mode, jceParameters.key, jceParameters.parameterSpec, jceParameters.random);
} else {
cipher.init(mode, jceParameters.key, jceParameters.parameterSpec);
}
} else {
if (null != jceParameters.random) {
cipher.init(mode, jceParameters.key, jceParameters.random);
} else {
cipher.init(mode, jceParameters.key);
}
}
}
@Override
public byte[] process(final byte[] data) {
return new byte[0];
}
/**
* JCE的{@link AlgorithmParameterSpec} 参数包装
*/
public static class JceParameters implements Parameters {
private final Key key;
/**
* 算法参数
*/
private final AlgorithmParameterSpec parameterSpec;
/**
* 随机数生成器可自定义随机数种子
*/
private final SecureRandom random;
/**
* 构造
*
* @param key 密钥
* @param parameterSpec {@link AlgorithmParameterSpec}
* @param random 自定义随机数生成器
*/
public JceParameters(final Key key, final AlgorithmParameterSpec parameterSpec, final SecureRandom random) {
this.key = key;
this.parameterSpec = parameterSpec;
this.random = random;
}
}
}

View File

@ -54,5 +54,10 @@ public enum Mode {
/**
* Propagating Cipher Block
*/
PCBC
PCBC,
/**
* GCM 全称为 Galois/Counter ModeG是指GMACC是指CTR
* 它在 CTR 加密的基础上增加 GMAC 的特性解决了 CTR 不能对加密消息进行完整性校验的问题
*/
GCM
}

View File

@ -14,10 +14,7 @@ package org.dromara.hutool.crypto.asymmetric;
import org.dromara.hutool.core.codec.binary.Base64;
import org.dromara.hutool.core.io.stream.FastByteArrayOutputStream;
import org.dromara.hutool.crypto.CipherWrapper;
import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.KeyUtil;
import org.dromara.hutool.crypto.SecureUtil;
import org.dromara.hutool.crypto.*;
import org.dromara.hutool.crypto.symmetric.SymmetricAlgorithm;
import javax.crypto.BadPaddingException;
@ -51,8 +48,7 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
/**
* Cipher负责完成加密或解密工作
*/
protected CipherWrapper cipherWrapper;
protected JceCipher cipher;
/**
* 加密的块大小
*/
@ -61,6 +57,15 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* 解密的块大小
*/
protected int decryptBlockSize = -1;
/**
* 算法参数
*/
private AlgorithmParameterSpec algorithmParameterSpec;
/**
* 自定义随机数
*/
private SecureRandom random;
// ------------------------------------------------------------------ Constructor start
/**
@ -209,7 +214,7 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @since 5.4.3
*/
public AlgorithmParameterSpec getAlgorithmParameterSpec() {
return this.cipherWrapper.getParams();
return this.algorithmParameterSpec;
}
/**
@ -217,10 +222,11 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* 在某些算法中需要特别的参数例如在ECIES中此处为IESParameterSpec
*
* @param algorithmParameterSpec {@link AlgorithmParameterSpec}
* @since 5.4.3
* @return this
*/
public void setAlgorithmParameterSpec(final AlgorithmParameterSpec algorithmParameterSpec) {
this.cipherWrapper.setParams(algorithmParameterSpec);
public AsymmetricCrypto setAlgorithmParameterSpec(final AlgorithmParameterSpec algorithmParameterSpec) {
this.algorithmParameterSpec = algorithmParameterSpec;
return this;
}
/**
@ -231,7 +237,7 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @since 5.7.17
*/
public AsymmetricCrypto setRandom(final SecureRandom random) {
this.cipherWrapper.setRandom(random);
this.random = random;
return this;
}
@ -301,7 +307,7 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @since 5.4.3
*/
public Cipher getCipher() {
return this.cipherWrapper.getRaw();
return this.cipher.getRaw();
}
/**
@ -310,7 +316,7 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @since 4.5.2
*/
protected void initCipher() {
this.cipherWrapper = new CipherWrapper(this.algorithm);
this.cipher = new JceCipher(this.algorithm);
}
/**
@ -376,6 +382,9 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @throws InvalidKeyException 异常KEY错误
*/
private Cipher initMode(final int mode, final Key key) throws InvalidAlgorithmParameterException, InvalidKeyException {
return this.cipherWrapper.initMode(mode, key).getRaw();
final JceCipher cipher = this.cipher;
cipher.init(mode,
new JceCipher.JceParameters(key, this.algorithmParameterSpec, this.random));
return cipher.getRaw();
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2024. looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* https://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.bc;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.crypto.Cipher;
import org.dromara.hutool.crypto.CipherMode;
import org.dromara.hutool.crypto.CryptoException;
/**
* 基于BouncyCastle库的{@link BufferedBlockCipher}封装的加密解密实现
*
* @author Looly, changhr2013
*/
public class BCCipher implements Cipher {
/**
* {@link BufferedBlockCipher}包含enginemodepadding
*/
private final BufferedBlockCipher blockCipher;
/**
* 构造
*
* @param blockCipher {@link BufferedBlockCipher}
*/
public BCCipher(final BufferedBlockCipher blockCipher) {
this.blockCipher = blockCipher;
}
@Override
public String getAlgorithmName() {
return this.blockCipher.getUnderlyingCipher().getAlgorithmName();
}
@Override
public int getBlockSize() {
return this.blockCipher.getBlockSize();
}
@Override
public void init(final CipherMode mode, final Parameters parameters) {
Assert.isInstanceOf(BCParameters.class, parameters, "Only support BCParameters!");
this.blockCipher.init(mode == CipherMode.encrypt, ((BCParameters) parameters).parameters);
}
@Override
public byte[] process(final byte[] data) {
final byte[] out;
try {
final BufferedBlockCipher cipher = this.blockCipher;
final int updateOutputSize = cipher.getOutputSize(data.length);
final byte[] buf = new byte[updateOutputSize];
int len = cipher.processBytes(data, 0, data.length, buf, 0);
len += cipher.doFinal(buf, len);
out = new byte[len];
System.arraycopy(buf, 0, out, 0, len);
} catch (final Exception e) {
throw new CryptoException("encrypt/decrypt process exception.", e);
}
return out;
}
/**
* BouncyCastle库的{@link CipherParameters}封装
*
* @author Looly
*/
public static class BCParameters implements Parameters {
/**
* 算法的参数
*/
private final CipherParameters parameters;
/**
* 构造
*
* @param parameters {@link CipherParameters}
*/
public BCParameters(final CipherParameters parameters) {
this.parameters = parameters;
}
}
}

View File

@ -15,10 +15,19 @@ package org.dromara.hutool.crypto.bc;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.DefaultBufferedBlockCipher;
import org.bouncycastle.crypto.modes.*;
import org.bouncycastle.crypto.paddings.ISO10126d2Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.crypto.Mode;
import org.dromara.hutool.crypto.Padding;
import java.io.IOException;
import java.security.PrivateKey;
@ -41,10 +50,10 @@ public class BCUtil {
*/
public static ECDomainParameters toDomainParams(final ECParameterSpec parameterSpec) {
return new ECDomainParameters(
parameterSpec.getCurve(),
parameterSpec.getG(),
parameterSpec.getN(),
parameterSpec.getH());
parameterSpec.getCurve(),
parameterSpec.getG(),
parameterSpec.getN(),
parameterSpec.getH());
}
/**
@ -67,10 +76,10 @@ public class BCUtil {
*/
public static ECDomainParameters toDomainParams(final X9ECParameters x9ECParameters) {
return new ECDomainParameters(
x9ECParameters.getCurve(),
x9ECParameters.getG(),
x9ECParameters.getN(),
x9ECParameters.getH()
x9ECParameters.getCurve(),
x9ECParameters.getG(),
x9ECParameters.getN(),
x9ECParameters.getH()
);
}
@ -81,7 +90,7 @@ public class BCUtil {
* @return PKCS#1格式私钥
* @since 5.5.9
*/
public static byte[] toPkcs1(final PrivateKey privateKey){
public static byte[] toPkcs1(final PrivateKey privateKey) {
final PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(privateKey.getEncoded());
try {
return pkInfo.parsePrivateKey().toASN1Primitive().getEncoded();
@ -97,13 +106,53 @@ public class BCUtil {
* @return PKCS#1格式公钥
* @since 5.5.9
*/
public static byte[] toPkcs1(final PublicKey publicKey){
public static byte[] toPkcs1(final PublicKey publicKey) {
final SubjectPublicKeyInfo spkInfo = SubjectPublicKeyInfo
.getInstance(publicKey.getEncoded());
.getInstance(publicKey.getEncoded());
try {
return spkInfo.parsePublicKey().getEncoded();
} catch (final IOException e) {
throw new IORuntimeException(e);
}
}
/**
* {@link BlockCipher}包装为指定mode和padding的{@link BufferedBlockCipher}
*
* @param cipher {@link BlockCipher}
* @param mode 模式
* @param padding 补码方式
* @return {@link BufferedBlockCipher}无对应Cipher返回{@code null}
* @since 6.0.0
*/
public static BufferedBlockCipher wrap(BlockCipher cipher, final Mode mode, final Padding padding) {
switch (mode) {
case CBC:
cipher = CBCBlockCipher.newInstance(cipher);
break;
case CFB:
cipher = CFBBlockCipher.newInstance(cipher, cipher.getBlockSize() * 8);
break;
case CTR:
cipher = SICBlockCipher.newInstance(cipher);
break;
case OFB:
cipher = new OFBBlockCipher(cipher, cipher.getBlockSize() * 8);
case CTS:
return new CTSBlockCipher(cipher);
}
switch (padding) {
case NoPadding:
return new DefaultBufferedBlockCipher(cipher);
case PKCS5Padding:
return new PaddedBufferedBlockCipher(cipher);
case ZeroPadding:
return new PaddedBufferedBlockCipher(cipher, new ZeroBytePadding());
case ISO10126Padding:
return new PaddedBufferedBlockCipher(cipher, new ISO10126d2Padding());
}
return null;
}
}

View File

@ -52,7 +52,15 @@ import java.util.concurrent.locks.ReentrantLock;
public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor, Serializable {
private static final long serialVersionUID = 1L;
private CipherWrapper cipherWrapper;
private JceCipher cipher;
/**
* 算法参数
*/
private AlgorithmParameterSpec algorithmParameterSpec;
/**
* 自定义随机数
*/
private SecureRandom random;
/**
* SecretKey 负责保存对称密钥
*/
@ -157,7 +165,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
this.isZeroPadding = true;
}
this.cipherWrapper = new CipherWrapper(algorithm);
this.cipher = new JceCipher(algorithm);
return this;
}
@ -176,17 +184,17 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @return 加密或解密
*/
public Cipher getCipher() {
return cipherWrapper.getRaw();
return cipher.getRaw();
}
/**
* 设置 {@link AlgorithmParameterSpec}通常用于加盐或偏移向量
* 设置{@link AlgorithmParameterSpec}通常用于加盐或偏移向量
*
* @param params {@link AlgorithmParameterSpec}
* @return 自身
* @param algorithmParameterSpec {@link AlgorithmParameterSpec}
* @return this
*/
public SymmetricCrypto setParams(final AlgorithmParameterSpec params) {
this.cipherWrapper.setParams(params);
public SymmetricCrypto setAlgorithmParameterSpec(final AlgorithmParameterSpec algorithmParameterSpec) {
this.algorithmParameterSpec = algorithmParameterSpec;
return this;
}
@ -197,7 +205,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @return 自身
*/
public SymmetricCrypto setIv(final IvParameterSpec iv) {
return setParams(iv);
return setAlgorithmParameterSpec(iv);
}
/**
@ -218,7 +226,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @since 5.7.17
*/
public SymmetricCrypto setRandom(final SecureRandom random) {
this.cipherWrapper.setRandom(random);
this.random = random;
return this;
}
@ -263,7 +271,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @since 5.6.8
*/
public byte[] update(final byte[] data) {
final Cipher cipher = cipherWrapper.getRaw();
final Cipher cipher = this.cipher.getRaw();
lock.lock();
try {
return cipher.update(paddingDataWithZero(data, cipher.getBlockSize()));
@ -417,8 +425,8 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
*/
private SymmetricCrypto initParams(final String algorithm, AlgorithmParameterSpec paramsSpec) {
if (null == paramsSpec) {
byte[] iv = Opt.ofNullable(cipherWrapper)
.map(CipherWrapper::getRaw).map(Cipher::getIV).get();
byte[] iv = Opt.ofNullable(cipher)
.map(JceCipher::getRaw).map(Cipher::getIV).get();
// 随机IV
if (StrUtil.startWithIgnoreCase(algorithm, "PBE")) {
@ -435,7 +443,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
}
}
return setParams(paramsSpec);
return setAlgorithmParameterSpec(paramsSpec);
}
/**
@ -455,10 +463,14 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
.getKeyAndIV(secretKey.getEncoded(), salt);
secretKey = KeyUtil.generateKey(algorithm, keyAndIV[0]);
if(ArrayUtil.isNotEmpty(keyAndIV[1])){
this.cipherWrapper.setParams(new IvParameterSpec(keyAndIV[1]));
setAlgorithmParameterSpec(new IvParameterSpec(keyAndIV[1]));
}
}
return this.cipherWrapper.initMode(mode, secretKey).getRaw();
final JceCipher cipher = this.cipher;
cipher.init(mode,
new JceCipher.JceParameters(secretKey, this.algorithmParameterSpec, this.random));
return cipher.getRaw();
}
/**