RSA 公私钥json化再反向生成公私钥

记录一次 公私钥json化再反向生成公私钥的操作

一、背景

因为项目需要将PrivateKey、PublicKey存到redis中,所以需要整体json化然后上传,再下次签名验签的时候,再取出来,反向生成对应的公私钥。

二、准备工作

首先需要设计合适的数据结构,满足新增证书上传,后续读取证书解析后生成公私钥。

根据实际情况发现,设计一个实体即可,redis存储String,k-v就行。(当然也可以设置Hash类型存储)

三、具体操作

3.1 存公私钥到redis

1、实体类:必须保证序列化。

public class KeyInfo implements Serializable {
    
    

    /**
     * key
     */
    private String keyId;
    /**
     * 公钥
     */
    private PublicKey publicKey;
    /**
     * 私钥
     */
    private PrivateKey privateKey;

}

2、Json化:就直接用fastjson了,方便快捷。

String json = JSON.toJSONString(keyInfo);

3、redis上传,直接用String-String类型的存,key=keyId,value=实际的json串,这里就不详细介绍怎么上传了,直接RedisTempate操作就行。

4、记得上传的时候,Base64一下传输内容,保证完整哈。还有注意过期时间,结合实际情况给值。

3.2 从redis中读公私钥

1、从redis中直接根据key获取value。

2、获取出来后,直接转为JSONObject对象。踩坑 这里切记不要转为Bean对象,因为公私钥本身没有序列化,所以你如果强行转为Bean,直接就是null了,而且json之后公私钥也会被格式化,根本没法再转回去了!!!

String resultKey = Base64.decode(response.getResultKey(), "utf-8");
JSONObject json = JSONObject.parseObject(resultKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//获取私钥json
JSONObject jsonObjectPr = (JSONObject) json.get("privateKey");
//生成私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(jsonObjectPr.getBytes("encoded"));
PrivateKey privateKey = keyFactory.generatePrivate(keySpec)
//获取公钥json
JSONObject jsonObjectPu = (JSONObject) json.get("publicKey");
//生成公钥
X509EncodedKeySpec x509EncodedPubKeySpec = new X509EncodedKeySpec(jsonObjectPu.getBytes("encoded"));
PublicKey publicKey = keyFactory.generatePublic(x509EncodedPubKeySpec)

3、正常操作公私钥进行签名验签即可。

补充说明:针对解析这块,说一下为什么这样写:

因为json化之后,原本的公私钥对象PrivateKey、PublicKey其内部结构会被重新格式化,所以你从redis中拿到的数据和你当时json前的公私钥已经不是同一个了。

好在公私钥内部的encoded,可以借助它反向再次生成公私钥对象。

下面截个私钥json对象的图,更好的认识其内部结构
在这里插入图片描述

四、总结

本次对公私钥json化存入redis再反向解析出来,可以引用在那种多地部署,共享证书的场景下,比如北京服务器上传了证书信息,但是内蒙服务器发交易的时候需要加载,但其本地没有,所以需要连接同一台redis去读取,当然你觉得redis不合理,可以存数据库、minio都可以,根据实际情况区分对待即可。
其实我理解,这也是分布式场景下,保证数据一致性的问题,因为我负责的这几个模块没法连接数据库,所以找了一个折中的方式,存入redis缓存,去解决这个问题。类似Session共享存token到redis中的做法。
也可以借助mq来解决这种情况,因为证书只会在一个地方上传,那么可以通过一个检查点,去监听所有模块,一旦有一个有上传,那检查点把证书拿到后,直接广播出去,实现共享,这样也行。
方法很多,就看你怎么设计,只要能保证大家能共享读取到就行。

本次分享就到这,欢迎大家一起学习讨论,本人能力有限,有些地方设计想法可能不太成熟,本文仅供大家学习参考~

猜你喜欢

转载自blog.csdn.net/qq_38653981/article/details/133812385
今日推荐