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; } }