JWT Token生成与解析 + ECDSA加密技术

2023-11-02 15:18

本文主要是介绍JWT Token生成与解析 + ECDSA加密技术,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

JWT Token生成与解析 + ECDSA加密技术

  • 需要maven依赖
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version>
</dependency>
  • 16进制字符串与byte数组互转工具类

/*** 16进制字符串与byte数组转换* @author chenyb**/
public final class HexUtil {private static final char[] HEX = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};public HexUtil() {}/*** byte数组转16进制字符串* @param bytes* @return*/public static String encodeHexString(byte[] bytes) {int nBytes = bytes.length;char[] result = new char[2 * nBytes];int j = 0;byte[] var4 = bytes;int var5 = bytes.length;for(int var6 = 0; var6 < var5; ++var6) {byte aByte = var4[var6];result[j++] = HEX[(240 & aByte) >>> 4];result[j++] = HEX[15 & aByte];}return new String(result);}/*** 16进制字符串转byte数组* @param s 字符串* @return*/public static byte[] decode(CharSequence s) {int nChars = s.length();if (nChars % 2 != 0) {throw new IllegalArgumentException("Hex-encoded string must have an even number of characters");} else {byte[] result = new byte[nChars / 2];for(int i = 0; i < nChars; i += 2) {int msb = Character.digit(s.charAt(i), 16);int lsb = Character.digit(s.charAt(i + 1), 16);if (msb < 0 || lsb < 0) {throw new IllegalArgumentException("Detected a Non-hex character at " + (i + 1) + " or " + (i + 2) + " position");}result[i / 2] = (byte)(msb << 4 | lsb);}return result;}}}
  •  生成密钥对,校验密钥有效性
package com.jwt.ecdsa;import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import javax.xml.bind.DatatypeConverter;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Calendar;public class ECDSATest {/*** SIGNALGORITHMS* NONEwithECDSA	112-571	256	128	JDK/BC* RIPEMD160withECDSA	同上	256	160	BC* SHA1withECDSA	...	256	160	JDK/BC* SHA224withECDSA	...	256	224	BC* SHA256withECDSA	...	256	256	JDK/BC* SHA384withECDSA	...	256	384	JDK/BC* SHA512withECDSA	...	256	512	JDK/BC*/private static final String SIGNALGORITHMS = "SHA256withECDSA";private static final String ALGORITHM = "EC";private static final String SECP256K1 = "secp256k1";public static void main(String[] args) throws Exception {//        生成公钥私钥KeyPair keyPair1 = getKeyPair();PublicKey publicKey1 = keyPair1.getPublic();PrivateKey privateKey1 = keyPair1.getPrivate();//密钥转16进制字符串String publicKey = HexUtil.encodeHexString(publicKey1.getEncoded());String privateKey = HexUtil.encodeHexString(privateKey1.getEncoded());System.out.println("生成公钥:"+publicKey);System.out.println("生成私钥:"+privateKey);//16进制字符串转密钥对象PrivateKey privateKey2 = getPrivateKey(privateKey);PublicKey publicKey2 = getPublicKey(publicKey);//加签验签,设计自己的签名JSONObject o = new JSONObject();o.put( "id","sadasdsadsawq2132343243242ds" );o.put( "name","chenyb" );String data=o.toJSONString();String signECDSA = signECDSA(privateKey2, data);System.out.println(signECDSA);boolean verifyECDSA = verifyECDSA(publicKey2, signECDSA, data);System.out.println("验签结果:"+verifyECDSA);}/*** 加签* @param privateKey 私钥* @param data 数据* @return*/public static String signECDSA(PrivateKey privateKey, String data) {String result = "";try {//执行签名Signature signature = Signature.getInstance(SIGNALGORITHMS);signature.initSign(privateKey);signature.update(data.getBytes());byte[] sign = signature.sign();return HexUtil.encodeHexString(sign);} catch (Exception e) {e.printStackTrace();}return result;}/*** 验签* @param publicKey 公钥* @param signed 签名* @param data 数据* @return*/public static boolean verifyECDSA(PublicKey publicKey, String signed, String data) {try {//验证签名Signature signature = Signature.getInstance(SIGNALGORITHMS);signature.initVerify(publicKey);signature.update(data.getBytes());byte[] hex = HexUtil.decode(signed);boolean bool = signature.verify(hex);// System.out.println("验证:" + bool);return bool;} catch (Exception e) {e.printStackTrace();}return false;}/*** 从string转private key* @param key 私钥的字符串* @return* @throws Exception*/public static PrivateKey getPrivateKey(String key) throws Exception {byte[] bytes = DatatypeConverter.parseHexBinary(key);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);return keyFactory.generatePrivate(keySpec);}/*** 从string转publicKey* @param key 公钥的字符串* @return* @throws Exception*/public static PublicKey getPublicKey(String key) throws Exception {byte[] bytes = DatatypeConverter.parseHexBinary(key);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);return keyFactory.generatePublic(keySpec);}/*** 生成密钥对* @return* @throws Exception*/public static KeyPair getKeyPair() throws Exception {ECGenParameterSpec ecSpec = new ECGenParameterSpec(SECP256K1);KeyPairGenerator kf = KeyPairGenerator.getInstance(ALGORITHM);kf.initialize(ecSpec, new SecureRandom());KeyPair keyPair = kf.generateKeyPair();return keyPair;}}
  • 测试密钥配对成功截图

  •  jwt生成token与解析
public static void main(String[] args) throws Exception {java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());//获取公钥私钥部分KeyPair keyPair1 = getKeyPair();PublicKey publicKey1 = keyPair1.getPublic();PrivateKey privateKey1 = keyPair1.getPrivate();//密钥转16进制字符串String publicKey = HexUtil.encodeHexString(publicKey1.getEncoded());String privateKey = HexUtil.encodeHexString(privateKey1.getEncoded());System.out.println("生成公钥:"+publicKey);System.out.println("生成私钥:"+privateKey);//16进制字符串转密钥对象PrivateKey privateKey2 = getPrivateKey(privateKey);PublicKey publicKey2 = getPublicKey(publicKey);//生成token部分SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Calendar c = Calendar.getInstance();c.add(Calendar.HOUR_OF_DAY, Integer.valueOf( 1000*60*5 ));//设置Token有效时长JSONObject o = new JSONObject();o.put("principal", "data数据");//封装数据Object类型o.put("exp", sdf.format(c.getTime()));//单纯的记录Token生成时间//SignatureAlgorithm.ES256 这里一定是对应的采用的加密技术String token = Jwts.builder().setClaims(o).setExpiration(c.getTime()).signWith( SignatureAlgorithm.ES256, privateKey2).compact();System.out.println("生成的token:"+token);//解析token部分final Claims claims = Jwts.parser().setSigningKey(publicKey2).parseClaimsJws(token).getBody();String str = (String) claims.get("principal");System.out.println("token解析出来的数据"+str);}
  • 实战中,我们只需要提供生成token接口与解析token接口,将密钥对提前生成好存在文件里,在生成、与解析的时候调用就好
//接口部分
package com.jwt.service;public interface JwtService {String createToken(String str);String getData(String token);}//实现部分
package com.jwt.service.impl;import com.alibaba.fastjson.JSONObject;
import com.jwt.ecdsa.ECDSATest;
import com.jwt.service.JwtService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Service;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;/*** Created by chenyb .*/
@Service
public class JwtServiceImpl implements JwtService {@SuppressWarnings("restriction")private PublicKey getPublicKey() {PublicKey publicKey = null;try {InputStream stream = getClass().getClassLoader().getResourceAsStream("key/public.key");BufferedReader br = new BufferedReader(new InputStreamReader(stream));String line = "";StringBuffer sb = new StringBuffer();while ((line = br.readLine()) != null) {sb.append(line);}publicKey = ECDSATest.getPublicKey(sb.toString());} catch (Exception e) {e.printStackTrace();}return publicKey;}private PrivateKey getPrivateKey(){PrivateKey privateKey = null;try {InputStream stream = getClass().getClassLoader().getResourceAsStream("key/private.key");BufferedReader br = new BufferedReader(new InputStreamReader(stream));String line = "";StringBuffer sb = new StringBuffer();while ((line = br.readLine()) != null) {sb.append(line);}privateKey = ECDSATest.getPrivateKey( sb.toString() );} catch (Exception e) {e.printStackTrace();}return privateKey;}@Overridepublic String createToken(String str){java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());PrivateKey privateKey = this.getPrivateKey();JSONObject data = new JSONObject();data.put("data", str);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Calendar c = Calendar.getInstance();c.add(Calendar.HOUR_OF_DAY, 1000*60*60*2);//token有效时间JSONObject o = new JSONObject();o.put("principal", data);o.put("exp", sdf.format(c.getTime()));Date timeOut = c.getTime();String token = Jwts.builder().setClaims(o).setExpiration(timeOut).signWith(SignatureAlgorithm.ES256, privateKey).compact();return token;}@Overridepublic String getData(String token) {PublicKey publicKey = getPublicKey();if (publicKey != null) {try {final Claims claims = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token).getBody();Map<String,String> map = (Map<String,String>) claims.get("principal");return map.get( "data" );}catch (Exception e){e.printStackTrace();}}return null;}
}
  •  Key文件位置

  • 测试代码
@Testpublic void createToken (){String token = jwtServiceImpl.createToken( "被封装的数据" );System.out.println("token:"+token);String s = jwtServiceImpl.getData( token );System.out.println(s);}
  • 测试结果

随笔记录,方便学习

2020-07-03

这篇关于JWT Token生成与解析 + ECDSA加密技术的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/331494

相关文章

解析 XML 和 INI

XML 1.TinyXML库 TinyXML是一个C++的XML解析库  使用介绍: https://www.cnblogs.com/mythou/archive/2011/11/27/2265169.html    使用的时候,只要把 tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

20170723 做的事 ecdsa的签名验证时间短于bls signature

1 今天在虚拟机 /home/smile/Desktop/20170610/Test//time_ecdsa 文件夹下,找到ecdsa的验证时间是 989.060606μs μs 先 make ,然后run。 再取BLS的签名生成时间: ./run  2  gnuplot 画图,画对比的时间 gnuplot 画图参考教程 http://blog.sciencen

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一

FastAdmin/bootstrapTable 表格中生成的按钮设置成文字

公司有个系统后台框架用的是FastAdmin,后台表格的操作栏按钮只有图标,想要设置成文字。 查资料后发现其实很简单,主需要新增“text”属性即可,如下 buttons: [{name: 'acceptcompany',title: '复核企业',text:'复核企业',classname: 'btn btn-xs btn-primary btn-dialog',icon: 'fa fa-pe

使用JWT进行安全通信

在现代Web应用中,安全通信是至关重要的。JSON Web Token(JWT)是一种流行的安全通信方式,它允许用户和服务器之间安全地传输信息。JWT是一种紧凑的、URL安全的表示方法,用于在两方之间传输信息。本文将详细介绍JWT的工作原理,并提供代码示例帮助新人理解和实现JWT。 什么是JWT? JWT是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSO

陀螺仪LSM6DSV16X与AI集成(8)----MotionFX库解析空间坐标

陀螺仪LSM6DSV16X与AI集成.8--MotionFX库解析空间坐标 概述视频教学样品申请源码下载开启CRC串口设置开启X-CUBE-MEMS1设置加速度和角速度量程速率选择设置FIFO速率设置FIFO时间戳批处理速率配置过滤链初始化定义MotionFX文件卡尔曼滤波算法主程序执行流程lsm6dsv16x_motion_fx_determin欧拉角简介演示 概述 本文将探讨

【文末附gpt升级秘笈】腾讯元宝AI搜索解析能力升级:千万字超长文处理的新里程碑

腾讯元宝AI搜索解析能力升级:千万字超长文处理的新里程碑 一、引言 随着人工智能技术的飞速发展,自然语言处理(NLP)和机器学习(ML)在各行各业的应用日益广泛。其中,AI搜索解析能力作为信息检索和知识抽取的核心技术,受到了广泛的关注和研究。腾讯作为互联网行业的领军企业,其在AI领域的探索和创新一直走在前列。近日,腾讯旗下的AI大模型应用——腾讯元宝,迎来了1.1.7版本的升级,新版本在AI搜

消息认证码解析

1. 什么是消息认证码         消息认证码(Message Authentication Code)是一种确认完整性并进行认证的技术,取三个单词的首字母,简称为MAC。         消息认证码的输入包括任意长度的消息和一个发送者与接收者之间共享的密钥,它可以输出固定长度的数据,这个数据称为MAC值。         根据任意长度的消息输出固定长度的数据,这一点和单向散列函数很类似

问题1,PE文件转到内存中出现解析PE不正确的问题

1,使用fopen(FileName, “r”) r的方式读取文件到内存,此时就可能存在问题了,r以只读方式,有时候不表示字符的有可能就不读了,那么内存中就不会是完整的原始文件。所以此时要采用rb,二进制读取的方式。 bool ReadFileToMem(char* FileName, char**buf) { FILE* f; f = fopen(FileName, “rb”); if