一.ECDSA:
椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟
二.模型
模型与 dsa , rsa 一致
三.具体的算法(注意!!!只有jdk1.7之后才提供了 ECDSA 算法的支持)
算法 | 密钥长度 | 默认长度 | 签名长度 | 实现的方 |
NONEwithECDSA | 112-571 | 256 | 128 | JDK/BC |
RIPEMD160withECDSA | 同上 | 256 | 160 | BC |
SHA1withECDSA | ... | 256 | 160 | JDK/BC |
SHA224withECDSA | ... | 256 | 224 | BC |
SHA256withECDSA | ... | 256 | 256 | JDK/BC |
SHA384withECDSA | ... | 256 | 384 | JDK/BC |
SHA512withECDSA | ... | 256 | 512 | JDK/BC |
四.优点:
速度快,强度高,签名短
五.具体的实现(java):
import java.security.InvalidKeyException;
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.Signature;
import java.security.SignatureException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.commons.codec.binary.Base64;
public class ECDSA {
static String src = "欧阳草帽";
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// 获取公钥、私钥
KeyPair keyPair = getKeyPair();
ECPublicKey ecPublicKey = getRSPublicKey(keyPair);
ECPrivateKey ecPrivateKey = getESAPrivateKey(keyPair);
byte [] publicKeyEnc = ecPublicKey.getEncoded(); // 公钥
byte [] privateKeyEnc = ecPrivateKey.getEncoded(); //私钥
//执行签名
byte[] result = sign(privateKeyEnc);
System.out.println("签名后的数据:"+Base64.encodeBase64String(result));
//验证签名
boolean ok = verify(publicKeyEnc, result);
System.out.println("签名验证的结果:" + ok);
}
/**
* 验证签名
* @param publicKeyEnc
* @param result
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws SignatureException
*/
public static boolean verify(byte[] publicKeyEnc, byte[] result)
throws NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeyException, SignatureException {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyEnc);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Signature signature = Signature.getInstance("SHA1withECDSA");
signature.initVerify(publicKey);
signature.update(src.getBytes());
boolean ok = signature.verify(result); // 验证结果
return ok;
}
/**
* 执行签名
* @param privateKeyEnc
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws SignatureException
*/
public static byte[] sign(byte[] privateKeyEnc)
throws NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeyException, SignatureException {
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyEnc);
PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//构建签名
Signature signature = Signature.getInstance("SHA1withECDSA");
signature.initSign(priKey);
signature.update(src.getBytes());
byte [] result = signature.sign(); // 签名后的数据信息
return result;
}
/**
* 生成私钥
* @param keyPair
* @return
*/
public static ECPrivateKey getESAPrivateKey(KeyPair keyPair) {
ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
return ecPrivateKey;
}
/**
* 生成公钥
* @param keyPair
* @return
*/
public static ECPublicKey getRSPublicKey(KeyPair keyPair) {
ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
return ecPublicKey;
}
/**
* 生成秘钥对的材料
* @return
* @throws NoSuchAlgorithmException
*/
private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
keyPairGenerator.initialize(256);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
}
签名后的数据:MEUCIQCpSOMWjSQtuCaRNPus8ukUwQ55c7HEc5Tx28al2zYg7wIgbKTtGEFoOZCtlxtT0gh08vhMJ0CO6on2juX4uTD7Wg0=
签名验证的结果:true