【环球速看料】JWE:安全传输敏感数据的最佳实践 (上)
最近工作需求,提供几个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); } }
成功进行加解密
先生成一对公钥和私钥
// 生成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日有网友拍到北京上空出现了三个太阳。对于这一现象气象专家 【详细】
十大名车车标 世界十大名车车标简介
十大名车车标 世界十大名车车标简介很多爱车人士对于车标是十分熟悉的,基本可以做到看一眼就知道是哪个品牌的车,世界名车更是如此,许多 【详细】
塑料袋属于什么 四种垃圾分类简介
塑料袋属于什么塑料袋是干垃圾。湿垃圾是指易腐烂的垃圾,通常是厨房垃圾。塑料袋不容易腐烂降解,是干垃圾。就是我们常说的白色污染,所以 【详细】
相关新闻
- 【环球速看料】JWE:安全传输敏感数据的最佳实践 (上)
- 全球新资讯:滴滴,小米,抖音,拼多多等创始人在SVB崩溃后急于安抚投资者
- 【世界新视野】机械系统动力学自动分析软件ADAMS2020 一键下载激活安装教程
- 一加2023年销量同比260% 成为行业增速第一的手机品牌
- 芬必得多少钱一盒24粒_芬必得多少钱
- 全球微动态丨《暗黑破坏神4》公测指南:时间/预载/内容/PC配置!
- 2023手机性价比最新排行榜出炉,预算2000以内的大屏智能手机推荐_天天速递
- 电脑提示“GeForce Experience遇到错误且必须关闭”怎么办?
- 360浏览器上网防忽悠报告发布 哪些人是受骗群体?
- 魔兽争霸3重制版秘籍 魔兽争霸3重制版秘籍代码
- iphone运营商图标修改方法 iphone手电筒图标是灰色咋回事?
- 国内油价首降 全国油价调整究竟是涨还是跌?
- 关于XPERIA系列介绍 索爱XPERIAPro配置简介
- directx9.0c是一款什么软件?directx9.0c软件特色
- 当前快讯:可插拔组件设计机制—SPI
- 【速看料】菜鸟驿站辟谣,遇上此类信息不要回复
- 小米11Ultra升级MIUI14稳定版,深度体验一个月感受如何?
- 魔兽世界提示“正在等待另一项安装或更新”的解决方法
- 榨汁机品牌汇总 榨汁机品牌介绍大全
- 苹果14.6系统怎么样 苹果ios14.6越狱插件怎么下载?