Closed aZuo0817 closed 1 year ago
为什么要给密文前面补充 04 呢?还是说你加密出来的密文本身就是 04 开头的解密不成功?
加密出来的密文本身就是04开头的,然后解密不成功
那方便给下具体的用例么,我本地来试试
我用的下面这个方法进行sm2加密,然后再前端解密,就会失败
import lombok.extern.slf4j.Slf4j; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.params.*; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom;
/**
@return 密文,BC库产生的密文带由04标识符,与非BC库对接时需要去掉开头的04 */ public static String encrypt(String publicKey, String data, int cipherMode){ // 获取一条SM2曲线参数 X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1"); // 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数N ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN()); //提取公钥点 ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey)); // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04 ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
SM2EngineExtend sm2Engine = new SM2EngineExtend(); // 设置sm2为加密模式 sm2Engine.init(true, cipherMode, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
byte[] arrayOfBytes = null;
try {
byte[] in = data.getBytes();
arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
} catch (Exception e) {
log.error("SM2加密时出现异常:{}", e.getMessage(), e);
}
return Hex.toHexString(arrayOfBytes);
}
我是按照这份标准来实现的,按道理只要其他语言库也是按照标准来应该可以互通:https://github.com/JuneAndGreen/sm-crypto/blob/master/docs/SM2%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E5%85%AC%E9%92%A5%E5%AF%86%E7%A0%81%E7%AE%97%E6%B3%95.pdf 有差异也应该是参数或者实现模式的差异导致。
用 java BC 库互通的话,我自己没有实现过,不过看线上似乎已经有人做过了,比如可以考虑参考下 https://github.com/lpilp/forhuahua 或 https://juejin.cn/post/7084038026971578398 ?
使用BC库进行加密的密文存在04开头,去掉04即可
生成的SM2密文中的C1
部分是公钥的坐标点,其格式是非压缩的,那么应该以标志位04
开头。
SM2加密算法的国标GB/T 32918.4-2016
中给出的密文示例均以04
开头。
该问题会影响到与其它国密算法组件,比如BouncyCastle和TencentKonaSMSuite,的交互。 如果出于兼容性的考量,不去解决这个问题。那么也应该在文档中说明一下,以提示用户自己去处理这个问题。
生成的SM2密文中的
C1
部分是公钥的坐标点,其格式是非压缩的,那么应该以标志位04
开头。 SM2加密算法的国标GB/T 32918.4-2016
中给出的密文示例均以04
开头。该问题会影响到与其它国密算法组件,比如BouncyCastle和TencentKonaSMSuite,的交互。 如果出于兼容性的考量,不去解决这个问题。那么也应该在文档中说明一下,以提示用户自己去处理这个问题。
因为之前并没有支持压缩公钥,所以默认都是非压缩的
生成的SM2密文中的
C1
部分是公钥的坐标点,其格式是非压缩的,那么应该以标志位04
开头。 SM2加密算法的国标GB/T 32918.4-2016
中给出的密文示例均以04
开头。该问题会影响到与其它国密算法组件,比如BouncyCastle和TencentKonaSMSuite,的交互。 如果出于兼容性的考量,不去解决这个问题。那么也应该在文档中说明一下,以提示用户自己去处理这个问题。
文档也补充了
刚刚注意到这一句提示:ps:密文会在解密时自动追加 04,如遇到其他工具追加的 04 需手动去除再传入。
不过,追加一般是指在末尾处添加,但在此处,实际上是在起始处插入04
。
另外,要求用户手动将开头处的04
删除,似乎对开发与性能均不友好。
sm2解密方法里面,在密文前面补充了04,对于04开头的密文,就会解密失败,所以是不是要判断密文是不是04开头的