全部產品
Search
文件中心

Key Management Service:簽名驗簽樣本

更新時間:Dec 26, 2024

初始化KMS執行個體SDK用戶端後,您可以通過用戶端調用Sign和Verify介面進行簽名驗簽。本文介紹簽名驗簽的程式碼範例。

完整程式碼範例

調用Sign介面使用非對稱金鑰進行數位簽章,調用Verify介面使用非對稱金鑰驗證數位簽章。

源碼github地址:Sha256AsymmetricSignVerifySample.java

簽名驗簽完整程式碼範例

package com.aliyun.dkms.gcs.sdk.example;

import com.aliyun.dkms.gcs.openapi.models.Config;
import com.aliyun.dkms.gcs.openapi.util.models.RuntimeOptions;
import com.aliyun.dkms.gcs.sdk.Client;
import com.aliyun.dkms.gcs.sdk.models.SignRequest;
import com.aliyun.dkms.gcs.sdk.models.SignResponse;
import com.aliyun.dkms.gcs.sdk.models.VerifyRequest;
import com.aliyun.dkms.gcs.sdk.models.VerifyResponse;
import com.aliyun.tea.TeaException;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;

/**
 * kms Sha256非對稱簽名驗簽樣本
 */
public class Sha256AsymmetricSignVerifySample {
    // kms執行個體Client對象
    private static Client client = null;

    public static void main(String[] args) {

        try {
            // 構建KMS執行個體Client對象
            initClient();

            // 使用kms執行個體進行簽名和驗簽
            asymmetricSignVerify();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 構建KMS執行個體Client對象
     *
     * @throws Exception
     */
    public static void initClient() throws Exception {
        // 連線協定請設定為"https"。KMS執行個體服務僅允許通過HTTPS協議訪問。
        Config config = new Config();
        config.setProtocol("https");
    
        // Client Key。
        config.setClientKeyFile("<your-client-key-file>");
     
         // Client Key口令。
        config.setPassword("<your-password>");
       
         // 設定endpoint為<your KMS Instance Id>.cryptoservice.kms.aliyuncs.com。
        config.setEndpoint("<your-endpoint>");
        
        // KMS執行個體的CA認證,可通過檔案路徑或直接設定內容。
        config.setCaFilePath("<path/to/yourCaCert>");
        // 或者,設定為KMS執行個體的CA認證內容
        //config.setCa("<your-ca-certificate-content");
        client = new Client(config);
        
    }

    /**
     * 使用kms執行個體進行簽名和驗簽
     *
     * @throws Exception
     */
    public static void asymmetricSignVerify() throws Exception {
        String keyId = "<your-key-id>";
        String algorithm = "<your-algorithm>";
        String message = "<your-message>";
        // 待簽名資料類型,RAW-原始訊息,DIGEST-摘要
        String messageType = "DIGEST";

        //使用kms對message進行簽名
        final SignContext signContext = asymmetricSign(keyId, algorithm, message, messageType);
        //使用kms對message進行驗證簽名
        asymmetricVerify(signContext, message);
    }

    /**
     * 使用kms對message進行簽名
     *
     * @param keyId
     * @param algorithm
     * @param message
     * @param messageType
     * @return
     * @throws Exception
     */
    public static SignContext asymmetricSign(String keyId, String algorithm, String message, String messageType) throws Exception {

        SignRequest signRequest = new SignRequest();
        signRequest.setKeyId(keyId);
        signRequest.setAlgorithm(algorithm);
        signRequest.setMessage(getDigest(message));
        signRequest.setMessageType(messageType);
        try {
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //SignResponse signResponse = client.signWithOptions(signRequest, runtimeOptions);
            SignResponse signResponse = client.sign(signRequest);
            // 簽名值
            byte[] signature = signResponse.getSignature();
            System.out.println("================sign================");
            System.out.printf("KeyId: %s%n", signResponse.getKeyId());
            System.out.printf("Signature: %s%n", Arrays.toString(signature));
            System.out.println("================sign================");
            return new SignContext(signResponse.getKeyId(), signResponse.getSignature(), signResponse.getAlgorithm(), signResponse.getMessageType());
        } catch (TeaException e) {
            System.out.printf("Code: %s%n", ((TeaException) e).getCode());
            System.out.printf("Message: %s%n", ((TeaException) e).getMessage());
            System.out.printf("HttpCode: %s%n", ((TeaException) e).getData().get("httpCode"));
            System.out.printf("HostId: %s%n", ((TeaException) e).getData().get("hostId"));
            System.out.printf("RequestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (Exception e) {
            System.out.printf("sign errMsg: %s%n", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 使用kms對message進行驗證簽名
     *
     * @param signContext
     * @throws Exception
     */
    public static void asymmetricVerify(final SignContext signContext, String message) throws Exception {
        VerifyRequest verifyRequest = new VerifyRequest();
        verifyRequest.setKeyId(signContext.getKeyId());
        verifyRequest.setAlgorithm(signContext.getAlgorithm());
        verifyRequest.setMessage(getDigest(message));
        verifyRequest.setMessageType(signContext.getMessageType());
        verifyRequest.setSignature(signContext.getSignature());
        try {
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //VerifyResponse verifyResponse = client.verifyWithOptions(verifyRequest, runtimeOptions);
            VerifyResponse verifyResponse = client.verify(verifyRequest);
            System.out.println("================verify================");
            System.out.printf("KeyId: %s%n", verifyResponse.getKeyId());
            System.out.printf("Value: %s%n", verifyResponse.getValue());
            System.out.println("================verify================");
        } catch (TeaException e) {
            System.out.printf("Code: %s%n", ((TeaException) e).getCode());
            System.out.printf("Message: %s%n", ((TeaException) e).getMessage());
            System.out.printf("HttpCode: %s%n", ((TeaException) e).getData().get("httpCode"));
            System.out.printf("HostId: %s%n", ((TeaException) e).getData().get("hostId"));
            System.out.printf("RequestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
        } catch (Exception e) {
            System.out.printf("verify errMsg: %s%n", e.getMessage());
            e.printStackTrace();
        }
    }

    private static byte[] getDigest(String message) throws Exception {
        MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
        return sha256.digest(message.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * The sign context may be stored.
     */
    static class SignContext implements Serializable {
        public String keyId;
        public byte[] signature;
        /**
         * Use default algorithm value,if the value is not set.
         */
        public String algorithm;
        public String messageType;

        public SignContext() {
        }

        public SignContext(String keyId, byte[] signature, String algorithm, String messageType) {
            this.keyId = keyId;
            this.signature = signature;
            this.algorithm = algorithm;
            this.messageType = messageType;
        }

        public String getKeyId() {
            return keyId;
        }

        public void setKeyId(String keyId) {
            this.keyId = keyId;
        }

        public byte[] getSignature() {
            return signature;
        }

        public void setSignature(byte[] signature) {
            this.signature = signature;
        }

        public String getAlgorithm() {
            return algorithm;
        }

        public void setAlgorithm(String algorithm) {
            this.algorithm = algorithm;
        }

        public String getMessageType() {
            return messageType;
        }

        public void setMessageType(String messageType) {
            this.messageType = messageType;
        }
    }
}

程式碼範例解析

初始化用戶端

關於初始化用戶端的詳細介紹,請參見初始化用戶端

import com.aliyun.dkms.gcs.openapi.models.Config;
import com.aliyun.dkms.gcs.sdk.Client;

                           
 public static void initClient() throws Exception {

        // 連線協定請設定為"https"。KMS執行個體服務僅允許通過HTTPS協議訪問。
        Config config = new Config();
        config.setProtocol("https");
    
        // Client Key。
        config.setClientKeyFile("<your-client-key-file>");
     
         // Client Key口令。
        config.setPassword("<your-password>");
       
         // 設定endpoint為<your KMS Instance Id>.cryptoservice.kms.aliyuncs.com。
        config.setEndpoint("<your-endpoint>");
        
        // KMS執行個體的CA認證,可通過檔案路徑或直接設定內容。
        config.setCaFilePath("<path/to/yourCaCert>");
        // 或者,設定為KMS執行個體的CA認證內容
        //config.setCa("<your-ca-certificate-content");
        client = new Client(config);
    }

調用Sign介面使用非對稱金鑰進行數位簽章

    /**
     * 使用KMS對message進行簽名
     *
     * @param keyId
     * @param algorithm
     * @param message
     * @param messageType
     * @return
     * @throws Exception
     */
    
    public static SignContext asymmetricSign(String keyId, String algorithm, String message, String messageType) throws Exception {

        SignRequest signRequest = new SignRequest();
        signRequest.setKeyId(keyId);
        signRequest.setAlgorithm(algorithm);
        signRequest.setMessage(getDigest(message));
        signRequest.setMessageType(messageType);
        try {
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //SignResponse signResponse = client.signWithOptions(signRequest, runtimeOptions);
            SignResponse signResponse = client.sign(signRequest);
            // 簽名值
            byte[] signature = signResponse.getSignature();
            System.out.println("================sign================");
            System.out.printf("KeyId: %s%n", signResponse.getKeyId());
            System.out.printf("Signature: %s%n", Arrays.toString(signature));
            System.out.println("================sign================");
            return new SignContext(signResponse.getKeyId(), signResponse.getSignature(), signResponse.getAlgorithm(), signResponse.getMessageType());
        } catch (TeaException e) {
            System.out.printf("Code: %s%n", ((TeaException) e).getCode());
            System.out.printf("Message: %s%n", ((TeaException) e).getMessage());
            System.out.printf("HttpCode: %s%n", ((TeaException) e).getData().get("httpCode"));
            System.out.printf("HostId: %s%n", ((TeaException) e).getData().get("hostId"));
            System.out.printf("RequestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (Exception e) {
            System.out.printf("sign errMsg: %s%n", e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

調用Verify介面使用非對稱金鑰驗證數位簽章

KMS的計算簽名、驗證數位簽章結果符合對應演算法標準,因此,除了通過調用Verify介面驗證數位簽章,您也可以從KMS下載公開金鑰後通過其它密碼演算法庫驗證數位簽章。

/**
     * 使用KMS對message進行驗證簽名
     *
     * @param signContext
     * @throws Exception
     */

    public static void asymmetricVerify(final SignContext signContext, String message) throws Exception {
        VerifyRequest verifyRequest = new VerifyRequest();
        verifyRequest.setKeyId(signContext.getKeyId());
        verifyRequest.setAlgorithm(signContext.getAlgorithm());
        verifyRequest.setMessage(getDigest(message));
        verifyRequest.setMessageType(signContext.getMessageType());
        verifyRequest.setSignature(signContext.getSignature());
        try {
            // 如需忽略服務端認證,可使用此處注釋代碼方式調用
            //RuntimeOptions runtimeOptions = new RuntimeOptions();
            //runtimeOptions.setIgnoreSSL(true);
            //VerifyResponse verifyResponse = client.verifyWithOptions(verifyRequest, runtimeOptions);
            VerifyResponse verifyResponse = client.verify(verifyRequest);
            System.out.println("================verify================");
            System.out.printf("KeyId: %s%n", verifyResponse.getKeyId());
            System.out.printf("Value: %s%n", verifyResponse.getValue());
            System.out.println("================verify================");
        } catch (TeaException e) {
            System.out.printf("Code: %s%n", ((TeaException) e).getCode());
            System.out.printf("Message: %s%n", ((TeaException) e).getMessage());
            System.out.printf("HttpCode: %s%n", ((TeaException) e).getData().get("httpCode"));
            System.out.printf("HostId: %s%n", ((TeaException) e).getData().get("hostId"));
            System.out.printf("RequestId: %s%n", ((TeaException) e).getData().get("requestId"));
            e.printStackTrace();
        } catch (Exception e) {
            System.out.printf("verify errMsg: %s%n", e.getMessage());
            e.printStackTrace();
        }
    }