1. 程式人生 > >JDK中JCA的簡單使用(二)---RSA加簽驗籤

JDK中JCA的簡單使用(二)---RSA加簽驗籤

Signature 類

Signature類是一個引擎類,提供加密的數字簽名演算法,例如DSA或RSAwithMD5。加密安全簽名演算法採用任意大小的輸入和私鑰,並生成一個相對較短(通常是固定大小)的位元組串——簽名。

  • 只有私鑰/公鑰對的所有者才能建立簽名。對於擁有公鑰的任何人來說,恢復私鑰在計算上是不可行的。
  • 用於生成簽名的私鑰相對應的公鑰,可以驗證輸入的真實性和完整性。
  • 簽名和公鑰不會洩露有關私鑰的任何資訊。

簡而言之,
1.建立一對Key:私鑰&公鑰。
2.使用私鑰建立簽名
3.使用公鑰對資料的真實性進行校驗。

值得注意的是,Signature

演算法目的並不在於對原資料加密,而是使用原資料和私鑰/公鑰生成簽名,驗籤時,使用公鑰/私鑰,簽名,原資料進行校驗。

應用場景:用於需要使用這份資料,又不能確定接收資料的可靠性。

使用流程:

1.獲取公私鑰對,程式碼如下:

     /**
     * 獲取公私鑰對
     *
     * @return
     */
    private static Map<String, String> getKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator generator = null;
        generator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        //初始化祕鑰size,最小為512
        generator.initialize(1024);
        KeyPair keyPair = generator.generateKeyPair();
        String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
        String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
        Map<String, String> keyMap = new HashMap<>();
        keyMap.put(PRIVATE_KEY, privateKey);
        keyMap.put(PUBLIC_KEY, publicKey);
        return keyMap;
    }

2.使用私鑰對資料進行加簽,獲得簽名字串,程式碼如下:

     /**
     * 根據私鑰加簽
     *
     * @param privateKey
     * @param data
     * @return
     */
    public static String sign(PrivateKey privateKey, String data) throws Exception {
        //加簽演算法,加簽演算法有很多種,這裡選擇 MD5WithRSA
        Signature signature = Signature.getInstance(ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data.getBytes());
        byte[] signByte = signature.sign();
        return Base64.getEncoder().encodeToString(signByte);
    }

3.根據公鑰驗籤

     /**
     * 根據公鑰驗籤
     *
     * @param publicKey
     * @param signStr
     * @param data
     * @return
     */
    public static boolean vertify(PublicKey publicKey, String signStr, String data) throws Exception {
        Signature signature = Signature.getInstance(ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(data.getBytes());
        return signature.verify(Base64.getDecoder().decode(signStr));
    }

完整的方法如下:

    public final static String KEY_ALGORITHM = "RSA";

    public final static String ALGORITHM = "MD5WithRSA";

    public final static String PRIVATE_KEY = "privateKey";

    public final static String PUBLIC_KEY = "publicKey";

    /**
     * 獲取公私鑰對
     *
     * @return
     */
    private static Map<String, String> getKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator generator = null;
        generator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        //初始化祕鑰size,最小為512
        generator.initialize(1024);
        KeyPair keyPair = generator.generateKeyPair();
        String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
        String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
        Map<String, String> keyMap = new HashMap<>();
        keyMap.put(PRIVATE_KEY, privateKey);
        keyMap.put(PUBLIC_KEY, publicKey);
        return keyMap;
    }

    /**
     * 根據字串獲取私鑰
     *
     * @param privateKeyStr
     * @return
     */
    public static PrivateKey getPrivateKey(String privateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyStr);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        return privateKey;
    }

    /**
     * 根據字串獲取公鑰
     *
     * @param publicKeyStr
     * @return
     */
    public static PublicKey getPublickey(String publicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 根據keyMap獲取私鑰字串
     *
     * @param keyMap
     * @return
     */
    public static String getPrivateKeyStr(Map<String, String> keyMap) {
        return keyMap.get(PRIVATE_KEY);
    }

    /**
     * 根據私鑰獲取私鑰字串
     *
     * @param privateKey
     * @return
     */
    public static String getPrivateKeyStr(PrivateKey privateKey) {
        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
    }

    /**
     * 根據keyMap獲取公鑰字串
     *
     * @param keyMap
     * @return
     */
    public static String getPublicKeyStr(Map<String, String> keyMap) {
        return keyMap.get(PUBLIC_KEY);
    }

    /**
     * 根據公鑰獲取公鑰字串
     *
     * @param publicKey
     * @return
     */
    public static String getPublicKeyStr(PublicKey publicKey) {
        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
    }

    /**
     * 根據私鑰字串加簽
     *
     * @param privateKeyStr 私鑰字串
     * @param data          需要加簽的資料
     * @return
     */
    public static String sign(String privateKeyStr, String data) throws Exception {
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        return sign(privateKey, data);
    }

    /**
     * 根據私鑰加簽
     *
     * @param privateKey
     * @param data
     * @return
     */
    public static String sign(PrivateKey privateKey, String data) throws Exception {
        //加簽演算法,加簽演算法有很多種,這裡選擇 MD5WithRSA
        Signature signature = Signature.getInstance(ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data.getBytes());
        byte[] signByte = signature.sign();
        return Base64.getEncoder().encodeToString(signByte);
    }

    /**
     * 根據公鑰字串驗籤
     *
     * @param publicKeyStr
     * @param signStr
     * @param data
     * @return
     */
    public static boolean vertify(String publicKeyStr, String signStr, String data) throws Exception {
        PublicKey publicKey = getPublickey(publicKeyStr);
        return vertify(publicKey, signStr, data);
    }

    /**
     * 根據公鑰驗籤
     *
     * @param publicKey
     * @param signStr
     * @param data
     * @return
     */
    public static boolean vertify(PublicKey publicKey, String signStr, String data) throws Exception {
        Signature signature = Signature.getInstance(ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(data.getBytes());
        return signature.verify(Base64.getDecoder().decode(signStr));
    }

完整工具類下載:https://download.csdn.net/download/cappadocia_/10730247