package com.commsoft.tsm.app.api.util;
public class ISOIEC9797 {
private static int[] scf_intxor(String data){
try {
byte[] bytes = Convert.hexStringToBytes(data);
int[] scfint = new int[bytes.length];
for(int i = 0;i<scfint.length;i++){
scfint[i] = bytes[i] & 0xff;
}
return scfint;
} catch (Exception e) {
return null;
}
}
/**异或运算方法**/
public static String scf_XOR(String data1,String data2){
int[] byteint1 = scf_intxor(data1);
int[] byteint2 = scf_intxor(data2);
StringBuffer str = new StringBuffer();
int len = byteint1.length;
int i = 0;
while (i < len) {
int b = byteint1[i]^byteint2[i];
str.append(Convert.bytesToHexString(Convert.gdlongtobyte(b, 1)));
i++;
}
return str.toString();
}
/**
* 单DES加密函数,输入 key /data 为16进制
* mode:0表示ecb,1表示cbc
* 默认 IV = '0000000000000000'
* padding = '8000……',只有在长度不是8的整数倍时才填充
* **/
public static String scf_desenc(String key,String data,int mode,String iv){
byte[] result = null;
try {
if(key.length() == 16 && key.length() <=2048){
byte[] sData = Convert.hexStringToBytes(data);
byte[] sKey = Convert.hexStringToBytes(key);
byte[] siv = Convert.hexStringToBytes(iv);
if(mode == 0){
result = DES.ECBEncrypt(sData, sKey, siv);
}else if(mode == 1){
result = DES.CBCEncrypt(sData, sKey, siv);
}
}
}catch (Exception e) {
e.printStackTrace();
}
return Convert.bytesToHexString(result);
}
/**
* 单DES解密函数,输入 key /data 为16进制
* mode:0表示ecb,1表示cbc
* 默认 IV = '0000000000000000'
* padding = '8000……',只有在长度不是8的整数倍时才填充
* **/
public static String scf_desdec(String key,String data,int mode,String iv){
byte[] result = null;
try {
if(key.length() == 16 && key.length() <=2048){
byte[] sData = Convert.hexStringToBytes(data);
byte[] sKey = Convert.hexStringToBytes(key);
byte[] siv = Convert.hexStringToBytes(iv);
if(mode == 0){
result = DES.ECBDecrypt(sData, sKey, siv);
}else if(mode == 1){
result = DES.CBCDecrypt(sData, sKey, siv);
}
}
}catch (Exception e) {
e.printStackTrace();
}
return Convert.bytesToHexString(result);
}
/**
* 3DES加密函数
* mode:0表示ecb,1表示cbc
* 默认 IV = '0000000000000000'
* padding = '8000……',只有在长度不是8的整数倍时才填充
* **/
public static String scf_tdesenc(String key,String data,int mode,String iv){
byte[] result = null;
try {
if(key.length() == 32 && key.length() <= 2048){
byte[] sData = Convert.hexStringToBytes(data);
byte[] sKey = Convert.hexStringToBytes(key);
byte[] siv = Convert.hexStringToBytes(iv);
if(mode == 0){
result = DES.ECB_3DesEncry(sData, sKey, siv);
}else if(mode == 1){
result = DES.CBC_3DesEncry(sData, sKey, siv);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return Convert.bytesToHexString(result);
}
/**
* 3DES解密函数
* mode:0表示ecb,1表示cbc
* 默认 IV = '0000000000000000'
* padding = '8000……',只有在长度不是8的整数倍时才填充
* **/
public static String scf_tdesdec(String key,String data,int mode,String iv){
byte[] result = null;
try {
if(key.length() == 32 && key.length() <= 2048){
byte[] sData = Convert.hexStringToBytes(data);
byte[] sKey = Convert.hexStringToBytes(key);
byte[] siv = Convert.hexStringToBytes(iv);
if(mode == 0){
result = DES.ECB_3DesDecry(sData, sKey, siv);
}else if(mode == 1){
result = DES.CBC_3DesDecry(sData, sKey, siv);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return Convert.bytesToHexString(result);
}
/**
* 单DESMAC 计算函数
* **/
public static String scf_desmac(String key,String data,String iv){
byte[] result = null;
try {
if(key.length() == 16 && key.length() <=2048){
byte[] sKey = Convert.hexStringToBytes(key);
byte[] sData = Convert.hexStringToBytes(data);
byte[] sIv = Convert.hexStringToBytes(iv);
result = Mac.desmac(sData, sKey, sIv);
}
} catch (Exception e) {
e.printStackTrace();
}
return Convert.bytesToHexString(result).substring(0, 8);
}
/**
* 3DESMAC 计算函数
* **/
public static String scf_tdesmac(String key,String data,String iv){
byte[] result = null;
try {
if(key.length() == 32 && key.length() <=2048){
byte[] sKey = Convert.hexStringToBytes(key);
byte[] sData = Convert.hexStringToBytes(data);
byte[] sIv = Convert.hexStringToBytes(iv);
result = Mac.tdesmac(sData, sKey, sIv);
}
} catch (Exception e) {
e.printStackTrace();
}
return Convert.bytesToHexString(result).substring(0, 8);
}
/**
* 3DES计算MAC(hex)
* PBOC_3DES_MAC(16的整数补8000000000000000)
* 前n-1组使用单长密钥DES 使用密钥是密钥的左8字节)
* 最后1组使用双长密钥3DES (使用全部16字节密钥)
* @param key 密钥(32byte)
* @param vector初始向量 默认0000000000000000
* @param data 数据 (16进制的数据)
* @return mac(前4个字节,8位)
*/
public static String PBOC_3DES_MAC(String key,String data, String vector){
if (key.length()!=32){
return null;
}
int len = data.length();
int arrLen = len / 16 + 1;
String[] D = new String[arrLen];
if (vector == null)
vector = "0000000000000000";
if (len % 16 == 0) {
data += "8000000000000000";
} else {
data += "80";
for (int i = 0; i < 15 - len % 16; i++) {
data += "00";
}
}
for (int i = 0; i < arrLen; i++) {
D[i] = data.substring(i * 16, i * 16 + 16);
}
// D0 Xor Vector
String I = scf_XOR(D[0], vector);
String O = null;
String kl = key.substring(0, 16);
String IV = "0000000000000000";
for (int i = 1; i < arrLen; i++) {
O = scf_desenc(kl, I, 0, IV);
I = scf_XOR(D[i], O);
}
I = scf_tdesenc(key, I, 0, IV);
return I.substring(0, 8);
}
/**
* ISO9797算法
* mactype
* padtype 数据填充类型
* icv 16 进制字符串 初始化向量 ,默认‘0000000000000000’
* key 16 进制字符串 秘钥
* data 16进制的字符串数据
* alg 值为TDES || DES
* **/
public static String scf_isoiec9797(int mactype,int padtype,String icv,String key,String data,String alg){
try {
icv = icv.replace(" ", "");
key = key.replace(" ", "");
data = data.replace(" ", "");
String cbuff = icv;
/**秘钥长度错误**/
if(mactype >=3 && key.length() != 32){
return null;
}
/**处理数据填充方式**/
if(padtype == 1){
//填充方式为1时,当数据不足8字节,在数据右边补00
while (data.length() % 16 != 0) {
data = data +"00";
}
}else if(padtype == 2){
//填充方式为2时,现在数据后补一个80 ,在判断是否为8字节,不足就补00
data = data +"80";
while (data.length() % 16 != 0) {
data = data +"00";
}
}else if(padtype == 3){
long l = data.length()/2 * 8;
String tl = Convert.bytesToHexString(Convert.gdlongtobyte(l, 4));
tl = Convert.rjust(tl, 16,'0');//右对齐 补 0
data = tl + data;
while (data.length() % 16 != 0) {
data = data +"00";
}
}else{
return null;
}
//处理Mac 计算方式
String dret = "";
if(mactype == 1){
if(alg.equals("TDES")){
dret = scf_tdesenc(key, data, 1, "0000000000000000");
return dret;
}else{
cbuff = scf_basicdesmac(key, icv, data, "DES");
}
}else if(mactype == 2){
cbuff = scf_basicdesmac(key, icv, data, "DES");
String ckey3 = scf_getkey3(key);
cbuff = scf_desenc(ckey3, cbuff, 0, "0000000000000000");
}else if(mactype == 3){
String lkey = key.substring(0,16);
String rkey = key.substring(16,32);
if(alg.equals("TDES")){
cbuff = scf_basicdesmac(lkey, icv, data, "