@TOC
该算法是微软操作系统及办公软件的序列号验证算法。 ECDSA(Elliptic Curve Digital Signature Algorithm, 椭圆曲线数字签名算法) 于1999年作为ANSI标准, 并于2000年成为IEEE和NIST标准。
ECDSA算法具有速度快、强度高、签名短等有点。
Java中未对该算法做实现, 而在Bouncy Castle中有该算法实现。
下面的表格说明了实现细节。
算法密钥长度密钥默认长度签名长度备注NONEwithECDSA、RIPEMD160withECDSA、SHA1withECDSA、SHA224withECDSA、SHA256withECDSA、SHA384withECDSA、SHA512withECDSA--128、160、160、224、256、384、512Bouncy Castle实现基于Bouncy Castle的 ECDSA算法实现
package com.calvin.android.demo2.secrity; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.ECParameterSpec; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * Author:cl * Email:lhzheng@grandstream.cn * Date:20-10-21 */ //java – 在BouncyCastle上使用数字签名算法(ECDSA)实现的椭圆曲线 http://www.voidcn.com/article/p-vmamxfcn-bup.html public class ECDSACoder { /** * 数字签名密钥算法 */ public static final String KEY_ALGORITHM = "ECDSA"; /** * 数字签名 * 签名/验证算法 */ public static final String SIGNATURE_ALGORITHM = "SHA1withECDSA"; //公钥 Map Key private static final String PUBLIC_KEY = "ECDSAPublicKey"; //私钥Map key private static final String PRIVATE_KEY = "ECDSAPrivateKey"; /** * DSA密钥长度,默认1024位,密钥长度必须是64的倍数,范围512~1024位之间 */ private static final int KEY_SIZE = 1024; /** * 签名 * @param data 待签名数据 * @param privateKey 私钥 * @return byte[] 数字签名 * @throws Exception 异常 */ public static byte[] sign(byte[] data, byte[] privateKey) throws Exception { //转换私钥材料 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey); //实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //取私钥对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); //实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, "BC"); //初始化Signature signature.initSign(priKey); //更新 signature.update(data); //签名 return signature.sign(); } /** * 校验 * @param data 待校验数据 * @param publicKey 公钥 * @param sign 数字签名 * @return boolean 校验成功返回true,校验失败返回false * @throws Exception */ public static boolean verity(byte[] data, byte[] publicKey, byte[] sign) throws Exception{ //转换公钥材料 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); //实例化密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成公钥 PublicKey pubKey = keyFactory.generatePublic(keySpec); //实例化Signature Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, "BC"); //初始化Signature signature.initVerify(pubKey); //更新 signature.update(data); //校验证 return signature.verify(sign); } public static Map<String, Object> initKey() throws Exception { //实例化BC Provider Provider bcProvider = new BouncyCastleProvider(); Security.removeProvider("BC"); Security.addProvider(bcProvider); ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("B-571"); //实例化密钥对生成器 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM, "BC"); keyPairGen.initialize(ecSpec, new SecureRandom()); //生成密钥对 KeyPair keyPair = keyPairGen.generateKeyPair(); //公钥 PublicKey publicKey = (PublicKey)keyPair.getPublic(); //私钥 PrivateKey privateKey = (PrivateKey)keyPair.getPrivate(); //封装密钥 Map<String, Object> keyMap = new HashMap<>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static byte[] getPublicKey(Map<String, Object> keyMap){ return ((Key)keyMap.get(PUBLIC_KEY)).getEncoded(); } public static byte[] getPrivateKey(Map<String, Object> keyMap){ return ((Key)keyMap.get(PRIVATE_KEY)).getEncoded(); } }