前后端联调sm2加密的坑Invalid point encoding
1.公私钥问题
Invalid point encoding
私钥前加00,密文前加04,公钥前加04
后端使用hutool
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.12</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
后端生成公私钥,公钥已带有04,私钥已带有00
SM2 sm2=new SM2();
BCECPrivateKey privateKey = (BCECPrivateKey) (sm2.getPrivateKey());
//私钥对应D值,EC为椭圆算法
//hutool-all-5.7.12-sources.jar!/cn/hutool/crypto/asymmetric/SM2.java:90
//hutool-all-5.7.12-sources.jar!/cn/hutool/crypto/ECKeyUtil.java:346
BigInteger d = privateKey.getD();
BCECPublicKey publicKey = (BCECPublicKey) sm2.getPublicKey();
//公钥对应Q值
//hutool-all-5.7.12-sources.jar!/cn/hutool/crypto/asymmetric/SM2.java:90
//hutool-all-5.7.12-sources.jar!/cn/hutool/crypto/ECKeyUtil.java:379
ECPoint q = publicKey.getQ();
String hutoolPrivateKeyHex = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(privateKey));
String hutoolPublicKeyHex = HexUtil.encodeHexStr(q.getEncoded(false));
D,Q是什么
sm2为椭圆算法
公钥对应Q值
私钥对应D值
hutool算法,先尝试D值=>再尝试PKCS#8=>尝试PKCS#1
hutool源码
public static ECPrivateKeyParameters decodePrivateKeyParams(byte[] privateKeyBytes) {
try {
// 尝试D值
return toSm2PrivateParams(privateKeyBytes);
} catch (Exception ignore) {
// ignore
}
PrivateKey privateKey;
//尝试PKCS#8
try {
privateKey = KeyUtil.generatePrivateKey("sm2", privateKeyBytes);
} catch (Exception ignore) {
// 尝试PKCS#1
privateKey = KeyUtil.generatePrivateKey("sm2", createOpenSSHPrivateKeySpec(privateKeyBytes));
}
return toPrivateParams(privateKey);
}