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加密算法应用跨服务免登陆接口设计的更多相关文章

  1. Python之登陆接口设计

    刚刚开始学习Python,第一个编写的程序. import os user_file = open('use_file.txt', 'r') user_list = user_file.readlin ...

  2. python——登陆接口设计(循环方法)

    近日重新整理了登陆接口设计程序,感觉以前的代码没有注释,让园子的其他童鞋读起来比较费劲.也没有流程图和程序运行说明. 1.流程图 2.user_file.txt&lock_file.txt文件 ...

  3. Web设计中打开新页面或页面跳转的方法 js跳转页面

    Web设计中打开新页面或页面跳转的方法 一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx ...

  4. web设计页面跳转的方法

    一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...

  5. Web设计中打开新页面或页面跳转的方法

    一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...

  6. wex5 教程 之 图文讲解 登陆,注册,页面跳转

    视频教程地址:http://v.youku.com/v_show/id_XMTc3OTE0Nzg0NA==.html 效果预览: 登陆页面   首页用windowContainer装载 注册页面 登陆 ...

  7. Android实现页面跳转、ListView及其事件

    Android实现页面跳转.ListView及其事件 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 进入主页面后,使用ListView实现特 ...

  8. ASP.NET页面跳转的三种方法比较

    在ASP.NET下,经常需要在页面之间跳转,下面我们来分别介绍一下关于.NET中Response.Redirect(),Sever.Execute(),Server.Transfer() 三种页面跳转 ...

  9. Behavior的使用(一):页面跳转NavigateToPageAction

    Behavior的使用,让UI设计师能够更加方便的进行UI设计,更高效地和开发进行合作.Behavior有三种触发方式:EventTriggerBehavior事件触发,DataTriggerBeha ...

  10. ASP.NET页面跳转的三大方法详解

    ASP.NET页面跳转有什么方法呢?,现在给大家介绍三种方法,他们的区别是什么呢?让我们开始吧: ASP.NET页面跳转1.response.redirect 这个跳转页面的方法跳转的速度不快,因为它 ...

随机推荐

  1. 拥抱云原生,Fluid结合JindoFS :阿里云OSS加速利器

    简介: Fluid 是一个开源的 Kubernetes 原生的分布式数据集编排和加速引擎,主要服务于云原生场景下的数据密集型应用.在 Fluid 上使用和部署 JindoRuntime 实现数据集的可 ...

  2. 阿里巴巴在开源压测工具 JMeter 上的实践和优化

    简介:Apache JMeter 是 Apach 旗下的开源压测工具,创建于 1999 年初,迄今已有超过 20 年历史.JMeter 功能丰富,社区(用户群体)庞大,是主流开源压测工具之一. 作者: ...

  3. 使用 Arthas 排查 SpringBoot 诡异耗时的 Bug

    简介: 公司有个渠道系统,专门对接三方渠道使用,没有什么业务逻辑,主要是转换报文和参数校验之类的工作,起着一个承上启下的作用.最近,在优化接口的响应时间,优化了代码之后,但是时间还是达不到要求:有一个 ...

  4. Azkaban业务流程如何转化为DataWorks业务流程

    简介: 用户在迁移上云的时候,需要将云下的的Azkaban任务迁移上云,之前通过用户在DataWroks一步步创建对应的业务流程,其转化难度和转化时间都是一定的成本和时间,但如何能做到省时省力的方式迁 ...

  5. 分久必合的Lindorm传奇

    简介: 2009年,阿里巴巴首先提出用分布式架构替代传统商业数据库,成功用自主开源的AliSQL支撑双11数据洪流:2016年,为应对超大规模业务场景,阿里云开始自研分布式数据库.十余年间,阿里巴巴数 ...

  6. Serverless 工程实践 | 自建 Apache OpenWhisk 平台

    ​简介: OpenWhisk 是一个开源.无服务器的云平台,可以在运行时容器中通过执行扩展的代码响应各种事件,而无须用户关心相关的基础设施架构. OpenWhisk 简介 OpenWhisk 是基于云 ...

  7. 延迟绑定与retdlresolve

    延迟绑定与retdlresolve 我们以前在ret2libc的时候,我们泄露的libc地址是通过延迟绑定实现的,我们知道,在调用libc里面的函数时候,它会先通过plt表和gor表绑定到,函数真实地 ...

  8. 超好用的 Redis GUI 工具,你值得拥有

    超好用的 Redis GUI 工具,你值得拥有 提供原生的性能,并且比使用 Electron 等 Web 技术开发的同等应用程序消耗的资源少得多. 下载地址:http://www.redisant.c ...

  9. C语言程序设计-笔记04-函数

    C语言程序设计-笔记04-函数 例5-1  计算圆柱体的体积.输入圆柱的高和半径,求圆柱体积volume=πxr^2xh.要求定义和调用函数cylinder(r,h)计算圆柱体的体积. #includ ...

  10. Docker的Portainer认识、安装、使用

    一.认识 docker的图形化界面 Portainer 是一个轻量级的容器管理界面,可以让用户更轻松地管理 Docker 容器.镜像.网络和数据卷等.Portainer 提供了一个用户友好的 Web ...