SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计
SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计
SOP,是 Standard Operating Procedure三个单词中首字母的大写 ,即标准作业程序,指将某一事件的标准操作步骤和要求以统一的格式描述出来,用于指导和规范日常的工作。
加密/加签过程:
1.动态随机生成AES密钥aesKey,而不是静态的AES密钥。提高安全性。
2.使用该AES对传输的接口数据data加密。 比如:username=AES(username原文,aesKey)&age=AES(age原文,aesKey)
3.使用RSA公钥对aesKey加密,作为参数传递 prikey=RSA(aeskey,公钥)
以上完整的路径:http://IP地址+端口/path?username=AES(username,aesKey)&age=AES(age,aesKey)&prikey=RSA(aeskey,公钥)
解密/解签过程:
1.先用私钥从prikey解密获取aesKey
2.用aesKey解密username,age获得username原文,age原文
* Invalid AES key length: 33 bytes
*
* 如果未指定init LEN,则根据参数的key自适应。AES KEY长度为 16位,24位,32位。
* 否则可以指定AES KEY长度
* // KeyGenerator kgen = KeyGenerator.getInstance(TYPE);
* // //Wrong keysize: must be equal to 128, 192 or 256
* // kgen.init(LEN); //128 / 8 = 16
*
* 经过测试发现:
* keysize: must be equal to 128, 192 or 256
* aes key长度 16,24,32
* 以上的两个条件相互都成立,而不是如下的第一组,第二组,第三组的强制配对。
DEMO代码示例:
package com.example.core.mydemo.spi; import com.alibaba.fastjson.JSONObject; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date; /**
* Invalid AES key length: 33 bytes
*
* 如果未指定init LEN,则根据参数的key自适应。AES KEY长度为 16位,24位,32位。
* 否则可以指定AES KEY长度
* // KeyGenerator kgen = KeyGenerator.getInstance(TYPE);
* // //Wrong keysize: must be equal to 128, 192 or 256
* // kgen.init(LEN); //128 / 8 = 16
*
* 经过测试发现:
* keysize: must be equal to 128, 192 or 256
* aes key长度 16,24,32
* 以上的两个条件相互都成立,而不是如下的第一组,第二组,第三组的强制配对。
*/
public class AesUtil { //算法
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
//密钥 (静态aesKey)
//第一组
public static final String KEY = "9862ecf540c64534";
// public static final String KEY = "yyyyyyyyyyyyyyyy"; //16位
//
private static final Integer LEN = 128; //第二组
// public static final String KEY = "yyyyyyyyyyyyyyyy91a1e003c11b414e"; //32位
// private static final Integer LEN = 256; //第三组
// public static final String KEY = "yyyyyyyyyyyyyyyy91a1e003"; //24位
// private static final Integer LEN = 192; // 加密类型
private static final String TYPE = "AES"; /**
* aes加密 - 静态aesKey
*
* @param content
* @return
* @throws Exception
*/
public static String aesEncrypt(String content) {
try {
return aesEncrypt(content, KEY);
} catch (Exception e) {
e.printStackTrace();
return "";
}
} /**
* aes解密 - 静态aesKey
*
* @param encrypt 内容
* @return
* @throws Exception
*/
public static String aesDecrypt(String encrypt) {
try {
return aesDecrypt(encrypt, KEY);
} catch (Exception e) {
e.printStackTrace();
return "";
}
} /**
* 将base 64 code AES解密
*
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
public static String aesDecrypt(String encryptStr, String decryptKey) throws Exception {
return isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr), decryptKey);
} /**
* AES解密
*
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解密密钥
* @return 解密后的String
* @throws Exception
*/
public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance(TYPE);
//Wrong keysize: must be equal to 128, 192 or 256
kgen.init(LEN); Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), TYPE));
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
} /**
* base 64 decode
*
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
public static byte[] base64Decode(String base64Code) throws Exception {
return isEmpty(base64Code) ? null : Base64.getDecoder().decode(base64Code);
} /**
* AES加密为base 64 code
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
public static String aesEncrypt(String content, String encryptKey) throws Exception {
return base64Encode(aesEncryptToBytes(content, encryptKey));
} /**
* base 64 encode
*
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
public static String base64Encode(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
} /**
* AES加密
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
* @throws Exception
*/
public static byte[] aesEncryptToBytes(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance(TYPE);
//Wrong keysize: must be equal to 128, 192 or 256
kgen.init(LEN); //128 / 8 = 16 Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), TYPE));
return cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
} /**
* 将byte[]转为各种进制的字符串
*
* @param bytes byte[]
* @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
* @return 转换后的字符串
*/
public static String binary(byte[] bytes, int radix) {
return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数
} public static boolean isEmpty(CharSequence cs) {
return cs == null || cs.length() == 0;
} /**
* 测试
* output:
* 对比:RASPublicAuthUtil.java输出结果 对比一致
* username AES加密后的数据:wG2GS4DxYko57DoL0kAAWA%3D%3D
* username解码:wG2GS4DxYko57DoL0kAAWA==
*
*encrypt=wG2GS4DxYko57DoL0kAAWA==
* encodeEncrypt=wG2GS4DxYko57DoL0kAAWA%3D%3D
* decrypt=admin
*
*/
public static void main(String[] args) throws Exception {
// JSONObject jsonObject = new JSONObject();
// jsonObject.put("ticketId", "8310000002021051115277C");
// jsonObject.put("serviceItemId", "100000000708");
// jsonObject.put("timestamp", new Date());
// System.out.println("json data=" + jsonObject.toJSONString());
// String encrypt = aesEncrypt(jsonObject.toJSONString());
//aes加密
String encrypt = aesEncrypt("admin");
System.out.println("encrypt=" + encrypt);
//aes编码
String encodeEncrypt = URLEncoder.encode(encrypt, "UTF-8");
System.out.println("encodeEncrypt=" + encodeEncrypt); //aes解密
String decodeEncrypt = URLDecoder.decode(encodeEncrypt,"UTF-8");
String decrypt = aesDecrypt(decodeEncrypt);
System.out.println("decrypt=" + decrypt);
}
} package com.example.core.mydemo.spi; import com.alibaba.fastjson.JSONObject; import javax.crypto.Cipher;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.UUID; /**
**/
public class RSAPublicAuthUtil { // Base64解密
private static final Base64.Decoder decoder = Base64.getDecoder();
// Base64加密
private static final Base64.Encoder encoder = Base64.getEncoder(); /**
* 非对称密钥算法
*/
public static final String KEY_ALGORITHM = "RSA"; /**
* 公钥
*/
private static final String PUBLIC_KEY = "可以使用支付宝开放平台开发助手.exe工具生成";
/**
* 私钥
*/
private static final String PRIVATE_KEY = "可以使用支付宝开放平台开发助手.exe工具生成"; /**
* @param data
* @throws
* @Description:
* @return: java.lang.String
* @Author: MeiQi
* @Date: 2021/7/12 20:50
**/
public static String encryptByPublicKey(String data)throws Exception {
byte[] key_byte = decoder.decode(PUBLIC_KEY);
byte[] encrypt_str = encryptByPublicKey(decoder.decode(data), key_byte);
return encoder.encodeToString(encrypt_str);
} /**
* @param data 待加密数据
* @param key 密钥
* @throws
* @Description: 公钥加密
* @return: byte[] 加密数据
* @Author: MeiQi
* @Date: 2021/7/12 20:51
**/
private static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
//实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥
//密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
//数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
} /**
* 私钥解密
* @param secretText 待解密的密文字符串
* @return 解密后的明文
*/
public static String decryptByPrivateKey(String secretText) {
try {
String privateKeyStr = PRIVATE_KEY;
String input_charset = "UTF-8";
// 生成私钥
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr));
// 密文解码
byte[] secretTextDecoded = decoder.decode(secretText);
byte[] tempBytes = cipher.doFinal(secretTextDecoded);
// return new String(tempBytes);
return encoder.encodeToString(tempBytes);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + secretText + "]时遇到异常", e);
}
} /**
* 得到私钥
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
private static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes;
keyBytes = decoder.decode(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
} /**
* output:
* 公钥:~~
* 原文:admin
* 原文:25
* aesKey:9862ecf540c64534
* username AES加密后的数据:wG2GS4DxYko57DoL0kAAWA%3D%3D
* age AES加密后的数据:NUjk8UtCDZq7U8HhRNixNQ%3D%3D
* 使用公钥加密prikey后的数据:NJ2dUzqqUwzcrYqV5GX0xKDo9eBuC1hjvTUAmtZmC9xoTX7nc0JhEErO2AZRyCS47Bc6CZi68MWSKsBt9bNxIfkY3ciGWOxSgHNhOVpWM8wEjWb6q%2BNcoLV9p7wapdur43v3jdcGFhzD0ugmDMiTPhCPfp0Dz3s9qTZD6rN1uc0%3D
* http://localhost:8010/#/index?&username=wG2GS4DxYko57DoL0kAAWA%3D%3D&age=NUjk8UtCDZq7U8HhRNixNQ%3D%3D&prikey=NJ2dUzqqUwzcrYqV5GX0xKDo9eBuC1hjvTUAmtZmC9xoTX7nc0JhEErO2AZRyCS47Bc6CZi68MWSKsBt9bNxIfkY3ciGWOxSgHNhOVpWM8wEjWb6q%2BNcoLV9p7wapdur43v3jdcGFhzD0ugmDMiTPhCPfp0Dz3s9qTZD6rN1uc0%3D
* prikey解码:NJ2dUzqqUwzcrYqV5GX0xKDo9eBuC1hjvTUAmtZmC9xoTX7nc0JhEErO2AZRyCS47Bc6CZi68MWSKsBt9bNxIfkY3ciGWOxSgHNhOVpWM8wEjWb6q+NcoLV9p7wapdur43v3jdcGFhzD0ugmDMiTPhCPfp0Dz3s9qTZD6rN1uc0=
* prikey解密:9862ecf540c64534
* username解码:wG2GS4DxYko57DoL0kAAWA==
* username解密:admin
* age解码:NUjk8UtCDZq7U8HhRNixNQ==
* age解密:25
*/ /**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//发送端
System.out.println("公钥:" + PUBLIC_KEY);
String username = "admin";
System.out.println("原文:" + username);
String age = "25";
System.out.println("原文:" + age); String nonceStr = UUID.randomUUID().toString().replace("-", "");
String aesKey = nonceStr.substring(0, 16);
System.out.println("aesKey:" + aesKey); username = AesUtil.aesEncrypt(username, aesKey);
username = URLEncoder.encode(username, "UTF-8");
System.out.println("username AES加密后的数据:" + username); age = AesUtil.aesEncrypt(age, aesKey);
age = URLEncoder.encode(age, "UTF-8");
System.out.println("age AES加密后的数据:" + age); //发送端进行数据的加密
String prikey = RSAPublicAuthUtil.encryptByPublicKey(aesKey);
prikey = URLEncoder.encode(prikey, "UTF-8");
System.out.println("使用公钥加密prikey后的数据:" + prikey); String base_url = "http://localhost:8010/#/index?";
System.out.println(base_url.concat("&username=").concat(username).concat("&age=").concat(age).concat("&prikey=").concat(prikey)); //接收端
prikey = URLDecoder.decode(prikey,"UTF-8");
System.out.println("prikey解码:" + prikey);
String decryAes = RSAPublicAuthUtil.decryptByPrivateKey(prikey);
System.out.println("prikey解密:" + decryAes); username = URLDecoder.decode(username,"UTF-8");
System.out.println("username解码:" + username);
String decryUsernameStr = AesUtil.aesDecrypt(username,decryAes);
System.out.println("username解密:" + decryUsernameStr); age = URLDecoder.decode(age,"UTF-8");
System.out.println("age解码:" + age);
String decryAgeStr = AesUtil.aesDecrypt(age,decryAes);
System.out.println("age解密:" + decryAgeStr); }
}
RSA公私钥生成可以使用支付宝开放平台开发助手.exe工具生成

SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计的更多相关文章
- Python之登陆接口设计
刚刚开始学习Python,第一个编写的程序. import os user_file = open('use_file.txt', 'r') user_list = user_file.readlin ...
- python——登陆接口设计(循环方法)
近日重新整理了登陆接口设计程序,感觉以前的代码没有注释,让园子的其他童鞋读起来比较费劲.也没有流程图和程序运行说明. 1.流程图 2.user_file.txt&lock_file.txt文件 ...
- Web设计中打开新页面或页面跳转的方法 js跳转页面
Web设计中打开新页面或页面跳转的方法 一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx ...
- web设计页面跳转的方法
一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...
- Web设计中打开新页面或页面跳转的方法
一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...
- wex5 教程 之 图文讲解 登陆,注册,页面跳转
视频教程地址:http://v.youku.com/v_show/id_XMTc3OTE0Nzg0NA==.html 效果预览: 登陆页面 首页用windowContainer装载 注册页面 登陆 ...
- Android实现页面跳转、ListView及其事件
Android实现页面跳转.ListView及其事件 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 进入主页面后,使用ListView实现特 ...
- ASP.NET页面跳转的三种方法比较
在ASP.NET下,经常需要在页面之间跳转,下面我们来分别介绍一下关于.NET中Response.Redirect(),Sever.Execute(),Server.Transfer() 三种页面跳转 ...
- Behavior的使用(一):页面跳转NavigateToPageAction
Behavior的使用,让UI设计师能够更加方便的进行UI设计,更高效地和开发进行合作.Behavior有三种触发方式:EventTriggerBehavior事件触发,DataTriggerBeha ...
- ASP.NET页面跳转的三大方法详解
ASP.NET页面跳转有什么方法呢?,现在给大家介绍三种方法,他们的区别是什么呢?让我们开始吧: ASP.NET页面跳转1.response.redirect 这个跳转页面的方法跳转的速度不快,因为它 ...
随机推荐
- dotnetCampus.UITest.WPF 一个支持中文用例的界面单元测试框架
本文来安利大家一个支持使用中文做用例名的 WPF 界面 UI 单元测试框架 卖点 有没有觉得命名太难?有没有觉得单元测试的命名更难?没错,这是一个业界的大问题.很多团队都会因为单元测试的用例函数命名太 ...
- 为什么需要学习ITSM/ITIL
假如你需要管理一个超过20人的IT服务组织,一般会面临以下问题: 人多事杂活重,每个人都很累,工作却还是一团糟糕, 用户方怨声载道,领导也颇有微词,同事间也经常互相甩锅埋坑, 工作只是救火或者混日子, ...
- kibana-6.2.4-amd64的安装
ubuntu系统 kibana: https://mirrors.huaweicloud.com/kibana/?C=N&O=D 找到6.2.4的下载连接 方法一: 下载tar包,解压即可: ...
- ibus 输入法导致输入卡顿的解决方案
系统: Zorin OS 16 Pro 基于 Ubuntu 20.04 LTS 关键词:Linux 间歇性卡顿.输入法导致卡顿.无法输入 本问题发生的情形是系统间歇性的无法接受键盘输入,无意间发现切换 ...
- link标签的media属性
media属性表示被链接的文档将显示在什么设备上.比如下面的例子: <head> <link rel="stylesheet" type="text/c ...
- DNS(1) -- DNS服务及dns资源类型
目录 1.1 DNS服务概述 1.2 DNS域名结构 1.3 DNS解析原理 1.3.1 DNS查询类型 1.3.2 解析答案 1.4 DNS资源记录类型 1.1 DNS服务概述 DNS(Domain ...
- 2022年官网下安装ActiveMQ最全版与官网查阅方法
目录 一.环境整合 构建工具(参考工具部署方式) 二.下载安装 1.百度搜索ActiveMQ,双击进入.或访问官网https://activemq.apache.org/ 2.进入下载界面,两种方式, ...
- swagger文档枚举类型描述
背景: 问题:使用swagger作为api文档,但文档中的枚举类型仅显示枚举name,对于使用文档的人员来讲不容易理解 解决思路:枚举类型加上自定义的描述 解决方案 maven配置 <depen ...
- k8s的知识图谱以及相关的知识梳理
一 kubernetes的知识图谱如下所示: 可以随时的根据自身情况来学习和深化对知识点的总结和归档
- linux sort命令的重要用法:按分隔符/字母/数字/月份进行排序
1.指定分隔符,以某一列进行排序并输出 #-t 指定一个分隔符 #-k 后面跟数字,指定按第几列进行排序 #-r 反序排序(升序变成降序) #按":"做分隔符,以第3列,也就是用户 ...