SM2解密时,兼容GmSSL非压缩省略的04头的密文

This commit is contained in:
Looly
2024-09-05 13:23:37 +08:00
parent c9cac93337
commit 38911594c8
7 changed files with 146 additions and 21 deletions

View File

@@ -31,6 +31,7 @@ import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.crypto.signers.StandardDSAEncoding;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.encoders.Hex;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.crypto.CryptoException;
@@ -313,7 +314,20 @@ public class SM2 extends AbstractAsymmetricCrypto<SM2> {
* @throws CryptoException 包括InvalidKeyException和InvalidCipherTextException的包装异常
* @since 5.1.6
*/
public byte[] decrypt(final byte[] data, final CipherParameters privateKeyParameters) throws CryptoException {
public byte[] decrypt(byte[] data, final CipherParameters privateKeyParameters) throws CryptoException {
Assert.isTrue(data.length > 1, "Invalid SM2 cipher text, must be at least 1 byte long");
// 检查数据gmssl等库生成的密文不包含04前缀非压缩数据标识此处检查并补充
// 参考https://blog.csdn.net/softt/article/details/139978608
// 根据公钥压缩形态不同,密文分为两种压缩形式:
// C1( 03 + X ) + C332个字节+ C2
// C1( 02 + X ) + C332个字节+ C2
// 非压缩公钥正常形态为04 + X + Y由于各个算法库差异04有时候会省略
// 非压缩密文正常形态为04 + C1 + C3 + C2
if (data[0] != 0x04 && data[0] != 0x02 && data[0] != 0x03) {
// 默认非压缩形态
data = ArrayUtil.insert(data, 0, 0x04);
}
lock.lock();
final SM2Engine engine = getEngine();
try {

View File

@@ -32,6 +32,8 @@ import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* SM2算法单元测试
*
@@ -333,4 +335,17 @@ public class SM2Test {
Assertions.assertNotNull(sm1);
Assertions.assertNotNull(sm2);
}
@Test
void decryptFromGmSSLTest() {
// https://the-x.cn/zh-cn/cryptography/Sm2.aspx
// python gmssl加密后的内容无04标识检查并补充
final String privateKey = "MHcCAQEEICxTSOhWA4oYj2DI95zunPqHHEKZSi5QFLvWz57BfIGVoAoGCCqBHM9VAYItoUQDQgAEIGRS/PssvgZ8Paw2YeFaW4VXrkgceBELKPWcXmq/p3iMhHxYfcaFAa5AzvPJOmYmVzVwu9QygMMrg/30Ok1npw==";
final SM2 sm2 = new SM2(privateKey, null);
sm2.setMode(SM2Engine.Mode.C1C2C3);
final String encrypt = "x0KA1DKkmuA/YZdmvMr8X+1ZQb7a19Pr5nSxxe2ItUYpDAioa263tm9u7vST38hAEUoOxxXftD+7bRQ7Y8v1tcFXeheKodetA6LrPIuh0QYZMdBqIKSKdmlGeVE0Vdm3excisbtC";
final byte[] decrypt = sm2.decrypt(encrypt, KeyType.PrivateKey);
assertEquals("123456", StrUtil.utf8Str(decrypt));
}
}