Extend the Encryption Key

Feedback


SuperMap iServer provides the SecretKeyProvider interface, which is used to extend the development of custom external keys that meet the needs of users and are applied to various encryption scenarios.

1. Introduction to SecretKey Provider Interface

The com.supermap.services.util.encryption.SecretKeyProvider interface has the following methods:

This method is used to load the key according to the configuration.

This method is used to unload the key.

This method is used to obtain the key according to the scene and ID, and the returned Optional.empty represents that the key acquisition of this scene is not supported.

The method is use for acquiring key description information accord to a scene and an ID, and returning a Optional. Empty representing that key acquisition which does not support the scene.

2. Implementation Example of SecretKey Provider Interface

Taking the inheritance of the SecretKeyProvider interface to implement the external national secret key SM4SecretKeyProvider class as an example, explain the specific code implementation method as follows:

package com.supermap.model.util;

import cn.hutool.core.util.RandomUtil;

import com.supermap.server.config.CipherKeySetting;

import com.supermap.services.util.encryption.EncryptionScenario;

import com.supermap.services.util.encryption.SecretKeyInfo;

import com.supermap.services.util.encryption.SecretKeyProvider;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

import java.util.Base64;

import java.util.List;

import java.util.Optional;

public class SM4SecretKeyProvider implements SecretKeyProvider {

    private static final String SM4_KEY_PATH = "D:\\SM4_keyStore\\SM4KEY.txt";

    @Override

    public void loadSecretKey(List<CipherKeySetting> list, EncryptionScenario encryptionScenario) {

    }

    @Override

    public void unloadSecretKey(List<CipherKeySetting> list, EncryptionScenario encryptionScenario) {

    }

    @Override

    public Optional<SecretKeySpec> getSecretKeySpec(String keyID, EncryptionScenario encryptionScenario) {

        Optional<SecretKeySpec> optional = Optional.empty();

        String keyPath = null;

        String algorithm = "";

        if ("keyID1".equals(keyID)) {

            keyPath = SM4_KEY_PATH;

            algorithm = "SM4";

        }

        if (StringUtils.isNotBlank(keyPath)) {

            int lineNumber = RandomUtil.randomInt(1,11);

            BufferedReader reader = null;

            try {

                reader = new BufferedReader(new FileReader(keyPath));

                String line;

                int currentLine = 1;

                optional = Optional.of(new SecretKeySpec(Base64.getDecoder().decode(line), algorithm));

            } catch (IOException e) {

                e.printStackTrace();

                log.error("获取密钥失败!");

            } finally {

                if (reader != null) {

                    try {

                        reader.close();

                    } catch (IOException e) {

                        throw new RuntimeException(e);

                    }

                }

            }

        }

        return optional;

    }

    @Override

    public Optional<SecretKeyInfo> getSecretKeyInfo(String keyID, EncryptionScenario encryptionScenario) {

        return Optional.empty();

    }