Open musicguoke opened 2 years ago
非常感谢,搞了半天看到您的方案终于解决了。👍
关于 hexStr 可以简化成以下的方法调用:
String hexStr = HexUtil.encodeHexStr(sm2.getQ(false));
后端解密的时候还是用的原始私钥进行解密吗?按照上面的方法,后端目前一直解码出错
后端解密的时候还是用的原始私钥进行解密吗?按照上面的方法,后端目前一直解码出错
SM2 sm2 = SmUtil.sm2(privateKey, null);
String requestBody = sm2.decryptStr("04" + requestBody, KeyType.PrivateKey);
可以用生成的Base64编码的私钥构造sm2对象来解密,需要在密文前加上04前缀
使用 SM2 和 SM4 实现的数字信封前后端数据传输加解密。
SM2 部分实现,如下。详情参见:代码
class SM2Utilities {
private static instance = new SM2Utilities();
private cipherMode = 1; // 1 - C1C3C2,0 - C1C2C3
private constructor() {}
public static getInstance(): SM2Utilities {
return this.instance;
}
public createKeyPair() {
return sm2.generateKeyPairHex();
}
public encrypt(content: string, publicKey: string) {
return '04' + sm2.doEncrypt(content, publicKey, this.cipherMode);
}
public decrypt(content: string, privateKey: string) {
let data = content.substring(2).toLocaleLowerCase();
return sm2.doDecrypt(data, privateKey, this.cipherMode);
}
}
@Override
public SecretKey createSecretKey() {
// 随机生成秘钥
SM2 sm2 = SmUtil.sm2();
// sm2的加解密时有两种方式即 C1C2C3、 C1C3C2,
sm2.setMode(SM2Engine.Mode.C1C3C2);
// 生成私钥
String privateKey = HexUtil.encodeStr(ECKeyUtil.encodeECPrivateKey(sm2.getPrivateKey()));
// 生成公钥
String publicKey = HexUtil.encodeStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false));
SecretKey secretKey = new SecretKey();
secretKey.setPrivateKey(privateKey);
secretKey.setPublicKey(publicKey);
return secretKey;
}
@Override
public String decrypt(String content, String privateKey) {
// 可用的 Hutool SM2 解密
SM2 sm2 = SmUtil.sm2(privateKey, null);
sm2.setMode(SM2Engine.Mode.C1C3C2);
String result = StrUtil.utf8Str(sm2.decrypt(content, KeyType.PrivateKey));
log.trace("[Herodotus] |- SM2 crypto decrypt data, value is : [{}]", result);
return result;
}
@Override
public String encrypt(String content, String publicKey) {
SM2 sm2 = SmUtil.sm2(null, publicKey);
String result = sm2.encryptHex(content, KeyType.PublicKey);
log.trace("[Herodotus] |- SM2 crypto encrypt data, value is : [{}]", result);
return result;
}
问题的原因
通常由于网上找的js端提供的 SM2代码实现的方案, 都是直接使用的私钥的d值和公钥的q值直接进行的加解密 所以后端口返回的最好是从公钥里面提取的q值,以q值做为js端的加密公钥
前端使用publicKey加密步骤