首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring Boot -加密JSON数据

Spring Boot -加密JSON数据
EN

Stack Overflow用户
提问于 2016-11-22 11:33:09
回答 2查看 22.8K关注 0票数 15

在我们的应用程序中,我们必须对每个请求和响应加密/解密Json属性值(而不是属性名)。例如,

{"userName":"encrypted value", "email":"encrypted value"}

我们使用Sprint引导1.3,我们使用@RequestBody@ResponseBody注释将请求JSON与对象绑定,并将响应对象序列化为json。

我们不希望在每个控制器方法中调用加密/解密方法。有任何方法可以指示sprint在绑定请求对象之前解密json值吗?类似地,在将响应对象字段值转换为json之前加密它们?还是定制杰克逊可以帮我们?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-22 12:07:11

您可以编写自己的http消息转换器。由于您使用的是spring引导,所以非常容易:只需从AbstractHttpMessageConverter扩展您的自定义转换器并使用@Component注释标记该类即可。

来自春季医生

您可以通过简单地在Spring上下文中添加该类型的bean来贡献额外的转换器。如果您添加的bean是默认包含的类型(比如用于JSON转换的MappingJackson2HttpMessageConverter ),那么它将替换默认值。

下面是一个简单的例子:

代码语言:javascript
运行
复制
@Component
public class Converter extends AbstractHttpMessageConverter<Object> {

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    @Inject
    private ObjectMapper objectMapper;

    public Converter(){
        super(MediaType.APPLICATION_JSON_UTF8,
            new MediaType("application", "*+json", DEFAULT_CHARSET));
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    protected Object readInternal(Class<? extends Object> clazz,
                                  HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return objectMapper.readValue(decrypt(inputMessage.getBody()), clazz);
    }

    @Override
    protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        outputMessage.getBody().write(encrypt(objectMapper.writeValueAsBytes(o)));
    }

    private InputStream decrypt(InputStream inputStream){
        // do your decryption here 
        return inputStream;
    }

    private byte[] encrypt(byte[] bytesToEncrypt){
        // do your encryption here 
        return bytesToEncrypt;
    }
}
票数 15
EN

Stack Overflow用户

发布于 2019-12-02 09:09:58

好吧,所以我用了@eparvan的答案,做了几处修改。

  1. 创建一个组件,对JSON响应进行加密,并从前端解密请求params。

我在" data“对象中以加密格式获取请求params,类似于这样,并以数据对象的方式发送加密的响应。

参考答复:{"data":"requestOrResponseInEncryptedUsingPrivateKey"}

代码语言:javascript
运行
复制
    @Component
    public class Converter extends AbstractHttpMessageConverter<Object> {

        private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

        @Autowired
        private ObjectMapper objectMapper;

        public Converter() {
            super(MediaType.APPLICATION_JSON,
                    new MediaType("application", "*+json", DEFAULT_CHARSET));
        }

        @Override
        protected boolean supports(Class<?> clazz) {
            return true;
        }

        @Override
        protected Object readInternal(Class<? extends Object> clazz,
                                      HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
            return objectMapper.readValue(decrypt(inputMessage.getBody()), clazz);
        }

        @Override
        protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
            outputMessage.getBody().write(encrypt(objectMapper.writeValueAsBytes(o)));
        }

        /**
         * requests params of any API
         *
         * @param inputStream inputStream
         * @return inputStream
         */
        private InputStream decrypt(InputStream inputStream) {
            //this is API request params
            StringBuilder requestParamString = new StringBuilder();
            try (Reader reader = new BufferedReader(new InputStreamReader
                    (inputStream, Charset.forName(StandardCharsets.UTF_8.name())))) {
                int c;
                while ((c = reader.read()) != -1) {
                    requestParamString.append((char) c);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                //replacing /n if available in request param json string

                //reference request: {"data":"thisisencryptedstringwithexpirytime"}

                JSONObject requestJsonObject = new
                        JSONObject(requestParamString.toString().replace("\n", ""));

                String decryptRequestString = EncryptDecrypt.decrypt(requestJsonObject.getString("data"));
                System.out.println("decryptRequestString: " + decryptRequestString);

                if (decryptRequestString != null) {
return new ByteArrayInputStream(decryptRequestString.getBytes(StandardCharsets.UTF_8));
                } else {
                    return inputStream;
                }
            } catch (JSONException err) {
                Log.d("Error", err.toString());
                return inputStream;
            }
        }

        /**
         * response of API
         *
         * @param bytesToEncrypt byte array of response
         * @return byte array of response
         */
        private byte[] encrypt(byte[] bytesToEncrypt) {
            // do your encryption here
            String apiJsonResponse = new String(bytesToEncrypt);

            String encryptedString = EncryptDecrypt.encrypt(apiJsonResponse);
            if (encryptedString != null) {
                //sending encoded json response in data object as follows

                //reference response: {"data":"thisisencryptedstringresponse"}

                Map<String, String> hashMap = new HashMap<>();
                hashMap.put("data", encryptedString);
                JSONObject jsob = new JSONObject(hashMap);
                return jsob.toString().getBytes();
            } else
                return bytesToEncrypt;
        }
    }
  1. 下面是我的EncryptDecrypt类,其中正在进行加密和解密 类IvParameterSpec(Constants.Encryption.INIT_VECTOR.getBytes(StandardCharsets.UTF_8));{静态字符串加密(字符串值){ EncryptDecrypt { IvParameterSpec iv =新的EncryptDecrypt SecretKeySpec skeySpec =新的EncryptDecrypt .getBytes(StandardCharsets.UTF_8),"AES");密码= Cipher.getInstance("AES/CBC/PKCS5PADDING");cipher.init(Cipher.ENCRYPT_MODE,skeySpec,iv);byte[]加密= cipher.doFinal(value.getBytes());byte[]原始=Base64.getEncoder().encode(加密);返回新字符串(原始);} catch (异常ex) { ex.printStackTrace();}返回空;}静态字符串解密(字符串加密){尝试{ IvParameterSpec iv =新的IvParameterSpec.getBytes(StandardCharsets.UTF_8);SecretKeySpec skeySpec =新的.getBytescipher.doFinal(Base64.getDecoder().decode(encrypted));( getBytes(StandardCharsets.UTF_8),"AES");密码= Cipher.getInstance("AES/CBC/PKCS5PADDING");cipher.init(Cipher.DECRYPT_MODE,skeySpec,iv);byte[]原件=返回新字符串(原始);} catch (除ex) { ex.printStackTrace();}返回null;} }

你就完蛋了!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40740771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档