Skip to content

Instantly share code, notes, and snippets.

@BlueYing
Created June 14, 2016 02:47
Show Gist options
  • Save BlueYing/8347a3bbf1c9ee7036fa5b2bc4e6f1eb to your computer and use it in GitHub Desktop.
Save BlueYing/8347a3bbf1c9ee7036fa5b2bc4e6f1eb to your computer and use it in GitHub Desktop.
hmacSM3
public class hmacSM3{
/**
* 做hmacSM3运算
*
* @param data 原文
* @param key 密钥
* @return 做hmacSM3运算的结果值
*/
private static byte[] hmacSM3(byte[] data, byte[] key) {
byte[] oPad = xor(key,(byte) 0x5c,64);
byte[] iPad = xor(key,(byte) 0x36,64);
byte[] ikeypad = new byte[data.length+64];
System.arraycopy(iPad,0,ikeypad,0,64);
System.arraycopy(data,0,ikeypad,64,data.length);
byte[] hash1 = SM3Strategy.createSign(ikeypad);
byte[] okeypad = new byte[hash1.length+64];
System.arraycopy(oPad,0,okeypad,0,64);
System.arraycopy(hash1,0,okeypad,64,hash1.length);
return SM3Strategy.createSign(okeypad);
}
private static byte[] xor(byte[] a1,byte a2,int length){
byte[] result = new byte[length];
for (int i=0 ; i< a1.length;i++){
result[i] = (byte) (a1[i] ^ a2);
}
for(int i= a1.length;i<length;i++){
result[i] = a2;
}
return result;
}
}
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.util.Arrays;
public class SM3Alg {
private static class SingletonHolder {
private static final SM3Alg INSTANCE = new SM3Alg();
}
public static final SM3Alg getInstance() {
return SingletonHolder.INSTANCE;
}
private static final byte[] FIRSTPADDING = new byte[] { (byte) -128 };
private static final byte[] ZEROPADDING = new byte[1];
private static final String IVHEXSTR = "7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e";
private static final BigInteger IV = new BigInteger(IVHEXSTR.replaceAll(
" ", ""), 16);
private static final char[] CHARS = new char[] { '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static final Integer TJ15 = Integer.valueOf("79cc4519", 16);
private static final Integer TJ63 = Integer.valueOf("7a879d8a", 16);
private byte[] padding(byte[] source) throws Exception {
long l = (long) (source.length * 8);
long k = 448L - (l + 1L) % 512L;
if (k < 0L) {
k += 512L;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(source);
baos.write(FIRSTPADDING);
for (long i = k - 7L; i > 0L; i -= 8L) {
baos.write(ZEROPADDING);
}
baos.write(long2bytes(l));
return baos.toByteArray();
}
private static byte[] long2bytes(long l) {
byte[] bytes = new byte[8];
for (int i = 0; i < 8; ++i) {
bytes[i] = (byte) ((int) (l >>> (7 - i) * 8));
}
return bytes;
}
private byte[] CF(byte[] vi, byte[] bi) throws Exception {
int a = this.toInteger(vi, 0);
int b = this.toInteger(vi, 1);
int c = this.toInteger(vi, 2);
int d = this.toInteger(vi, 3);
int e = this.toInteger(vi, 4);
int f = this.toInteger(vi, 5);
int g = this.toInteger(vi, 6);
int h = this.toInteger(vi, 7);
int[] w = new int[68];
int[] w1 = new int[64];
int ss1;
for (ss1 = 0; ss1 < 16; ++ss1) {
w[ss1] = this.toInteger(bi, ss1);
}
for (ss1 = 16; ss1 < 68; ++ss1) {
w[ss1] = this.P1(
Integer.valueOf(w[ss1 - 16] ^ w[ss1 - 9]
^ Integer.rotateLeft(w[ss1 - 3], 15))).intValue()
^ Integer.rotateLeft(w[ss1 - 13], 7) ^ w[ss1 - 6];
}
for (ss1 = 0; ss1 < 64; ++ss1) {
w1[ss1] = w[ss1] ^ w[ss1 + 4];
}
for (int v = 0; v < 64; ++v) {
ss1 = Integer.rotateLeft(
Integer.rotateLeft(a, 12) + e
+ Integer.rotateLeft(this.T(v), v), 7);
int ss2 = ss1 ^ Integer.rotateLeft(a, 12);
int tt1 = this.FF(Integer.valueOf(a), Integer.valueOf(b),
Integer.valueOf(c), v).intValue()
+ d + ss2 + w1[v];
int tt2 = this.GG(Integer.valueOf(e), Integer.valueOf(f),
Integer.valueOf(g), v).intValue()
+ h + ss1 + w[v];
d = c;
c = Integer.rotateLeft(b, 9);
b = a;
a = tt1;
h = g;
g = Integer.rotateLeft(f, 19);
f = e;
e = this.P0(Integer.valueOf(tt2)).intValue();
}
byte[] var19 = this.toByteArray(a, b, c, d, e, f, g, h);
for (int i = 0; i < var19.length; ++i) {
var19[i] ^= vi[i];
}
return var19;
}
private int toInteger(byte[] source, int index) {
StringBuilder valueStr = new StringBuilder("");
for (int i = 0; i < 4; ++i) {
valueStr.append(CHARS[(byte) ((source[index * 4 + i] & 240) >> 4)]);
valueStr.append(CHARS[(byte) (source[index * 4 + i] & 15)]);
}
return Long.valueOf(valueStr.toString(), 16).intValue();
}
private Integer P1(Integer x) throws Exception {
return Integer.valueOf(x.intValue()
^ Integer.rotateLeft(x.intValue(), 15)
^ Integer.rotateLeft(x.intValue(), 23));
}
private int T(int j) throws Exception {
if (j >= 0 && j <= 15) {
return TJ15.intValue();
} else if (j >= 16 && j <= 63) {
return TJ63.intValue();
} else {
throw new Exception();
}
}
private Integer FF(Integer x, Integer y, Integer z, int j) throws Exception {
if (j >= 0 && j <= 15) {
return Integer.valueOf(x.intValue() ^ y.intValue() ^ z.intValue());
} else if (j >= 16 && j <= 63) {
return Integer.valueOf(x.intValue() & y.intValue() | x.intValue()
& z.intValue() | y.intValue() & z.intValue());
} else {
throw new Exception();
}
}
private Integer GG(Integer x, Integer y, Integer z, int j) throws Exception {
if (j >= 0 && j <= 15) {
return Integer.valueOf(x.intValue() ^ y.intValue() ^ z.intValue());
} else if (j >= 16 && j <= 63) {
return Integer.valueOf(x.intValue() & y.intValue() | ~x.intValue()
& z.intValue());
} else {
throw new Exception();
}
}
private Integer P0(Integer x) throws Exception {
return Integer.valueOf(x.intValue()
^ Integer.rotateLeft(x.intValue(), 9)
^ Integer.rotateLeft(x.intValue(), 17));
}
private byte[] toByteArray(int a, int b, int c, int d, int e, int f, int g,
int h) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream(32);
baos.write(this.toByteArray(a));
baos.write(this.toByteArray(b));
baos.write(this.toByteArray(c));
baos.write(this.toByteArray(d));
baos.write(this.toByteArray(e));
baos.write(this.toByteArray(f));
baos.write(this.toByteArray(g));
baos.write(this.toByteArray(h));
return baos.toByteArray();
}
private byte[] toByteArray(int i) {
byte[] byteArray = new byte[] { (byte) (i >>> 24),
(byte) ((i & 16777215) >>> 16), (byte) ((i & '\uffff') >>> 8),
(byte) (i & 255) };
return byteArray;
}
public byte[] digest(byte[] text) throws Exception {
byte[] m1 = this.padding(text);
int n = m1.length / 64;
byte[] vi = IV.toByteArray();
byte[] vi1 = null;
for (int i = 0; i < n; ++i) {
byte[] var8 = Arrays.copyOfRange(m1, i * 64, (i + 1) * 64);
vi1 = this.CF(vi, var8);
vi = vi1;
}
return vi1;
}
}
import SM3Alg;
public class SM3Strategy {
public static byte[] createSign(byte[] explicit) {
if ((explicit != null) && (explicit.length > 0)) {
try {
SM3Alg sm3 = SM3Alg.getInstance();
return sm3.digest(explicit);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
}
@maobon
Copy link

maobon commented Oct 13, 2021

Amazing .... Cool ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment