SM2密钥交换

SM2密钥交换

代码拆解(只做记录)
1.创建曲线(标准曲线)
public class SM2Util extends SM2GennerateKeyPair{
    /** 素数p */
    public static final BigInteger p = new BigInteger("FFFFFFFE" + "FFFFFFFF"
            + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF"
            + "FFFFFFFF", 16);

    /** 系数a */
    public static final BigInteger a = new BigInteger("FFFFFFFE" + "FFFFFFFF"
            + "FFFFFFFF" + "FFFFFFFF" + "FFFFFFFF" + "00000000" + "FFFFFFFF"
            + "FFFFFFFC", 16);

    /** 系数b */
    public static final BigInteger b = new BigInteger("28E9FA9E" + "9D9F5E34"
            + "4D5A9E4B" + "CF6509A7" + "F39789F5" + "15AB8F92" + "DDBCBD41"
            + "4D940E93", 16);

    /** 坐标x */
    public static final BigInteger xg = new BigInteger("32C4AE2C" + "1F198119"
            + "5F990446" + "6A39C994" + "8FE30BBF" + "F2660BE1" + "715A4589"
            + "334C74C7", 16);

    /** 坐标y */
    public static final BigInteger yg = new BigInteger("BC3736A2" + "F4F6779C"
            + "59BDCEE3" + "6B692153" + "D0A9877C" + "C62A4740" + "02DF32E5"
            + "2139F0A0", 16);

    /** 基点G, G=(xg,yg),其介记为n */
    public static final BigInteger n = new BigInteger("FFFFFFFE" + "FFFFFFFF"
            + "FFFFFFFF" + "FFFFFFFF" + "7203DF6B" + "21C6052B" + "53BBF409"
            + "39D54123", 16);

    private static SecureRandom random = new SecureRandom();
    private ECCurve.Fp curve;
    public static ECPoint G;


    public SM2Util(){
        curve =  new ECCurve.Fp(p,a,b);
        G = curve.createPoint(xg,yg);
    }

}
2.随机数的生成
public class SM2Random {
    private static final SecureRandom random = new SecureRandom();
    public  static BigInteger random(BigInteger m){
        BigInteger r = new BigInteger(256,random);
        while (r.compareTo(m) >= 0){
            r = new BigInteger(128,random);
        }
        return r;
    }
}
3.获得公私钥对
public class SM2GennerateKeyPair {
    public SM2KeyPair generateKeyPair() {
        BigInteger d = SM2Random.random(SM2Util.n.subtract(new BigInteger("1")));
        SM2KeyPair keyPair = new SM2KeyPair(SM2Util.G.multiply(d).normalize(),d);
        if (SM2CheckPublicKey.checkPublicKey(keyPair.getPublicKey())) {
            System.out.println("成功生成密钥");
            return keyPair;
        } else {
            System.err.println("生成密钥失败");
            return null;
        }
    }
}
4.公钥检验
public class SM2CheckPublicKey {

    private static boolean between(BigInteger param, BigInteger min, BigInteger max) {
        if (param.compareTo(min) >= 0 && param.compareTo(max) < 0) {
            return true;
        } else {
            return false;
        }
    }
    public static boolean checkPublicKey(ECPoint publicKey) {
        if (!publicKey.isInfinity()) {
            BigInteger x = publicKey.getXCoord().toBigInteger();
            BigInteger y = publicKey.getYCoord().toBigInteger();
            System.out.println("x: "+ x);
            System.out.println("y: "+ y);
            if (between(x, new BigInteger("0"), SM2Util.p) && between(y, new BigInteger("0"), SM2Util.p)) {
                BigInteger xResult = x.pow(3).add(SM2Util.a.multiply(x)).add(SM2Util.b).mod(SM2Util.p);
                System.out.println("xResult: " + xResult.toString());
                BigInteger yResult = y.pow(2).mod(SM2Util.p);
                System.out.println("yResult: " + yResult.toString());
                if (yResult.equals(xResult) && publicKey.multiply(SM2Util.n).isInfinity()) {
                    return true;
                }
            }
            return false;
        } else {
            return false;
        }
    }
}
5.字节数组转Hex
public class SM2HexString {
    public static String HexString(byte[] b) {
        StringBuilder builder = new StringBuilder();
        if (b == null || b.length <= 0){
            return null;
        }
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
//                builder.append(0);
                hex = '0' + hex;
            }
            System.out.print(hex.toUpperCase());
            builder.append(hex);
        }
        return builder.toString();
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值