ECDSA
微軟的Office、Windows操作系統的驗證就是ECDSA算法——橢圓曲線數字簽名算法(Elliptic Curve Digital Signature Algorithm),在2000年的時候稱為了ANSI和IEEE的標准。特點是:速度快、簽名短、強度高。在JDK1.7update4之后提供了對ECDSA的支持。該簽名的算法也和RSA的數字簽名算法也是大同小異。
============================================================================ECDSA數字簽名工具類:
import java.security.Key; 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.SecureRandom; import java.security.Signature; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; public class DigitalSignECDSA { //公鑰 private static final String PUBLIC_KEY = "ECDSAPublicKey"; //私鑰 private static final String PRIVATE_KEY = "ECDSAPrivateKey"; /** 初始化密鑰對 * @return Map 密鑰對Map * @throws Exception */ public static Map<String, Object> initKey() { try { //實例化密鑰對生成器 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC"); // 初始化密鑰對生成器,密鑰大小為256位 keyPairGenerator.initialize(256, new SecureRandom()); //生成密鑰對 KeyPair keyPair = keyPairGenerator.generateKeyPair(); //公鑰 ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic(); //私鑰 ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate(); //將密鑰對存儲在Map中 Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } /** 執行數字簽名【私鑰簽名】 * @param data 待加密數據 * @param privKey 私鑰 * @return byte[] 加密數據 * @throws Exception */ public static byte[] digitalSign(byte[] data, byte[] privKey) { try { PrivateKey privateKey = (PrivateKey) KeyFactory.getInstance("EC") .generatePrivate(new PKCS8EncodedKeySpec(privKey)); Signature signature = Signature.getInstance("SHA1WithECDSA"); signature.initSign(privateKey); signature.update(data); return signature.sign(); } catch (Exception ex) { ex.printStackTrace(); } return null; } /** 驗證簽名【公鑰驗證】 * @param data 待解密數據 * @param pubKey 公鑰 * @return byte[] 解密數據 * @throws Exception */ public static boolean signVerify(byte[] data, byte[] rsaData, byte[] pubKey) { try { PublicKey publicKey = (PublicKey) KeyFactory.getInstance("EC") .generatePublic(new X509EncodedKeySpec(pubKey)); Signature signature = Signature.getInstance("SHA1WithECDSA"); signature.initVerify(publicKey); signature.update(data); return signature.verify(rsaData); } catch (Exception ex) { ex.printStackTrace(); } return false; } /** 取得私鑰 * @param keyMap 密鑰Map * @return byte[] 私鑰 * @throws Exception */ public static byte[] getPrivateKey(Map<String, Object> keyMap) { Key key = (Key) keyMap.get(PRIVATE_KEY); return key.getEncoded(); } /** 取得公鑰 * @param keyMap 密鑰Map * @return byte[] 公鑰 * @throws Exception */ public static byte[] getPublicKey(Map<String, Object> keyMap) { Key key = (Key) keyMap.get(PUBLIC_KEY); return key.getEncoded(); } }
============================================================================ECDSA數字簽名工具測試類:
@Test public void test_DigitalSignECDSA() { //公鑰 byte[] publicKey; //私鑰 byte[] privateKey; //初始化密鑰 //生成密鑰對 Map<String, Object> keyMap = DigitalSignECDSA.initKey(); publicKey = DigitalSignECDSA.getPublicKey(keyMap); privateKey = DigitalSignECDSA.getPrivateKey(keyMap); System.out.println("ECDSA公鑰:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(publicKey)); System.out.println("ECDSA私鑰:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(privateKey)); System.out.println(); String msgA2B = "What can I do for you?"; //執行數字簽名【私鑰簽名】 byte[] encodeMsgA2B = DigitalSignECDSA.digitalSign(msgA2B.getBytes(), privateKey); System.out.println("JDK ECDSA簽名::\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(encodeMsgA2B)); //驗證簽名【公鑰驗證】 boolean bool = DigitalSignECDSA.signVerify(msgA2B.getBytes(), encodeMsgA2B, publicKey); System.out.println("數字簽名是否有效?:\n" + bool); }