Java數字簽名-ECDSA算法


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);
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM