当前位置:科学 > 正文

【环球速看料】JWE:安全传输敏感数据的最佳实践 (上)

2023-03-14 15:49:30  来源:sakka6868
起源

最近工作需求,提供几个API,但是数据是敏感数据,最好是不要暴露出来(PS: 本来接口就已经是HTTPS,也足够安全)

好吧,老板注重数据安全,通过网上一顿操作,发现 JSON Web Encryption(JWE),貌似可以拿来用用(PS: 复制粘贴大法)

JWE 是什么?

JWE是"JSON Web Encryption"的缩写,是一种基于JSON的加密规范,用于在网络上传输加密的数据。它定义了一种将JSON数据加密为JWE格式的方法,以确保安全传输。JWE规范使用一种称为"JWE Compact Serialization"的格式来序列化加密后的数据,以便它可以轻松地在不同的系统之间传输。


(资料图片仅供参考)

JWE使用加密算法来保护数据的机密性,同时使用消息认证码(MAC)算法来验证数据的完整性,以防止数据在传输过程中被篡改。JWE还支持多种密钥管理方法,例如将密钥嵌入到JWE中,或者通过密钥交换协议来获取密钥。

JWE通常用于保护敏感的网络数据,例如用户凭证、支付信息等等。它是JSON Web Token(JWT)规范的一部分,JWT使用JWE来提供安全性。

好了,上面搬来了八股文,还不如直接通过代码操作

首先引入maven依赖,nimbus-jose-jwt 是JWT的一种实现,相信大家也不陌生

<dependency><groupId>com.nimbusds</groupId><artifactId>nimbus-jose-jwt</artifactId><version>9.8.1</version></dependency>
public class JweRSADemo {    public static String encrypt(String payload, RSAPublicKey publicKey) throws Exception {        // 创建加密器        JWEHeader header = new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A256GCM).build();        JWEEncrypter jweEncrypter = new RSAEncrypter(publicKey);        // 加密JSON数据        Payload jwePayload = new Payload(payload);        JWEObject jweObject = new JWEObject(header, jwePayload);        jweObject.encrypt(jweEncrypter);        // 将JWE对象转换为JWE字符串        return jweObject.serialize();    }    public static String decrypt(String jwe, RSAPrivateKey privateKey) throws Exception {        // 创建解密器        JWEDecrypter jweDecrypter = new RSADecrypter(privateKey);        // 解密JWE字符串        JWEObject jweObject = JWEObject.parse(jwe);        jweObject.decrypt(jweDecrypter);        // 将解密后的JSON数据转换为JSONObject对象        Payload payload = jweObject.getPayload();        return payload.toString();    }    public static void main(String[] args) throws Exception {        // 创建一个JSON对象        JSONObject payload = new JSONObject();        payload.put("name", "Alice");        payload.put("age", 30);        String jsonString = payload.toJSONString();        // 生成RSA密钥对        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");        keyPairGenerator.initialize(2048);        KeyPair keyPair = keyPairGenerator.generateKeyPair();        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();        // 加密JSON对象        String jwe = encrypt(jsonString, publicKey);        System.out.println("JWE: " + jwe);        // 解密JWE字符串        String decryptedPayload = decrypt(jwe, privateKey);        System.out.println("Decrypted payload: " + decryptedPayload);    }    }

成功进行加解密


接入Spring Boot

先生成一对公钥和私钥

// 生成RSA密钥对KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();System.out.println("Base64.encode(publicKey.getEncoded()) = " + Base64.encode(publicKey.getEncoded()));System.out.println("Base64.encode(privateKey.getEncoded()) = " + Base64.encode(privateKey.getEncoded()));


用生成出来的公钥加密数据,加密出来的内容等下作为参数调用,通常公钥都是分发给调用端

String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsqBTYOqBU5rdpdRX9/owxi0nHsxsyGr/8PWQZ8GtPQilXfNuQEFWO01o0ZU8Agn+wzatpGCOwIgSaEF4p6uI4tyhC8BlnkQZN/GcjbryljzIrRlu8NKsLu40SQO3CYa+p7DA36pdX/nMQ9QceSeGW9e7E5YWuiMhUDgqWVEdmRxX+bxfoNYpBtNlvyxeL0MKEIUVlikYKe+UxKhiPRcwjBIiHKfsY2PszP4h485UjcIWveyJjBu8nEpUgHUqUHdA1nm32WmUMcOhTU41tX6ZoYK6qUBeNX4xnfOG7jnE76Vz2QcsVTnnTqTQ/93nxEIrZsSfQ/vdzi8LryY2xS0EmQIDAQAB";PublicKey publicKey = getPublicKey(publicKeyStr);//playload 可以是json串,也可以是普通字符串String encrypt = encrypt("jwe 测试", publicKey);System.out.println(encrypt);


我们再写一个Controller来接受参数并用私钥解密

@RestControllerpublic class JWEController {    private static final Logger LOGGER = LoggerFactory.getLogger(JWEController.class);    private final PrivateKey privateKey;/**     * 在构造方法里初始化刚刚生成的私钥     * @throws NoSuchAlgorithmException     * @throws InvalidKeySpecException     */    public JWEController() throws NoSuchAlgorithmException, InvalidKeySpecException {        String privateKeyBase64 = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCyoFNg6oFTmt2l1Ff3+jDGLScezGzIav/w9ZBnwa09CKVd825AQVY7TWjRlTwCCf7DNq2kYI7AiBJoQXinq4ji3KELwGWeRBk38ZyNuvKWPMitGW7w0qwu7jRJA7cJhr6nsMDfql1f+cxD1Bx5J4Zb17sTlha6IyFQOCpZUR2ZHFf5vF+g1ikG02W/LF4vQwoQhRWWKRgp75TEqGI9FzCMEiIcp+xjY+zM/iHjzlSNwha97ImMG7ycSlSAdSpQd0DWebfZaZQxw6FNTjW1fpmhgrqpQF41fjGd84buOcTvpXPZByxVOedOpND/3efEQitmxJ9D+93OLwuvJjbFLQSZAgMBAAECggEAJHg4XcazPeMWEufuR/pkX+nTHWYmZar283bnk0+HM7lirfJoFaVhWj09Q+EgvdfVlHzC6hcuvh9qBrArVqxeh9b86H3RIYWM0o+5Y3SCV+s0G6dgL7oLno9SzH9+LOs+XNVpI6FQbCp/qm+RmqjXtUOv9dlEbZ+DizHUb6TwkpRPMo3BHPUKGpajmP0pgSkQz8x4MWJ0a6SVST+/E7ZbwF8PobzOQCxND2yZQah/TY1EvCCyOM6chGm0loCyC4HGTBmDm/0LcWRqgiI8GiglEijGu2Iha6UR11JaEStHoc1Sy38Orj377bhndm2l19HNOQIslp9m0VP4WUSG3GJDKwKBgQC55+HY29F0H2jy7p94+snPCKVG0uJHu0IKhFN09fChP/1q0PLJuz3Vj07YUjGneSL3RHM1D+HbMYAGnZ+7GFmwIi8FLKBVZDx4L7ENhcPMUM2q0rsBphZuHfD14Hf9I0xUiNrpyTLuVPJfK3kzx2NYQmRGo6tY+INDuI5L2HEELwKBgQD1+c4ilEQtTRvoIa+BfZ/oOBeFaYsQGlLL+8yVbsPsfH+0MMoiIY++my5rDhT//8QXNhnOI1cs7CFKELA/99Mk7y9G/4o+cMb1kAyZJU6zNoSe9Eitdyo0qQQ20NVAW+YWX0zAuAm5bttk1RvVGz/wiuOotVw6oCSR0uUYUWCptwKBgB2psy6f/G6z6FIC4y0xjuva7Ew9r99UMLhu3sYly+xewne9uU+Y8cfWovT/QG8BdCPSJzPLQfVwk4X6tpbqzry855XCxh557PAcY/rNYi2Cox5jm3Uq5B9T5bPFyj9412ARqiRtdxPyN+4ZiLBLWz2k8k0XJmr+1CsFEqdldLr/AoGAEjyqLuAlSeKMriJJO+WPhI0cGVUg7Vm2R89sdKvYtODqKvbvFaa9XJlu0JsjrXNOG5Z0RVdTcE41jaM9HhEGw5dEPxRVMJn19mDuvjAI7LqfDJX6CXprU6owWMwU84ecwI3iR+udNPVmKMywGpXBoNj7VhfUNbiH3ZPwTmRCMXMCgYBi5I1KJ7kyaHKTilJEAhiYv6XBwsJScJkdAXWuA/SdG3aWQAEc4SOrRwqmqbHWYOm827tb20kG09rHnVS+tVSShvCkv4OcAr2X0L04IX9OfvUqI5pPWiQd/VzCQrTPcelixgkUkG4Sc2dRr6gvvFOKFAAVTQrePh9clk8kd3bg+g==";        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBase64.getBytes(StandardCharsets.UTF_8));        KeyFactory keyFactory;        keyFactory = KeyFactory.getInstance("RSA");        privateKey = keyFactory.generatePrivate(keySpec);    }    @GetMapping("/jwe")    public void jwe(@RequestParam String encrypt) throws Exception {        LOGGER.info("接受到的密文:{}", encrypt);        String decrypt = decrypt(encrypt, (RSAPrivateKey) privateKey);        LOGGER.info("解密后的内容:{}", decrypt);    }    public String decrypt(String jwe, RSAPrivateKey privateKey) throws Exception {        // 创建解密器        JWEDecrypter jweDecrypter = new RSADecrypter(privateKey);        // 解密JWE字符串        JWEObject jweObject = JWEObject.parse(jwe);        jweObject.decrypt(jweDecrypter);        // 将解密后的JSON数据转换为JSONObject对象        Payload payload = jweObject.getPayload();        return payload.toString();    }}

接下来用刚刚公钥生成的加密数据作为参数,调用接口


我们看控制台输出,接口调用成功,并成功解密


关键词:

推荐阅读

航天员出舱七个小时怎么喝水?太空行走的危险和好处是什么?

航天员出舱七个小时怎么喝水?7月4日,中国宇航员刘伯明和汤洪波出航活动,整个进程持续了7个多小时。据报道,宇航员在舱外服里有饮水袋,在 【详细】

NASA毅力号录下了来自火星的声音 毅力号录下了来自火星的声音怎么回事?

NASA毅力号录下了来自火星的声音近日,有报道称,NASA毅力号录下了来自火星的声音,这非常的奇妙,相信大家十分的感兴趣,下面一起去看看吧 【详细】

北京上空现三个太阳 古代幻日现象预兆什么?

北京上空现三个太阳北京上空现三个太阳 专家释疑今日登上热搜,主要是在12月29日有网友拍到北京上空出现了三个太阳。对于这一现象气象专家 【详细】

十大名车车标 世界十大名车车标简介

十大名车车标 世界十大名车车标简介很多爱车人士对于车标是十分熟悉的,基本可以做到看一眼就知道是哪个品牌的车,世界名车更是如此,许多 【详细】

塑料袋属于什么 四种垃圾分类简介

塑料袋属于什么塑料袋是干垃圾。湿垃圾是指易腐烂的垃圾,通常是厨房垃圾。塑料袋不容易腐烂降解,是干垃圾。就是我们常说的白色污染,所以 【详细】

关于我们  |  联系方式  |  免责条款  |  招聘信息  |  广告服务  |  帮助中心

联系我们:85 572 98@qq.com备案号:粤ICP备18023326号-40

科技资讯网 版权所有