Java數字簽名-RSA算法


數字簽名

  數字簽名是帶有密鑰(公鑰、私鑰)的消息摘要算法。主要作用是驗證數據的完整性、認證數據來源、抗否認。在數字簽名的實現中我們使用私鑰簽名、公鑰驗證。常用的數字簽名算法包括RSA、DSA、ECDSA。

RSA

  該算法是數字簽名的經典算法。主要包括MD和SHA兩類。

應用場景:

   Java實現RSA數字簽名如下:

============================================================================RSA數字簽名工具類:

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.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class DigitalSignRSA {
    //公鑰
    private static final String PUBLIC_KEY = "RSAPublicKey";
    //私鑰
    private static final String PRIVATE_KEY = "RSAPrivateKey";
 
    /** 初始化密鑰對
     * @return Map 密鑰對Map
     * @throws Exception
     */
    public static Map<String, Object> initKey() {
        try {
            //實例化密鑰對生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            // 初始化密鑰對生成器,密鑰大小為96-1024位
            keyPairGenerator.initialize(512, new SecureRandom());
            //生成密鑰對
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            //公鑰
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            //私鑰
            RSAPrivateKey privateKey = (RSAPrivateKey) 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("RSA")
                    .generatePrivate(new PKCS8EncodedKeySpec(privKey));
            Signature signature = Signature.getInstance("MD5WithRSA");
            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("RSA")
                    .generatePublic(new X509EncodedKeySpec(pubKey));
            Signature signature = Signature.getInstance("MD5WithRSA");
            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();
    }
}

============================================================================RSA數字簽名工具測試類:

    @Test
    public void test_DigitalSignRSA() {
        //公鑰
        byte[] publicKey;
        //私鑰
        byte[] privateKey;
 
        //初始化密鑰
        //生成密鑰對
        Map<String, Object> keyMap = DigitalSignRSA.initKey();
        publicKey = DigitalSignRSA.getPublicKey(keyMap);
        privateKey = DigitalSignRSA.getPrivateKey(keyMap);
        System.out.println("RSA公鑰:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(publicKey));
        System.out.println("RSA私鑰:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(privateKey));
 
        System.out.println();
        String msgA2B = "What can I do for you?";
        //執行數字簽名【私鑰簽名】
        byte[] encodeMsgA2B = DigitalSignRSA.digitalSign(msgA2B.getBytes(), privateKey);
        System.out.println("JDK RSA簽名::\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(encodeMsgA2B));
        //驗證簽名【公鑰驗證】
        boolean bool = DigitalSignRSA.signVerify(msgA2B.getBytes(), encodeMsgA2B, publicKey);
        System.out.println("數字簽名是否有效?:\n" + bool);
    }

 


免責聲明!

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



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