注:
- 仅适用没有java JCE证书的情况,最好还是申请一张签名证书。申请地址:获取JCE签名证书
- 请提前了解BouncyCastle轻量级加密套件
- 请提前了解HMAC
- 了解ClassLoader原理
一、有JCE签名证书的情况
直接修改SM3.java文件,添加几个方法即可。
1 | /** |
至此,从新打包BC,签名即可使用。
二、无JCE签名证书,外部挂载
新建一个项目,导入bcprov的jar包
新建
SM3和DigestAlgorithmProvider类将BC中的相同类源码复制到新建类中,主要是
DigestAlgorithmProvider类不是public的,所以需要重写一下。编写测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46import java.security.MessageDigest;
import java.security.Security;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
public class HmacTest {
static byte[] keyBytes = Hex.decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b");
static byte[] message = Hex.decode("4869205468657265");
public static void main(String[] args) throws Exception {
BouncyCastleProvider bcp = new BouncyCastleProvider();
Security.addProvider(bcp);
new SM3.Mappings().configure(bcp);
for (String s : Security.getAlgorithms("Mac")) {
if (s.contains("HMACSM3")) {
System.out.println(true);
break;
}
}
HmacTest hmactest = new HmacTest();
hmactest.testHMac("HMAC-SM3");
}
public void testHMac(String hmacName) throws Exception {
SecretKey key = new SecretKeySpec(keyBytes, hmacName);
byte[] out,out1;
// SM3
MessageDigest sm3 = MessageDigest.getInstance("SM3", "BC");
out1 = sm3.digest(message);
System.out.println(Hex.toHexString(out1));
// HMAC-SM3
Mac mac = Mac.getInstance(hmacName, "BC");
mac.init(key);
mac.reset();
mac.update(message, 0, message.length);
out = mac.doFinal();
System.out.println(Hex.toHexString(out));
}
}
其中遇到的问题:
需要了解JCE的调用过程和BC实现的相关方法
DigestAlgorithmProvider抽象类中的方法都是protected方法,需要在外部重写。bcprov.jar不能放到java/jre/ext中,因为会loadSM3$Hmac.class,不然会报如下Exception。所以jar要和class使用相同的classloader。
1
2
3
4
5
6
7
8
9
10
11
12
13
14Exception in thread "main" java.security.NoSuchAlgorithmException: class configured for Mac (provider: BC) cannot be found.
at java.security.Provider$Service.getImplClass(Provider.java:1649)
at java.security.Provider$Service.newInstance(Provider.java:1592)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
at javax.crypto.JceSecurity.getInstance(JceSecurity.java:103)
at javax.crypto.Mac.getInstance(Mac.java:222)
at cn.com.infosec.HmacSM3.HmacTest.testHMac(HmacTest.java:37)
at cn.com.infosec.HmacSM3.HmacTest.main(HmacTest.java:30)
Caused by: java.lang.ClassNotFoundException: com.gsealy.HmacSM3.SM3X$HashMac
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.security.Provider$Service.getImplClass(Provider.java:1636)
... 6 more结束!🔚
