import org.apache.commons.codec.binary.Base64;
import com.sansec.impl.device.softdigest.SM3Digest;
public class SM3Hmac {
private static final int BLOCK_LENGTH = 64;
private static String startKey="";
public static byte[] SM3HashMac(String text,String key){
key=startKey+key;
//1.填充0至key,或者hashkey,使其长度为sm3分组长度
/** BLOCK_LENGTHSM3分组长度 ,64个字节,512位*/
byte[] sm3_key;
byte[] structured_key=new byte[BLOCK_LENGTH];
byte[] IPAD=new byte[BLOCK_LENGTH];
byte[] OPAD=new byte[BLOCK_LENGTH];
if( Base64.decodeBase64(key).length>BLOCK_LENGTH){
sm3_key= sm3Hash(Base64.decodeBase64(key));
System.arraycopy(sm3_key,0,structured_key,0,sm3_key.length);
}else {
System.arraycopy(Base64.decodeBase64(key),0,structured_key,0,Base64.decodeBase64(key).length);
}
//2.让处理之后的key 与ipad (分组长度的0x36)做异或运算
for(int i=0;i<BLOCK_LENGTH;i++){
IPAD[i]=0x36;
OPAD[i]=0x5c;
}
byte[] ipadkey=XOR(structured_key,IPAD);
//3.将2的结果与text拼接
int textLen=text.getBytes().length;
byte[] t3=new byte[BLOCK_LENGTH+textLen];
System.arraycopy(ipadkey,0,t3,0,ipadkey.length);
System.arraycopy(text.getBytes(),0,t3,ipadkey.length,text.getBytes().length);
//4.将3的结果sm3 哈希
byte[] t4=sm3Hash(t3);
//5.让处理之后的key 与opad(分组长度的0x5c)做异或运算
byte[] opadkey=XOR(structured_key,OPAD);
//6.4的结果拼接在5之后
byte[] t6=new byte[BLOCK_LENGTH+t4.length];
System.arraycopy(opadkey,0,t6,0,opadkey.length);
System.arraycopy(t4,0,t6,opadkey.length,t4.length);
//7.对6做hash
return (sm3Hash(t6));
}
private static byte[] sm3Hash(byte[] srcData) {
SM3Digest digest = new SM3Digest();
digest.update(srcData,0,srcData.length);
byte[] hash = new byte[digest.getDigestSize()];
digest.doFinal(hash,0);
return hash;
}
/**
* 异或算法加密/解密
*
* @param data 数据(密文/明文)
* @param key 密钥
* @return 返回解密/加密后的数据
*/
public static byte[] XOR(byte[] key,byte[] data ) {
if (data == null || data.length == 0 || key == null || key.length == 0) {
return data;
}
byte[] result = new byte[data.length];
// 使用密钥字节数组循环加密或解密
for (int i = 0; i < data.length; i++) {
// 数据与密钥异或, 再与循环变量的低8位异或(增加复杂度)
result[i] = (byte) (data[i] ^ key[i % key.length] ^ (i & 0xFF));
}
return result;
}
public static void main(String[] args) {
byte[] sm3HashMac = SM3HashMac("123456123456", "111111111111111111111111");
System.out.println(Base64.encodeBase64String(sm3HashMac));
byte[] sm3HashMac1 = SM3HashMac("123456123456", "111111111111111111111111");
System.out.println(Base64.encodeBase64String(sm3HashMac1));
byte[] sm3HashMac2 = SM3HashMac("1234567", "11111");
System.out.println(Base64.encodeBase64String(sm3HashMac2));
byte[] sm3HashMac3 = SM3HashMac("123456", "11111");
System.out.println(Base64.encodeBase64String(sm3HashMac3));
}
}