当前位置: 首页 > 编程日记 > 正文

RSA签名算法,计算调用加密报文,安全传输

RSA签名算法

1. 获取当前的时间戳参数

2. 计算参数签名

3. 获取请求对象的MD5密文

4. 通过私钥计算某个参数的RSA签名

5. 转换字符集到utf8

6. MD5加密字符串

7. base64编码

8. base64编码字符串

9. base64解码


/*** 参数签名算法工具类*/
public class RSAUtils {/*** 获取当前的时间戳参数* @return*/public static String getRtick(){long timestamp = new Date().getTime();int rnd = (int)Math.random() * 1000;String rtick = timestamp + "" + rnd;return rtick;}/*** 计算参数签名* @param developerId 开发者ID* @param privateKey 用户私钥* @param host 请求的HOST地址(http://ip:port/context)* @param methodName 请求的接口方法名* @param rtick 时间戳参数* @param urlParams url参数(param1=value1&param2=value2&param3=value3)* @param requestBody request body 参数(JSON字符串)* @return*/public static String calcRsaSign(String developerId, String privateKey, String host, String methodName, String rtick, String urlParams, String requestBody) {String url = host+methodName;Map<String, String> mySignedURLParams = new TreeMap<String, String>();mySignedURLParams.put("developerId", developerId);mySignedURLParams.put("rtick", rtick);mySignedURLParams.put("signType", "rsa");if(urlParams != null && !"".equals(urlParams)){String[] params = urlParams.split("&");for(String p1 : params){String[] p2 = p1.split("=");String key = p2[0];String value = "";if(p2.length == 2){value = p2[1];}mySignedURLParams.put(key, value);}}String requestPath;try {requestPath = new URL(url).getPath();}catch (MalformedURLException e) {throw new RuntimeException(e.getMessage(), e);}StringBuilder signStringBuilder = new StringBuilder();for (String name : mySignedURLParams.keySet()) {String value = mySignedURLParams.get(name);signStringBuilder.append(name);signStringBuilder.append("=");signStringBuilder.append(value);}signStringBuilder.append(requestPath);if (requestBody != null && !"".equals(requestBody) ) {String requestMd5 = getRequestMd5(requestBody);signStringBuilder.append(requestMd5);}String signString = signStringBuilder.toString();String rsaSign =  calcRsaSign(privateKey, signString);//rsa算出来的sign,需要urlencodetry {rsaSign = URLEncoder.encode(rsaSign,"UTF-8");} catch (UnsupportedEncodingException e) {rsaSign = null;}return rsaSign;}/*** 获取request body 的MD5* @param requestBody* @return*/private static String getRequestMd5(final String requestBody) {byte[] data;String newRequestBody = convertToUtf8(requestBody);try {data = newRequestBody.getBytes("UTF-8");}catch (UnsupportedEncodingException e) {throw new RuntimeException(e.getMessage(), e);}return md5(data);}/*** 计算参数RSA签名* @param privateKey* @param signData* @return*/private static String calcRsaSign(String privateKey, final String signData) {byte[] data;try {data = signData.getBytes("UTF-8");}catch (UnsupportedEncodingException e) {throw new RuntimeException(e.getMessage(), e);}byte[] sign = null;// 解密由base64编码的私钥byte[] privateKeyBytes = base64decode(privateKey.getBytes());// 构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);// KEY_ALGORITHM 指定的加密算法KeyFactory keyFactory;try {keyFactory = KeyFactory.getInstance("RSA");}catch (NoSuchAlgorithmException e) {throw new RuntimeException(e.getMessage(), e);}// 取私钥匙对象PrivateKey priKey;try {priKey = keyFactory.generatePrivate(pkcs8KeySpec);}catch (InvalidKeySpecException e) {throw new RuntimeException(e.getMessage(), e);}// 用私钥对信息生成数字签名Signature signature;try {signature = Signature.getInstance("SHA1withRSA");}catch (NoSuchAlgorithmException e) {throw new RuntimeException(e.getMessage(), e);}try {signature.initSign(priKey);}catch (InvalidKeyException e) {throw new RuntimeException(e.getMessage(), e);}try {signature.update(data);sign = signature.sign();}catch (SignatureException e) {throw new RuntimeException(e.getMessage(), e);}return new String(base64encode(sign));}/*** 转换字符集到utf8** @param src* @return*/private static String convertToUtf8(String src) {if (src == null || src.length() == 0) {return src;}if ("UTF-8".equalsIgnoreCase(Charset.defaultCharset().name())) {return src;}byte[] srcData = src.getBytes();try {return new String(srcData, "UTF-8");}catch (UnsupportedEncodingException e) {throw new RuntimeException(e.getMessage(), e);}}/*** md5* @param data* @return*/public static String md5(byte[] data) {char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};byte[] btInput = data;// 获得MD5摘要算法的 MessageDigest 对象MessageDigest mdInst;try {mdInst = MessageDigest.getInstance("MD5");}catch (NoSuchAlgorithmException e) {throw new RuntimeException(e.getMessage(), e);}// 使用指定的字节更新摘要mdInst.update(btInput);// 获得密文byte[] md = mdInst.digest();// 把密文转换成十六进制的字符串形式int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);}/*** base64编码* @param data* @return*/public static byte[] base64encode(byte[] data) {return Base64.encodeBase64(data);}/*** base64编码字符串* @param data* @return*/public static String base64encodeString(byte[] data) {return Base64.encodeBase64String(data);}/*** base64解码* @param data* @return*/public static byte[] base64decode(byte[] data) {try {return Base64.decodeBase64(data);} catch (Exception e) {ByteArrayOutputStream outputStream = new ByteArrayOutputStream();for (int i = 0; i < data.length; i++) {byte c = data[i];if (c == 13 || c == 10) {continue;}outputStream.write(c);}try {outputStream.close();} catch (IOException e2) {}data = outputStream.toByteArray();return Base64.decodeBase64(data);}}
}

相关文章:

两步完成项目定时启动,java项目定时启动

两步完成项目定时设置&#xff1a; 在需要定时启动或运行的方法上面加上注解Scheduled //当天只跑一次 Scheduled(cron "0 40 21 * * ?")在启动类上加注解EnableScheduling SpringBootApplication EnableScheduling ComponentScan({"com.xxx.xxx.newinterf&qu…

Java Calendar.add()方法的使用,参数含义。指定时间差。

cal.add()方法中的参数含义&#xff1a; 第一个参数如果是1则代表的是对年份操作&#xff0c;2是对月份操作&#xff0c;3是对星期操作&#xff0c;5是对日期操作&#xff0c;11是对小时操作&#xff0c;12是对分钟操作&#xff0c;13是对秒操作&#xff0c;14是对毫秒操作。 …

jar包升级部署到服务器详细流程,将服务部署在linux中

假设你已经准备好以下东西&#xff0c;即可进行服务部署 一台服务器&#xff08;云服务器或虚拟机皆可&#xff09;已安装好的jdk 1.8 的环境&#xff08;可自行百度&#xff09;打好的jar包&#xff08;maven打jar包&#xff09; 1. 在服务器中新建好你的项目文件目录&#x…

将jar包部署在docker上,将jar包打成镜像,使用docker部署jar包

假设你已经准备好以下东西&#xff0c;即可进行服务部署 一台安装好docker的linux服务器&#xff08;安装docker见安装docker&#xff09; 准备好的jar包 接下来开始吧&#xff01; 将jar包上传至服务器&#xff08;建好文件夹存放以方便管理&#xff09; 编辑Dockerfile文…

MybatisPlus忽略实体类中的非数据库字段、JPA忽略实体类中的非数据库字段、HeHibernate忽略实体类中的非数据库字段

mybatis plus忽略映射字段时可以在实体类属性上使用以下注解&#xff1a; TableField(exist false)&#xff1a;表示该属性不为数据库表字段&#xff0c;但又是必须使用的。 TableField(exist true)&#xff1a;表示该属性为数据库表字段。在实体类的属性上面加上这个注解后…

如果你没用过maven的install,你应该了解一下!maven中的install功能及用法。

maven中有一个大多数人都忽视或者没有用到过的一个功能——install&#xff0c;大多数java开发人员都了解maven&#xff0c;使用maven进行依赖管理。但使用的大多数功能不过是clean清理、compile编译、package打包&#xff0c;却很少用到install这个功能&#xff0c;接下来就来…

IDEA中maven的命令及作用

maven中的Lifecycle中的那些按钮都有哪些&#xff0c;都有什么功能呢&#xff1f; validate&#xff1a;验证项目的正确性以及包含所有必要的信息compile&#xff1a;编译源码test&#xff1a;编译和运行测试代码package&#xff1a;把编译好的源码打成包&#xff0c;如jarveri…

docker :open /var/lib/docker/tmp/GetImageBlob318829910: no such file or directory异常解决

千万不要直接去重装docker&#xff0c;不要删除镜像&#xff0c;不要手动创建目录和文件&#xff0c;只需要这样就好了&#xff01;&#x1f447; 重启docker服务 sudo systemctl restart docker解决 以上&#xff01;

设置普通用户执行docker命令,执行docker命令无需输入密码或者切换root用户

每次执行docker命令都要输入密码或者切换root用户&#xff0c;非常不方便&#xff0c;尤其是在shell脚本中就更麻烦了&#xff0c;一起来解决这个问题&#xff1b; 1. 创建名为docker的组&#xff0c;如果之前已经有该组就会提示已存在&#xff1a; sudo groupadd docker gro…

spring boot项目 中止运行 最常用的几种方法

spring boot项目 中止运行 最常用的几种方法&#xff1a; 1. 调用接口&#xff0c;停止应用上下文 RestController public class ShutdownController implements ApplicationContextAware {private ApplicationContext context;PostMapping("/shutdownContext")pub…

力扣每日一题——独一无二出现的次数

难度&#xff1a;简单 题目&#xff1a; 给你一个整数数组 arr&#xff0c;请你帮忙统计数组中每个数的出现次数。 如果每个数的出现次数都是独一无二的&#xff0c;就返回 true&#xff1b;否则返回 false。 示例 1&#xff1a; 输入&#xff1a;arr [1,2,2,1,1,3] 输出&a…

java1.8新增超实用Map方法——Map.getOrDefault()和Map.value()方法详解

1. Map.getOrDefault() 翻译一下官方解释&#xff1a; java.util.Map<K, V> V getOrDefault(Object key, V defaultValue) 返回到指定键所映射的值&#xff0c;或defaultValue如果此映射包含该键的映射。 入参&#xff1a; 键 - 其关联值的键是要返回 默认值 - 键的默认…

力扣解题——求根到叶子节点数字之和

难度&#xff1a;中等 题目&#xff1a;给定一个二叉树&#xff0c;它的每个结点都存放一个 0-9 的数字&#xff0c;每条从根到叶子节点的路径都代表一个数字。 例如&#xff0c;从根到叶子节点路径 1->2->3 代表数字 123。 计算从根到叶子节点生成的所有数字之和。 …

docker安装kafka消息队列

1. 启动zookeeper容器&#xff08;Zookeeper用于崩溃检测&#xff0c;实现Topic发现&#xff0c;和维护Topic的生产和消费状态&#xff09; docker run -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper2. 启动kafka容器 docker run -d --name kafka -p 9092:90…

一文吃透JAVA定时器格式

JAVA 定时器时间格式 ​ 基本格式: [秒] [分] [小时] [日] [月] [周] [年] 序号说明是否必填允许填写的值允许使用的通配符1秒是0-59, - * /2分是0-59, - * /3小时是0-23, - * /4日是1-31, - * ? / L W5月是1-12 或 JAN-DEC, - * /6周是…

List元素互换,List元素转换下标,Java Collections.swap()方法实例解析

Java Collections.swap()方法解析 jdk源码&#xff1a; public static void swap(List<?> list, int i, int j) {// instead of using a raw type here, its possible to capture// the wildcard but it will require a call to a supplementary// private methodfina…

使用feign调用注解在eureka上的微服务,简单学会微服务

使用feign调用注解在eureka上的微服务。 首先&#xff0c;确保所有服务&#xff08;调用方与被调用方&#xff09;都被注册在同一个eureka服务上。 1. 在调用方添加依赖&#xff08;万事第一步&#xff0c;加依赖&#xff09; <dependency><groupId>org.springfr…

快速排查feign.FeignException: status 500 …

feign.FeignException: status 500 … 总结一下feign报500的时候快速排查问题的方法&#xff0c; 这个bug容易出现的地方分别为: 1. 远程调用的时候feign的注册信息有没有写错,比如少一个斜杠什么之类的 FeignClient(value "testservice",path "/newinter…

手动将web项目的class文件打成jar包,手动打jar包,java -cvf,IDE打包底层指令

手动将web项目的class文件打成jar包。 我们的项目在使用IDE进行编译后&#xff0c;在项目的target目录下将会生成class文件。我们可以将class文件打成jar包。 使用的到命令为&#xff1a; 在target目录下打开命令窗口 jar -cvf xxx.jar * 可供的选项包括: -c 创建新的归档文件…

科学处理java.lang.StackOverflowError: null异常

java.lang.StackOverflowError: null异常处理 在项目运行中出现StackOverflowError 首先要检查在编码中是否有明显的递归编码,比如死循环或者无限循环调用。 而编码中并没有出现使用递归&#xff0c;这时候可以查看一下表是否有关联&#xff0c;两个表相互关联&#xff0c;我…

JPA不同包下同类名查询出错

不同包下同类名查询出错 异常现象&#xff1a;使用JPA进行查询时&#xff0c;JPA的实体类映射到了另外一个包下的同名类&#xff0c;由于两个同名类中字段名和字段数不相同&#xff0c;所以会出现种种查询错误。 原因及对策&#xff1a;这里应该是jpa实体类默认注入问题&…

java基本类型转换,随记

java基本类型转换&#xff1a; double double 转 long double random Math.round(Math.random()*10000); long l new Double(random).longValue();

IDEA设置单个文件、单个包、单个项目的编码格式

IDEA设置单个文件、单个包、单个项目的编码格式 File-> Settings-> File Enclodings 选择编码格式&#xff0c;确定即可。 注意&#xff1a;此处的编码格式设定以后&#xff0c;该包已经存在的类内部乱码或文字不会有变化&#xff0c;若新复制类进入则会按照新的编码格式…

IDEA自动生成对象所有set方法

idea中有一款插件能够生成对象所有的set方法&#xff0c;GenerateAllSetter &#xff1a;下载地址 步骤1&#xff1a;将下载好的压缩包放在自己记得的文件夹中&#xff0c;在idea中进行导入 步骤2&#xff1a;在本地选中刚才的压缩包&#xff0c;导入即可。然后将IDE重启即生…

typora新增主题,typora将主题导入本地

首先&#xff0c;需要打开typora的偏好设置&#xff0c;也就是设置 点击获取主题&#xff0c;进入 https://theme.typora.io/ 这个网站进行下载 下载好后是一个压缩包&#xff0c;将压缩包解压&#xff0c;将其中theme文件夹下的css文件复制到主题文件夹下&#xff0c;主题文件…

将文件上传至ftp服务器,FTP文件上传工具类,将文件上传至服务器指定目录

将文件上传至ftp服务器,传入File对象&#xff0c;将文件上传至ftp服务器 需要配置修改的点&#xff1a; 1. 服务器ip端口&#xff08;服务器ip 端口22/21&#xff09;。 2. 服务器账号密码&#xff08;服务器登录用户名密码&#xff09;。 3. 上传路径&#xff08;写入的路径会…

苹果设备iphone,ipad,macbook网络连接慢,开机开什么卡什么,一步解决

苹果电脑网络连接慢&#xff0c;开机开什么卡什么&#xff1f;&#xff1f;&#xff1f; 网络上的方法一种种&#xff0c;没有一个适用的&#xff1f; 如果你的macbook也是打开就没网&#xff0c;但有一些软件也能用&#xff0c;就是浏览器加载跑条儿&#xff0c;不妨试试&am…

Map的分类和不同的应用场景

java为数据结构中的映射定义了一个接口java.util.Map; 它有四个实现类,分别是HashMap&#xff0c;Hashtable&#xff0c;LinkedHashMap和TreeMap 可能很多人只使用过HashMap&#xff0c;但还是那句话&#xff0c;你可以不用&#xff0c;但你不能不懂。如果你也是这样&#xff0…

sql特殊字符转义,oracle中将字符 ‘ 转义

oracle中使用sql语句或多或少地会遇到使用特殊字符&#xff0c;比如" ’ ",这时&#xff0c;这个单引号就会与前面的单引号匹配&#xff0c;将文本从中间断开&#xff0c;引发问题和错误。这就需要我们进行转义。 而oracle中并不像C java这些编程语言那样使用"…

idea中如何打开RunDashboard窗口,微服务最实用设置

idea中如何打开RunDashboard窗口 找到.idea目录&#xff0c;打开workspace.xml&#xff0c;搜索RunDashboard&#xff0c;找到该段配置&#xff0c;加入下面注释中的代码 <component name"RunDashboard"><option name"ruleStates"><list&…