ECDSA算法--java实现

简介

椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准。它在1998年既已为ISO所接受,并且包含它的其他一些标准亦在ISO的考虑之中。与普通的离散对数问题(discrete logarithm problem  DLP)和大数分解问题(integer factorization problem  IFP)不同,椭圆曲线离散对数问题(elliptic curve discrete logarithm problem  ECDLP)没有亚指数时间的解决方法。因此椭圆曲线密码的单位比特强度要高于其他公钥体制。

模型:模型与 dsa , rsa  一致 

具体的算法(注意!!!只有jdk1.7之后才提供了 ECDSA 算法的支持)

速度快,强度高,签名短

算法分类信息:

算法密钥长度默认长度签名长度实现的方
NONEwithECDSA112-571256128JDK/BC
RIPEMD160withECDSA同上256160BC
SHA1withECDSA...256160JDK/BC
SHA224withECDSA...256224BC
SHA256withECDSA...256256JDK/BC
SHA384withECDSA...256384JDK/BC
SHA512withECDSA...256512JDK/BC

java实现:

package com.zoo.lion.security;

import org.apache.commons.codec.binary.Hex;

import javax.crypto.KeyAgreement;
import javax.xml.bind.DatatypeConverter;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @Author: xf
 * @Date: 2019/6/4 13:44
 * @Version 1.0
 */
public class ECDSACoder {

    private static String data = "ecdsa security";
//    private final static String publicKey1 = "3059301306072A8648CE3D020106082A8648CE3D03010703420004A416FD8C6572CCD2345AC3310A02D44A0BF2BC2E22153A26ABE0CB01EFC62D286D002D9B1328590EE2A8890D52E54652EA1AC54FB9699A98953128B20A177734";
//    private final static String privateKey1 = "3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010420D0C7C40D4841EFA1F2AB1831C18EA8CDF73974F26475E0DFA393D822FA475FF7";
//    private final static String publicKey2 = "3059301306072a8648ce3d020106082a8648ce3d03010703420004767c30eae6ef41a24de0b61b730f5990924c7427d2f215a3478a871c0de4dfe34b5e6c275d447098d864499491c669012e8c2c6aeb1c8cffff3e34a5f8515c9a";
//    private final static String privateKey2 = "3041020100301306072a8648ce3d020106082a8648ce3d03010704273025020101042011353b6b2ee5975cf2c7efb836329a07794be70b58d64efc23e7311fb4352501";

    public static void main(String[] args) throws Exception {
//        加签验签
//        KeyPair keyPair = getKeyPair();
//        PrivateKey privateKey = keyPair.getPrivate();
//        PublicKey publicKey = keyPair.getPublic();
//        String sign = signECDSA(privateKey, data);
//        verifyECDSA(publicKey,sign,data);

//        生成公钥私钥1
        KeyPair keyPair1 = getKeyPair();
        PublicKey publicKey1 = keyPair1.getPublic();
        PrivateKey privateKey1 = keyPair1.getPrivate();
        System.out.println(Hex.encodeHexString(publicKey1.getEncoded()));
        System.out.println(Hex.encodeHexString(privateKey1.getEncoded()));

//        生成公钥私钥2
        KeyPair keyPair2 = getKeyPair();
        PublicKey publicKey2 = keyPair2.getPublic();
        PrivateKey privateKey2 = keyPair2.getPrivate();
        System.out.println(Hex.encodeHexString(publicKey2.getEncoded()));
        System.out.println(Hex.encodeHexString(privateKey2.getEncoded()));

        //生成多次的share key一样
        for (int i = 0; i < 10; i++) {
            String sharedKey1 = genSharedKey(publicKey1, privateKey2);
            String sharedKey2 = genSharedKey(publicKey2, privateKey1);
            System.out.println(sharedKey1);
            System.out.println(sharedKey2);
        }


    }

    //加签
    public static String signECDSA(PrivateKey privateKey, String message) {
        String result = "";
        try {
            //执行签名
            Signature signature = Signature.getInstance("SHA1withECDSA");
            signature.initSign(privateKey);
            signature.update(message.getBytes());
            byte[] sign = signature.sign();
            return Hex.encodeHexString(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    //验签
    public static boolean verifyECDSA(PublicKey publicKey, String signed, String message) {
        try {
            //验证签名
            Signature signature = Signature.getInstance("SHA1withECDSA");
            signature.initVerify(publicKey);
            signature.update(message.getBytes());

            byte[] hex = Hex.decodeHex(signed);
            boolean bool = signature.verify(hex);
            System.out.println("验证:" + bool);
            return bool;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 从string转private key
     */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] bytes = DatatypeConverter.parseHexBinary(key);

        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 从string转public key
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] bytes = DatatypeConverter.parseHexBinary(key);

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance("EC");
        return keyFactory.generatePublic(keySpec);
    }


    /**
     * 生成 share key
     *
     * @param publicStr  公钥字符串
     * @param privateStr 私钥字符串
     * @return
     */
    public static String genSharedKey(String publicStr, String privateStr) {
        try {
            return genSharedKey(getPublicKey(publicStr), getPrivateKey(privateStr));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成 share key
     *
     * @param publicKey  公钥
     * @param privateKey 私钥
     * @return
     */
    public static String genSharedKey(PublicKey publicKey, PrivateKey privateKey) {
        String sharedKey = "";
        try {
            KeyAgreement ka = KeyAgreement.getInstance("ECDH");
            ka.init(privateKey);
            ka.doPhase(publicKey, true);
            sharedKey = Hex.encodeHexString(ka.generateSecret());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sharedKey;
    }

    //生成KeyPair
    public static KeyPair getKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        keyGen.initialize(256, random);
        return keyGen.generateKeyPair();
    }


}

(完)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值