您的位置:首页 > 编程语言 > Java开发

ECDSA数字签名算法及JAVA实现

2017-12-26 16:58 316 查看
ECDSA数字签名算法
         ECDSA椭圆曲线数字签名算法是针对素数域和伽罗瓦域上的椭圆曲线定义的,在实际中前者更为常用,以下是针对素数域的说明:
         1.使用椭圆曲线E其中
                  椭圆曲线E的模数为p,系数为a和b,生成素数阶q的循环群的点A
         2.选择一个随机整数d,并且0<d<q
         3.计算B=dA
         4.这时,公钥和私钥就全部都生成了
                  公钥:{p,a,b,q,A,B}            私钥:d
         5.签名,ECDSA签名是由两个整数r,s构成,下面是r,s的获取方式
                  R=kA
                  r=X  
                  s=(h(M)+d·r)k^-1mod q
                  注:X是R这个点的x轴坐标,h(M)是明文的哈希值
         6.签名验证,假设收到的明文为M’,收到的签名为s’、r’,则验证方式如下:
                  w=(s’)^-1mod q
                  u1=[H(M’)w] mod q
                  u2=(r’)w mod q
                  P=u1·A+u2·B
                  P的横坐标为X’,若X’=X则签名有效,反之则无效;
import sun.security.ec.ECPrivateKeyImpl;
import sun.security.ec.ECPublicKeyImpl;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
import java.util.HashMap;
import java.util.Map;

public class EcDsaCode {
private static final String KEY_ALGORITHM="EC";
private static final int KEY_SIZE = 256;
private static final String SIGNATURE_ALGORITHM = "SHA512withECDSA";

//产生密钥对,获取密钥参数
public static Map<String,Object> initKey() throws Exception{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化密钥对生成器
keyPairGenerator.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//得到公钥和私钥
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
//获取私钥D
BigInteger D = privateKey.getS();
//得到公钥的横纵坐标
BigInteger publicKeyX= publicKey.getW().getAffineX();
BigInteger publicKeyY= publicKey.getW().getAffineY();
//得到生成椭圆曲线的参数a,b
java.security.spec.ECParameterSpec ecParams = privateKey.getParams();
BigInteger curveA = ecParams.getCurve().getA();
BigInteger curveB = ecParams.getCurve().getB();
//获取此椭圆有限字段的素数 qq
ECFieldFp fieldFp = (ECFieldFp) ecParams.getCurve().getField();
BigInteger q = fieldFp.getP();
//获取椭圆的基点的x,y值
BigInteger coordinatesX = ecParams.getGenerator().getAffineX();
BigInteger coordinatesY = ecParams.getGenerator().getAffineY();
//基点的阶
BigInteger coordinatesG = ecParams.getOrder();
//获取余因子
int h = ecParams.getCofactor();

Map<String, Object> initKeyMap = new HashMap<String,Object>();
//椭圆曲线参数A,B
initKeyMap.put("A",curveA);
initKeyMap.put("B",curveB);
//素数Q
initKeyMap.put("Q",q);
//G点的坐标
initKeyMap.put("X",coordinatesX);
initKeyMap.put("Y",coordinatesY);
//N为G点的阶
initKeyMap.put("N",coordinatesG);
//H为余因子
initKeyMap.put("H",h);
//获取私钥
initKeyMap.put("D",D);
//获取公钥点的坐标
initKeyMap.put("PUBKEY_X",publicKeyX);
initKeyMap.put("PUBKEY_Y",publicKeyY);
return initKeyMap;
}

//DATA是数据,Q是大素数q,A,B为椭圆曲线参数a,b,G为基点,N为点G的阶,H是余因子,X,Y是基点的坐标,PUBKEY_X,PUBKEY_Y是公钥(DG)的坐标,D是随机数私钥

public static KeyPair generateKey(BigInteger Q, BigInteger A, BigInteger B, BigInteger N, int H, BigInteger X, BigInteger Y, BigInteger PUBKEY_X, BigInteger PUBKEY_Y, BigInteger D) throws Exception{
//创建基于指定值的椭圆曲线域参数
ECParameterSpec ecParameterSpec = new ECParameterSpec(new EllipticCurve(new ECFieldFp(Q),A,B),new ECPoint(X,Y),N,H);
ECPublicKey publicKey = new ECPublicKeyImpl(new ECPoint(PUBKEY_X,PUBKEY_Y),ecParameterSpec);
ECPrivateKey privateKey = new ECPrivateKeyImpl(D,ecParameterSpec);
return new KeyPair(publicKey,privateKey);
}
public static byte[] sign(byte[] data,PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
}

public static boolean verify(byte[] data,PublicKey publicKey, byte[] sign) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(sign);
}

}
import sun.security.ec.ECPrivateKeyImpl;
import sun.security.ec.ECPublicKeyImpl;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
import java.util.HashMap;
import java.util.Map;

public class EcDsaCode {
private static final String KEY_ALGORITHM="EC";
private static final int KEY_SIZE = 256;
private static final String SIGNATURE_ALGORITHM = "SHA512withECDSA";

//产生密钥对,获取密钥参数
public static  Map<String,Object> initKey() throws Exception{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化密钥对生成器
keyPairGenerator.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//得到公钥和私钥
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();
//获取私钥D
BigInteger D = privateKey.getS();
//得到公钥的横纵坐标
BigInteger publicKeyX= publicKey.getW().getAffineX();
BigInteger publicKeyY= publicKey.getW().getAffineY();
//得到生成椭圆曲线的参数a,b
java.security.spec.ECParameterSpec ecParams = privateKey.getParams();
BigInteger curveA = ecParams.getCurve().getA();
BigInteger curveB = ecParams.getC
996f
urve().getB();
//获取此椭圆有限字段的素数 qq
ECFieldFp fieldFp = (ECFieldFp) ecParams.getCurve().getField();
BigInteger q = fieldFp.getP();
//获取椭圆的基点的x,y值
BigInteger coordinatesX = ecParams.getGenerator().getAffineX();
BigInteger coordinatesY =  ecParams.getGenerator().getAffineY();
//基点的阶
BigInteger coordinatesG = ecParams.getOrder();
//获取余因子
int h = ecParams.getCofactor();

Map<String, Object> initKeyMap = new HashMap<String,Object>();
//椭圆曲线参数A,B
initKeyMap.put("A",curveA);
initKeyMap.put("B",curveB);
//素数Q
initKeyMap.put("Q",q);
//G点的坐标
initKeyMap.put("X",coordinatesX);
initKeyMap.put("Y",coordinatesY);
//N为G点的阶
initKeyMap.put("N",coordinatesG);
//H为余因子
initKeyMap.put("H",h);
//获取私钥
initKeyMap.put("D",D);
//获取公钥点的坐标
initKeyMap.put("PUBKEY_X",publicKeyX);
initKeyMap.put("PUBKEY_Y",publicKeyY);
return initKeyMap;
}

//DATA是数据,Q是大素数q,A,B为椭圆曲线参数a,b,G为基点,N为点G的阶,H是余因子,X,Y是基点的坐标,PUBKEY_X,PUBKEY_Y是公钥(DG)的坐标,D是随机数私钥

public static KeyPair generateKey(BigInteger Q, BigInteger A, BigInteger B, BigInteger N, int H, BigInteger X, BigInteger Y, BigInteger PUBKEY_X, BigInteger PUBKEY_Y, BigInteger D) throws Exception{
//创建基于指定值的椭圆曲线域参数
ECParameterSpec ecParameterSpec = new ECParameterSpec(new EllipticCurve(new ECFieldFp(Q),A,B),new ECPoint(X,Y),N,H);
ECPublicKey publicKey = new ECPublicKeyImpl(new ECPoint(PUBKEY_X,PUBKEY_Y),ecParameterSpec);
ECPrivateKey privateKey = new ECPrivateKeyImpl(D,ecParameterSpec);
return new KeyPair(publicKey,privateKey);
}
public static   byte[] sign(byte[] data,PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
}

public static boolean verify(byte[] data,PublicKey publicKey, byte[] sign) throws Exception {
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(sign);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息