init files
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum AlgorithmType {
|
||||
|
||||
// DES 加密
|
||||
ENCRYPT_DES,
|
||||
// DES 解密
|
||||
DECRYPT_DES,
|
||||
// AES 加密
|
||||
ENCRYPT_AES,
|
||||
// AES 解密
|
||||
DECRYPT_AES,
|
||||
// SSF33 加密
|
||||
ENCRYPT_SSF33,
|
||||
// SSF33 解密
|
||||
DECRYPT_SSF33,
|
||||
// SM1 加密
|
||||
ENCRYPT_SM1,
|
||||
// SM1 解密
|
||||
DECRYPT_SM1,
|
||||
// SM4 加密
|
||||
ENCRYPT_SM4,
|
||||
// SM4 解密
|
||||
DECRYPT_SM4,
|
||||
// IDEA 加密
|
||||
ENCRYPT_IDEA,
|
||||
// IDEA 解密
|
||||
DECRYPT_IDEA,
|
||||
// AES256 加密
|
||||
ENCRYPT_AES256,
|
||||
// AES256 解密
|
||||
DECRYPT_AES256,
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public enum CMD {
|
||||
|
||||
// 加解密
|
||||
ENCRYPTION_DECRYPTION("E0");
|
||||
|
||||
private String value;
|
||||
|
||||
public ByteBuffer getValue() {
|
||||
return ByteBuffer.wrap(value.getBytes());
|
||||
}
|
||||
|
||||
CMD(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum DataType {
|
||||
|
||||
// 二进制
|
||||
BIN,
|
||||
// 十六进制编码的二进制
|
||||
HEX,
|
||||
// 文本格式
|
||||
TXT
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum FullEndType {
|
||||
|
||||
/**
|
||||
* 填充数据的最后一个字节不填充计数位。解
|
||||
密后的数据包含填充数据,由应用摘取实际数据。
|
||||
*/
|
||||
WITH_END,
|
||||
/**
|
||||
* 填充数据的最后一个字节填充计数位。计数
|
||||
位取值在 0x01 to 0x08/ 0x10 之间。解密后
|
||||
的数据由加密机根据 Pad count flag 值在内部自
|
||||
动去掉填充数据
|
||||
*/
|
||||
AUTO_END,
|
||||
|
||||
/**
|
||||
* pkcs5和 pkcs7 填充
|
||||
*/
|
||||
PKCS5_PKCS7
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
/**
|
||||
*/
|
||||
public enum FullMode {
|
||||
|
||||
/**
|
||||
* 如果数据块长度为 8/16 的整数倍,不需要填
|
||||
充;如果长度不为 8/16 的整数倍,填充至长度满
|
||||
8/16 的整数倍(填充方式按 Pad character 域中
|
||||
描述的规则进行,由加密机内部自动完成)
|
||||
*/
|
||||
FULL_8_16,
|
||||
/**
|
||||
* 如果数据块长度为 8/16 的整数倍,填充一个
|
||||
整 8/16 字节的数据(填充方式按 Pad character
|
||||
域中描述的规则进行,由加密机内部自动完成);
|
||||
如果长度不为8/16的整数倍,填充至长度满8/16
|
||||
的整数倍(填充方式按 Pad character 域中描述
|
||||
的规则进行,由加密机内部自动完成)
|
||||
*/
|
||||
FULL_MORE_8_16
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum KeyType {
|
||||
|
||||
// LMK 加密的 ZEK (区域加密密钥)
|
||||
ZEK,
|
||||
// LMK 加密的 TEK ()
|
||||
TEK,
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
public enum PackType {
|
||||
|
||||
// 唯一块
|
||||
ONLY,
|
||||
// 起始块
|
||||
HEAD,
|
||||
// 中间块
|
||||
MIDDLE,
|
||||
// 结束块
|
||||
TAIL
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
import com.sunyard.proto.Util;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* 生成包序号,不负责销毁。
|
||||
* 相同设备 sn 轮转
|
||||
* 不同设备 sn 无关
|
||||
*/
|
||||
public class PacketSN {
|
||||
|
||||
private static HashMap<String, SN> keeper = new HashMap<String, SN>();
|
||||
|
||||
private ByteBuffer sn;
|
||||
private String devid;
|
||||
|
||||
public static PacketSN gen(String devid){
|
||||
|
||||
// 申请小锁
|
||||
SN sn = keeper.get(devid);
|
||||
if ( null == sn){
|
||||
// 申请全局锁
|
||||
synchronized (PacketSN.class){
|
||||
SN snCheck = keeper.get(devid);
|
||||
if( null == snCheck){
|
||||
keeper.put(devid, new SN());
|
||||
sn = keeper.get(devid);
|
||||
}else{
|
||||
sn = snCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new PacketSN(sn.next(), devid);
|
||||
}
|
||||
|
||||
public static PacketSN gen(){
|
||||
return gen("default");
|
||||
}
|
||||
|
||||
public PacketSN(ByteBuffer sn, String devid) {
|
||||
this.sn = sn;
|
||||
this.devid = devid;
|
||||
}
|
||||
|
||||
public ByteBuffer getSn() {
|
||||
return sn;
|
||||
}
|
||||
|
||||
public String getDevid() {
|
||||
return devid;
|
||||
}
|
||||
|
||||
public String getGlobalId(){
|
||||
return devid + "-" + Util.bytes2HexString(sn.array());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SN {
|
||||
private long sn = 0;
|
||||
|
||||
synchronized ByteBuffer next(){
|
||||
ByteBuffer bb = ByteBuffer.allocate(8);
|
||||
bb.put((byte) ((sn >>> 56) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 48) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 40) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 32) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 24) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 16) & 0xFF));
|
||||
bb.put((byte) ((sn >>> 8) & 0xFF));
|
||||
bb.put((byte) (sn & 0xFF));
|
||||
sn += 1;
|
||||
return bb;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.sunyard.trans;
|
||||
|
||||
|
||||
public enum RoundType {
|
||||
|
||||
// 占位
|
||||
DO_NOT_USE,
|
||||
// 电子密码本
|
||||
ECB,
|
||||
// 密码块连接
|
||||
CBC,
|
||||
// 分组长度密码反馈
|
||||
CFB,
|
||||
// 分组长度输出反馈
|
||||
OFB
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
package com.sunyard.trans.pkg;
|
||||
|
||||
import com.sunyard.trans.FullMode;
|
||||
import com.sunyard.SydApiException;
|
||||
import com.sunyard.proto.Util;
|
||||
import com.sunyard.trans.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class DataEncryptDecryptPacket extends Packet {
|
||||
|
||||
// 包类型
|
||||
private int packType;
|
||||
// 算法标记
|
||||
private int alg;
|
||||
// 轮类型
|
||||
private int round;
|
||||
// 密钥类型
|
||||
private int keyType;
|
||||
// 密钥
|
||||
private byte[] key;
|
||||
// 输入数据类型
|
||||
private int inDataType;
|
||||
// 输出数据类型
|
||||
private int outDataType;
|
||||
// 填充模式
|
||||
private int fullMode;
|
||||
// 填充字符
|
||||
private String fullCharacter;
|
||||
// 填充类型
|
||||
private int fullEndType;
|
||||
/**
|
||||
* 消息类型影响消息长度(若消息类型为二进制,则为
|
||||
* 随后域长度;若消息类型为扩展十六进制,则为随后
|
||||
* 域长度的一半)。默认是 BIN
|
||||
*/
|
||||
private int messageType;
|
||||
|
||||
// 消息数据
|
||||
private byte[] message;
|
||||
|
||||
|
||||
public DataEncryptDecryptPacket() {
|
||||
this.setCommand(CMD.ENCRYPTION_DECRYPTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataEncryptDecryptPacket clone(){
|
||||
DataEncryptDecryptPacket subPack = new DataEncryptDecryptPacket();
|
||||
subPack.setCommand(getCommand());
|
||||
subPack.setHeader(getHeader());
|
||||
subPack.setPackType(packType);
|
||||
subPack.setAlg(alg);
|
||||
subPack.setRound(round);
|
||||
subPack.setKeyType(keyType);
|
||||
subPack.setKey(key);
|
||||
subPack.setInDataType(inDataType);
|
||||
subPack.setOutDataType(outDataType);
|
||||
subPack.setFullMode(fullMode);
|
||||
subPack.setFullCharacter(fullCharacter);
|
||||
subPack.setFullEndType(fullEndType);
|
||||
return subPack;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始向量
|
||||
* 仅当密钥加密轮函数类型为 CBC ,CFB ,OFB 时有此域。
|
||||
* 当密钥模式为 DES加解密 该域为 16H
|
||||
* 当密钥模式为 AES SSF33 SM1 加解密时,该域为 32H
|
||||
*/
|
||||
private byte[] iv = new byte[0];
|
||||
|
||||
|
||||
public void setKeyType(KeyType keyType) {
|
||||
this.keyType = keyType.ordinal();
|
||||
}
|
||||
|
||||
|
||||
public void setRoundType(RoundType roundType) {
|
||||
this.round = roundType.ordinal();
|
||||
}
|
||||
|
||||
public void setPackType(PackType type) {
|
||||
this.packType = type.ordinal();
|
||||
}
|
||||
|
||||
public void setAlgType(AlgorithmType type){
|
||||
this.alg = type.ordinal();
|
||||
}
|
||||
|
||||
public void setKey(byte[] key){
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
||||
public void setIv(byte[] iv) {
|
||||
if ( RoundType.CBC.ordinal() == round
|
||||
|| RoundType.CFB.ordinal() == round
|
||||
|| RoundType.OFB.ordinal() == round
|
||||
){
|
||||
if( AlgorithmType.ENCRYPT_DES.ordinal() == keyType
|
||||
|| AlgorithmType.DECRYPT_DES.ordinal() == keyType
|
||||
){
|
||||
if( 16 != iv.length ){
|
||||
throw new SydApiException(65535);
|
||||
}
|
||||
}else{
|
||||
if( 32 != iv.length ){
|
||||
throw new SydApiException(65535);
|
||||
}
|
||||
}
|
||||
this.iv = iv;
|
||||
}
|
||||
throw new SydApiException(65535);
|
||||
|
||||
}
|
||||
|
||||
public void setInDataType(DataType dataType) {
|
||||
this.inDataType = dataType.ordinal();
|
||||
}
|
||||
|
||||
public void setOutDataType(DataType dataType) {
|
||||
this.outDataType = dataType.ordinal();
|
||||
}
|
||||
|
||||
public void setFullMode(FullMode mode,FullEndType endType, String firstChar, String otherChar){
|
||||
this.fullMode = mode.ordinal();
|
||||
this.fullCharacter = firstChar + otherChar;
|
||||
this.fullEndType = endType.ordinal();
|
||||
}
|
||||
|
||||
public void setMessage(DataType type , byte[] message) {
|
||||
this.message = message;
|
||||
this.messageType = type.ordinal();
|
||||
}
|
||||
|
||||
public void setMessage(byte[] message) {
|
||||
setMessage(DataType.BIN, message);
|
||||
}
|
||||
|
||||
private ByteBuffer toSubPack(){
|
||||
ByteBuffer bb = ByteBuffer.allocate(MAX_PACKAGE_DATA_LEN);
|
||||
bb.put( Util.int2charbyte16(packType) );
|
||||
bb.put( Util.int2charbyte16(alg) );
|
||||
bb.put( Util.int2charbyte16(round) );
|
||||
bb.put( Util.int2charbyte16(keyType));
|
||||
bb.put( key );
|
||||
bb.put( Util.int2charbyte16(inDataType) );
|
||||
bb.put( Util.int2charbyte16(outDataType) );
|
||||
if ( 0 == packType || 3 == packType ){
|
||||
bb.put( Util.int2charbyte16(fullMode) );
|
||||
bb.put( fullCharacter.getBytes() );
|
||||
bb.put( Util.int2charbyte16(fullEndType));
|
||||
}
|
||||
bb.put(iv);
|
||||
int msgLen = message.length;
|
||||
if ( DataType.HEX.ordinal() == messageType ){
|
||||
msgLen = msgLen/2;
|
||||
}
|
||||
bb.put(String.format("%03X", msgLen).getBytes());
|
||||
bb.put(message);
|
||||
|
||||
this.setData(bb);
|
||||
|
||||
return this.pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer toSendPack(PacketSN sn) {
|
||||
|
||||
setHeader(sn.getSn());
|
||||
|
||||
// 依据数据长度的不同可能需要分包
|
||||
int packLen = 2048;
|
||||
int inDataLen = this.message.length;
|
||||
// 拆包数量
|
||||
int loop = inDataLen / packLen;
|
||||
if ( 0 != inDataLen % packLen ){
|
||||
loop += 1;
|
||||
}
|
||||
|
||||
ByteBuffer bb = ByteBuffer.allocate( packLen * loop );
|
||||
|
||||
int i = 0;
|
||||
while ( i < loop){
|
||||
|
||||
DataEncryptDecryptPacket subPack = this.clone();
|
||||
if ( 0 == i){
|
||||
if ( 1 == loop){
|
||||
subPack.setPackType(PackType.ONLY);
|
||||
}else{
|
||||
subPack.setPackType(PackType.HEAD);
|
||||
}
|
||||
}else{
|
||||
if ( (loop - 1) == i){
|
||||
subPack.setPackType(PackType.TAIL);
|
||||
}else{
|
||||
subPack.setPackType(PackType.MIDDLE);
|
||||
}
|
||||
}
|
||||
|
||||
// 唯一包
|
||||
if ( 1 == loop){
|
||||
subPack.setMessage(this.message);
|
||||
}else{
|
||||
byte[] tMsg = new byte[packLen];
|
||||
// 最后一个包
|
||||
if ( (loop - 1) == i){
|
||||
System.arraycopy(this.message, i * packLen , tMsg, 0, this.message.length % packLen);
|
||||
}else{ // 其他包
|
||||
System.arraycopy(this.message, i * packLen , tMsg, 0, packLen);
|
||||
}
|
||||
subPack.setMessage(tMsg);
|
||||
}
|
||||
|
||||
bb.put( subPack.toSubPack() );
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// POJO set
|
||||
|
||||
public void setPackType(int packType) {
|
||||
this.packType = packType;
|
||||
}
|
||||
|
||||
public void setAlg(int alg) {
|
||||
this.alg = alg;
|
||||
}
|
||||
|
||||
public void setRound(int round) {
|
||||
this.round = round;
|
||||
}
|
||||
|
||||
public void setKeyType(int keyType) {
|
||||
this.keyType = keyType;
|
||||
}
|
||||
|
||||
public void setInDataType(int inDataType) {
|
||||
this.inDataType = inDataType;
|
||||
}
|
||||
|
||||
public void setOutDataType(int outDataType) {
|
||||
this.outDataType = outDataType;
|
||||
}
|
||||
|
||||
public void setFullMode(int fullMode) {
|
||||
this.fullMode = fullMode;
|
||||
}
|
||||
|
||||
public void setFullCharacter(String fullCharacter) {
|
||||
this.fullCharacter = fullCharacter;
|
||||
}
|
||||
|
||||
public void setFullEndType(int fullEndType) {
|
||||
this.fullEndType = fullEndType;
|
||||
}
|
||||
|
||||
public void setMessageType(int messageType) {
|
||||
this.messageType = messageType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.sunyard.trans.pkg;
|
||||
|
||||
|
||||
import com.sunyard.trans.CMD;
|
||||
import com.sunyard.trans.PacketSN;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* SJJ1316 加密机通用格式
|
||||
*/
|
||||
public abstract class Packet {
|
||||
|
||||
public static final int MAX_PACKAGE_DATA_LEN = 8192;
|
||||
public static final int MAX_PACKAGE_LEN = MAX_PACKAGE_DATA_LEN + 10;
|
||||
|
||||
|
||||
private ByteBuffer header;
|
||||
private ByteBuffer command;
|
||||
private ByteBuffer data;
|
||||
private ByteBuffer length;
|
||||
|
||||
|
||||
|
||||
public abstract ByteBuffer toSendPack(PacketSN sn);
|
||||
|
||||
|
||||
public ByteBuffer getHeader() {
|
||||
return header;
|
||||
}
|
||||
|
||||
public ByteBuffer getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public void setCommand(CMD cmd) {
|
||||
this.command = cmd.getValue();
|
||||
}
|
||||
|
||||
public void setCommand(ByteBuffer command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public void setHeader(ByteBuffer header){
|
||||
this.header = header;
|
||||
}
|
||||
|
||||
public void setData(ByteBuffer data){
|
||||
this.data = data;
|
||||
int len = data.array().length + 8 + 2;
|
||||
header.put(0, (byte) (len / 256));
|
||||
header.put(1, (byte) (len % 256));
|
||||
}
|
||||
|
||||
|
||||
public ByteBuffer pack(){
|
||||
ByteBuffer bb = ByteBuffer.allocate(MAX_PACKAGE_LEN);
|
||||
// 长度占位
|
||||
bb.put(length);
|
||||
// head 占位
|
||||
bb.put(header);
|
||||
// command 占位
|
||||
bb.put(command);
|
||||
// data
|
||||
bb.put(data);
|
||||
|
||||
return bb;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user