前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计

SOP页面跳转设计 RAS AES加密算法应用跨服务免登陆接口设计

作者头像
oktokeep
发布2024-10-09 11:23:19
710
发布2024-10-09 11:23:19
举报
文章被收录于专栏:第三方工具

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代码示例:

代码语言:javascript
复制
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工具生成

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档