登录
原创

java SM2签名和验签

发布于 2020-10-26 阅读 6628
  • 后端
  • 算法
  • Java
原创

SM2签名也是通过私钥签名,公钥验签,这里的私钥格式可以是pkcs#1,pkcs#8,公钥格式可以是pkcs1和X509格式,这里只介绍标准的格式,公钥X509格式,私钥是pkcs#8格式,其他格式的需要进一步转换
这里需要借助BouncyCastle实现

//签名
public byte[] sign(byte[] message,byte[] privateKey,String withId) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        ECPrivateKey ecPrivateKey = (ECPrivateKey) KeyFactory.getInstance("EC", new BouncyCastleProvider())
            .generatePrivate(new PKCS8EncodedKeySpec(privateKey));
        ECPrivateKeyParameters privateKeyParameters = getPrivateKeyParameters(ecPrivateKey);
        SM2Signer signer = new SM2Signer();
        ParametersWithRandom pwr = new ParametersWithRandom(privateKeyParameters, new SecureRandom());
        CipherParameters param;
        if (withId== null) {
            param = pwr;
        } else {
            param = new ParametersWithID(pwr, WITH_ID.getBytes());
        }
        signer.init(true, param);
        signer.update(message, 0, message.length);
        return signer.generateSignature();
    }

    private ECPrivateKeyParameters getPrivateKeyParameters(ECPrivateKey ecPrivateKey) {
        ECParameterSpec parameterSpec = ecPrivateKey.getParameters();
        ECCurve curve = parameterSpec.getCurve();
        ECPoint g = parameterSpec.getG();
        BigInteger n = parameterSpec.getN();
        BigInteger h = parameterSpec.getH();
        ECDomainParameters domainParams = new ECDomainParameters(curve, g, n, h);
        return new ECPrivateKeyParameters(ecPrivateKey.getD(), domainParams);
    }

//验签
    public boolean verifySign(byte[] sign,byte[] publicKey,String withId) throws Exception {
        Security.addProvider(new BouncyCastleProvider()); 
        String message = objects[2].toString();
        ECPublicKey ecPublicKey = (ECPublicKey) KeyFactory.getInstance("EC", new BouncyCastleProvider())
            .generatePublic(new X509EncodedKeySpec(publicKey));
        ECPublicKeyParameters ecPublicKeyParameters = getPublicKeyParameters(ecPublicKey);
        SM2Signer signer = new SM2Signer();
        CipherParameters param;
        if (withId== null) {
            param = ecPublicKeyParameters;
        } else {
            param = new ParametersWithID(ecPublicKeyParameters, WITH_ID.getBytes());
        }
        byte[] messageByte = message.getBytes(StandardCharsets.UTF_8);
        signer.init(false, param);
        signer.update(messageByte, 0, messageByte.length);
        return signer.verifySignature(sign);
    }

    private ECPublicKeyParameters getPublicKeyParameters(ECPublicKey ecPublicKey) {
        ECParameterSpec parameterSpec = ecPublicKey.getParameters();
        ECCurve curve = parameterSpec.getCurve();
        ECPoint g = parameterSpec.getG();
        BigInteger n = parameterSpec.getN();
        BigInteger h = parameterSpec.getH();
        ECDomainParameters domainParams = new ECDomainParameters(curve, g, n, h);
        return new ECPublicKeyParameters(ecPublicKey.getQ(), domainParams);
    }

评论区

梦飞
0粉丝

励志做一条安静的咸鱼,从此走上人生巅峰。

0

0

0

举报