Description
JAVA bouncycastle 签名:
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;
public class SM2Sign {
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final String PRIVATE_KEY_HEX = "55855c26d046fb36f5808b890477c0475288aad304d233a7aa8b6aa3c06518e8";
// SM2签名
public static String sign(String message) throws Exception {
byte[] data = message.getBytes("UTF-8");
String signValue = null;
SM2Signer signer = new SM2Signer();
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
//构造domain参数
ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
CipherParameters param = new ParametersWithRandom(new ECPrivateKeyParameters(new BigInteger(PRIVATE_KEY_HEX, 16), domainParameters));
signer.init(true, param);
signer.update(data, 0, data.length);
signValue = Hex.toHexString(signer.generateSignature());
return signValue;
}
}`
python gmssl验签:
`def verify_signature(message, signValue) -> bool:
# 将16进制公钥和签名转换为字节
# 假设公钥是16进制字符串(示例值,需替换为实际公钥)
# SM2公钥格式为04 + X坐标 + Y坐标(共130字符,如04开头)
PUBLIC_KEY_HEX = "04a8431884a374059f2a37763e4cecd13a0875854d515f160b99ceb91788c16d4d81cf02db83842646f41f3196dd0a7855478a90e6553ba9749efde29f4dd835bc"
if not message or not signValue:
return False
# 加载公钥
# 创建SM2对象
# 确保公钥以0x04开头(未压缩格式)
sm2_crypt = sm2.CryptSM2(public_key=PUBLIC_KEY_HEX, private_key=None)
data_bytes = message.encode('utf-8')
return sm2_crypt.verify(signValue, data_bytes)`