
com.github.joekerouac.common.tools.crypto.CipherSpi Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
* file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package com.github.joekerouac.common.tools.crypto;
import java.security.Provider;
import java.security.SecureRandom;
import java.util.Arrays;
import com.github.joekerouac.common.tools.crypto.constant.CipherDesc;
/**
* 加密接口
*
* @since 1.0.0
* @author JoeKerouac
*/
public interface CipherSpi extends AlgorithmSpi {
/**
* 加密模式
*/
int ENCRYPT_MODE = 1;
/**
* 解密模式
*/
int DECRYPT_MODE = 2;
int WRAP_MODE = 3;
int UNWRAP_MODE = 4;
/**
* 获取加解密模式,{@link #ENCRYPT_MODE}表示加密模式,{@link #DECRYPT_MODE}表示解密
*
* @return 加解密模式
*/
int getMode();
/**
* 初始化密钥
*
* @param key
* 加密密钥
* @param iv
* IV,目前对于非GCM模式允许为空
* @param mode
* 密码器模式,1表示加密模式,2表示解密模式
*/
default void init(byte[] key, byte[] iv, int mode) {
init(key, iv, mode, new SecureRandom());
}
/**
* 初始化密钥
*
* @param key
* 加密密钥
* @param iv
* IV,目前对于非GCM模式允许为空
* @param mode
* 密码器模式,1表示加密模式,2表示解密模式
* @param secureRandom
* 安全随机数
*/
void init(byte[] key, byte[] iv, int mode, SecureRandom secureRandom);
/**
* 获取块大小
*
* @return 块大小
*/
int getBlockSize();
/**
* 对长度len的数据进行加解密,得到的结果长度,如果是加密模式,那么返回要加密数据长度+tagLen,如果是解密模式,返回要解密数据长度-tagLen
*
* @param len
* 原始数据长度
* @return 加密后的数据长度
*/
int getOutputSize(int len);
/**
* 认证数据长度,只有GCM模式才会有,GCM模式会在加密数据的最后补充上该长度的认证数据
*
* @return 认证数据长度,不是GCM模式返回0,GCM模式返回其对应的认证数据长度,目前应该都是16
*/
int getTagLen();
/**
* 更新附加认证信息(注意,这里和{@link #getTagLen()})方法中说的认证数据不是一个概念,{@link #getTagLen()}中说的是GCM自带计算的认证 信息,而这个是在加密前人为添加的认证信息
*
* @param data
* 认证信息,该方法必须在{@link #update(byte[])}方法和{@link #doFinal()}之前调用(再加密实际数据前)
*/
void updateAAD(byte[] data);
/**
* 追加更新内容
*
* @param data
* 追加更新的加密内容
*/
default byte[] update(byte[] data) {
return update(data, 0, data.length);
}
/**
* 追加更新内容
*
* @param data
* 数据
* @param offset
* 起始位置
* @param len
* 长度
*/
default byte[] update(byte[] data, int offset, int len) {
int outputSize = getOutputSize(len);
byte[] result = new byte[outputSize];
int resultLen = update(data, offset, len, result, 0);
// GCM模式下update返回的resultLen是固定0,在调用doFinal的时候才会将结果一次性输出,因为GCM模式还有一个附加的认证信息需要计算或者校验
if (resultLen != outputSize) {
return Arrays.copyOfRange(result, 0, resultLen);
} else {
return result;
}
}
/**
* 追加更新
*
* @param data
* 待加密数据
* @param offset
* 起始位置
* @param len
* 长度
* @param result
* 存放加密结果的数组
* @param resultOffset
* 结果写入存放加密数据数组的起始位置
* @return 写入result中的数据的长度,也就是加密结果长度
*/
int update(byte[] data, int offset, int len, byte[] result, int resultOffset);
/**
* 最终加密处理
*
* @param data
* 待加密数据
* @return 加密结果
*/
default byte[] doFinal(byte[] data) {
return doFinal(data, 0, data.length);
}
/**
* 最终处理
*
* @param data
* 待加密数据
* @param offset
* 起始位置
* @param len
* 长度
* @return 加密结果
*/
default byte[] doFinal(byte[] data, int offset, int len) {
byte[] result = new byte[getOutputSize(len)];
int resultLen = doFinal(data, offset, len, result, 0);
// 对于padding模式的加密,这里是不相等的
if (resultLen != result.length) {
return Arrays.copyOfRange(result, 0, resultLen);
}
return result;
}
/**
* 最终加密处理
*
* @return AES模式下返回认证数据长度,长度等于{@link #getTagLen() 认证数据长度}
*/
byte[] doFinal();
/**
* 结束加密
*
* @param data
* 待加密数据,不允许为null
* @param offset
* 起始位置
* @param len
* 长度
* @param result
* 存放加密结果的数组,不允许为null
* @param resultOffset
* 结果写入存放加密数据数组的起始位置
* @return 写入result中的数据的长度,也就是加密结果长度
*/
int doFinal(byte[] data, int offset, int len, byte[] result, int resultOffset);
/**
* 获取provider
*
* @return provider
*/
Provider provider();
@Override
default int type() {
return AlgorithmSpi.CIPHER;
}
static CipherSpi getInstance(CipherDesc algorithm) {
return AlgorithmRegistry.newInstance("alias.cipher." + algorithm.name());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy