当前位置: 首页 > news >正文

nas上建设网站云南网站开发网络公司前10

nas上建设网站,云南网站开发网络公司前10,mooc网站建设,系统总裁为什么要设计安全的api接口 运行在外网服务器的接口暴露在整个互联网中#xff0c;可能会受到各种攻击#xff0c;例如恶意爬取服务器数据、恶意篡改请求数据等#xff0c;因此需要一个机制去保证api接口是相对安全的。 本项目api接口安全设计 本项目api接口的安全性主要…为什么要设计安全的api接口 运行在外网服务器的接口暴露在整个互联网中可能会受到各种攻击例如恶意爬取服务器数据、恶意篡改请求数据等因此需要一个机制去保证api接口是相对安全的。 本项目api接口安全设计 本项目api接口的安全性主要是为了请求参数不会被篡改和防止接口被多次调用而产生脏数据实现方案主要围绕令牌(token)、时间戳(timestamp)、签名(signature)三个机制展开设计。 模拟前端签名与后端验证签名 RSA密钥对生成 KeyPairGenerator生成RSA密钥对 自定义Generator密钥生成器 package com.atguigu.signcenter.util;import org.apache.tomcat.util.codec.binary.Base64;import java.io.UnsupportedEncodingException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey;/*** 自定义Generator密钥生成器* 描述密钥生成器** RSA密钥对生成* KeyPairGenerator生成RSA密钥对*** author: jd* create: 2024-07-30*/ public class Generator {public static final String ALGORITHM_RSA RSA;private static final String RSA_CHARSET UTF-8;public static void main(String[] args) throws Exception {// 初始化密钥对生成器生成RSA密钥对KeyPairGenerator keyPairGen KeyPairGenerator.getInstance(ALGORITHM_RSA);// // 可以指定密钥大小如1024位keyPairGen.initialize(1024);// 生成密钥对KeyPair keyPair keyPairGen.generateKeyPair();//从密钥对中获取公钥RSAPublicKey rsaPublicKey (RSAPublicKey)keyPair.getPublic();// 获取公钥的ASN.1 DER编码 byte[] keyBs rsaPublicKey.getEncoded();String publicKey encodeBase64(keyBs);System.out.println(生成的公钥\r\n publicKey);//从密钥对中获取私钥RSAPrivateKey rsaPrivateKey (RSAPrivateKey) keyPair.getPrivate();// 获取私钥的ASN.1 DER编码keyBs rsaPrivateKey.getEncoded();String privateKey encodeBase64(keyBs);System.out.println(生成的私钥\r\n privateKey);}/*** 描述byte数组转String* param source 入参byte数组* return*/public static String encodeBase64(byte[] source) throws UnsupportedEncodingException {return new String(Base64.encodeBase64(source), RSA_CHARSET);}/*** 描述String转byte数组* param target 入参字符串* return* throws Exception*/public static byte[] decodeBase64(String target) throws Exception {return Base64.decodeBase64(target.getBytes(RSA_CHARSET));}} 测试效果 生成的公钥 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDSv50KbmfIibYRZoFnVLdtjp/sjDAAHrAwWu9lLk6zSfx9QhEqGFbeLD6tDuS0vcBoXRCrXphOvDbMGjEWPRGw0bz2Q65zfwLTyk//XBgezDTNBK3VYYeMu9/Skgdm9lZDsvXFHPBypTfJf8/Co7sKZRXtwS69pT0UK9uMWN03wIDAQAB 生成的私钥 MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANK/nQpuZ8iJthFmgWdUt22OnyMMAAesDBa72UuTrNJ/H1CESoYVt4sPq0O5LS9wGhdEKtemE68NswaMRY9EbDRvPZDrnN/AtPKT/9cGB7MNM0ErdVhh4y739KSB2b2VkOy9cUc8HKlN8l/z8KjuwplFe3BLr2lPRQr24xY3T7fAgMBAAECgYBSVqS/f5Uyx4MH11m1imbDhZHcBoM4fCKYzmRipfaAeq1JYqMSo3UWgHays15nD3FW01w2ArY5nPdBx1NhE3DicwKbbtvIpgfMRGU0EYBkm2pNdGaQDI3UYyLeMOjytletH85Dj0kue4YHSOVDPGj2sNAHtaKTL57d65Q8QJBAPd5YALQgNAQLNCjhaDZYbdeySOrtp7uP0kAs37NywFgf9L14FMi0orTr1FduexYs2cB9tPpMJp43nzDppohNCcCQQDaAlUrbjxBHf0cPhWHcMOiEFUqPCFQB/JJDQsCZVFA8ZwXAUTOAi51tK3ID0XcsJzVZiaIlI6CyVE8WRKVrLqJAkEAqhNQWJ7S6Cs1oW3AOHstHMiXk1w/dZpnA9Tnhw4HpjqbnnA8auZTq/UvV8wCKtwK74/6AkkQjhjjTvtnVCXdoQJBAJqGrsHzCAiL7h23rDpv/ErG8cYextRYIcGaKgGCD1YNM5lgCDsVTDNa6pjLZqBTCJkGSdEAqKEee5pxqaCkCQHIrF3nC9CoaJMrywRYOF3sKNt9loHWHOg5wtzt0Ccdfy3MKpuJjMlWqQe8Licz/FcaQFMr9PVtk93cHBtIDANo使用keytool生成RSA密钥对 keytool口令生成一个名称为jwt.jks、别名为jwt的RSA密钥证书 keytool -genkey -alias jwt -keyalg RSA -keystore jwt.jks注意如果提示keytool 工具未找到则直接到JDK的bin目录下cmd执行即可。 产生了秘钥文件 然后把产生的秘钥文件放到类路径下面 KeyPair配置类 KeyPairConfig.java package com.atguigu.signcenter.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;import java.security.KeyPair;/*** author: jd* create: 2024-07-30*/ Configuration public class KeyPairConfig {Beanpublic KeyPair keyPair() {//从classpath下的证书中获取秘钥对KeyStoreKeyFactory keyStoreKeyFactory new KeyStoreKeyFactory(new ClassPathResource(jwt.jks), 123456.toCharArray());return keyStoreKeyFactory.getKeyPair(jwt, 123456.toCharArray());} } SecurityUtilTestService服务类 package com.atguigu.signcenter.service;import java.io.UnsupportedEncodingException;public interface SecurityUtilTestService {public void test() throws UnsupportedEncodingException; } SecurityUtilTestServiceImpl.java 服务实现类 package com.atguigu.signcenter.service.serviceImpl;import com.atguigu.signcenter.service.SecurityUtilTestService; import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.codec.binary.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.io.UnsupportedEncodingException; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey;/***https://blog.csdn.net/weixin_47560078/article/details/118222785* 使用keytool生成RSA密钥对* keytool口令生成一个名称为jwt.jks、别名为jwt的RSA密钥证书* author: jd* create: 2024-07-30*/Slf4j Service public class SecurityUtilTestServiceImpl implements SecurityUtilTestService {Autowiredpublic KeyPair keyPair;public void test() throws UnsupportedEncodingException {RSAPublicKey publicKey (RSAPublicKey) keyPair.getPublic();log.info(公钥信息 \n {} \n 公钥:{}, publicKey.toString(), encodeBase64(publicKey.getEncoded()));RSAPrivateKey priKey (RSAPrivateKey) keyPair.getPrivate();log.info(私钥信息 \n {} \n 私钥:{}, priKey.toString(), encodeBase64(priKey.getEncoded()));}public String encodeBase64(byte[] source) throws UnsupportedEncodingException {return new String(Base64.encodeBase64(source),UTF-8);}} 测试效果 2024-08-02 09:28:00.380 INFO 15240 --- [nio-8025-exec-1] c.a.s.s.s.SecurityUtilTestServiceImpl : 公钥信息 Sun RSA public key, 2048 bitsmodulus: 23829896032654266449237055885186070100267258718676980642255177035533633961682767587031637650539693543712242029204450662903733370684503258275060048893522899536661642394654212548304797355318568454907620090143269620466272360481207010741679722568484516052908816917363309070994255480818549791827817786183403586871515551029544108830017390208760682982163893096953077182893148288822722804881185915432409621143786029919505816246686776327742032964509838775989821139201389029065260189892568467570697405413232162062535688873178341418936979958788897096099384096388668260002427751117248616155956906183130250777246881881675374119023public exponent: 65537 公钥:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvMTmPTwH1lX5wnfQndyU2s0945VNpagEFGDZpQsh30377r5tB7baUv4WW4AkDtGzE1Tog8vZStZGnZzxOzcfi65Lfwir7BaXm1BZX2VzPHcj6pi/rzNoQBfCVu4sb2OuOzU2znpQdDJsp4oBZYLOOc201vUyj//2CZXljIFS22OLdFcsyabAeWVK8eLuWrNeV4wIScP2oGOBED5amvNlojhlrYP//Rq2HZxZJAQWZFKzbqMqcY9xz74DZK4ZE8ttSfVjMNQ6ZzI76MGIWXzIh83OeLJv/wC9LpDMdlkGnbRVWUSt14IFLIJiMGIG7PsJIaCH9Ri8qpLclHIbwIDAQAB 2024-08-02 09:28:00.381 INFO 15240 --- [nio-8025-exec-1] c.a.s.s.s.SecurityUtilTestServiceImpl : 私钥信息 sun.security.rsa.RSAPrivateCrtKeyImplffdad0f9 私钥:MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC8xOY9PAfWVfnCd9Cd3JTazT3jlU2lqAQUYNmn5CyHfTfvuvm0HttpS/hZbgCQO0bMTVOiDy9lK1kadnPE7NxLrkt/CKvsFpebUFlfZXM8dyPqmLvM2hAF8JW7ixvY647NTbOelB0MmynigFlgs45zbTW9TKP//YJleWMgVLbY4t0VyzJpsB75ZUrx4u5as15XjAhJw/agY4EQPlqa82WiOGWtg//9GrYdnFkkBBZkUrNuoypxj3H7PvgNkrhkTy21J9WMw1DpnMjvowYhZfMiHzc754sm//AL0ukMx2WQadtFVZRK3XggUsgmIwYgbswkhoIf1GLyqkv5yUchvAgMBAAECggEAIWFcKXXlGOTJLrdLP68S74IdsJHlUibc2dGqi4LQ0QC2lIDmyRAv0nXpq77FALxKr7P41w6CXgyFTCWoISmVcAbJHjWY2KKByHLffpfvlncqfoktykgOwKq1I42BooSXqWHP3hhmhAnssNZA04QN5fkU9kgTsd0cXOO3QK9aRTIOrogcdor1auytnpNQKBRA6We7MJo67HFWn1DkacKdYatyjI4B11eSuHQoiGSR92Is0ITnu1ToVZq8ljknI87sUeSr2745ZNa9dvCixnqu3MDo8MpriIbvIs/ou/EIkOkWIqxk3ZcJlnSLAp3KExzZrEn6oNgnt0f5o1SQKBgQDeCvijwzUfgPFT6BmqcG7aizd8c9muwIJq5SZ092WbkeYLJ1MTE/M/FdYgf60RGerIoqs/MS5Wq22Wkm2zoNExlx1J74j3T/hLJi83k2sPcLZ8ERylF2gxHCC0mSq8XYBP95JnhP3GhJAb0AfZAX33aNlTmhIx0dGK/E3LEwKBgQDZo0EhzhTQ6LfKgdq856V0BhPCrUMAiclvgww9hZTKJizDDhYRmozplqMxJDsoYMUIrT4HOgn1hhyVyQrLUuU4avwlFvttRV2qP5DN23cCmO2fCEl1VZsdfYwM6Wxi5W3HtrfPCOTI3UDCBBaIVIY5ysgaYN/K3d7GApbx8tQKBgQC6Fr3NGZPTBFC8wamwLSxqklR9QaDE6n5hnTVgGWynPMME/gGvCiXjWiR2IasCzXeIsJlCY1FHpwtgLvYrnjLUec49IbhLdMUlzimyTSVjulXl4r18CwLybZ1nXhq35TDdVCJqCcZZ8s2H0bBSCXMVv9SrwStbW837HGa7k6wKBgDEfLw5X2lnnVQPyxcoEagGVx9xi9XrQ5PvuCuKovKdeyzrWP/QKk3uuha1XsTWVQPScZZgPXjbfk9T65ib5QHkcUSIKcecNFQ/rsWbdCI4GutqLRkYnAhSkl1tM6VQOlxbz3MdA62aich6lC0vMiYMlag5wjdJ0EXwPyZIChAoGBALY2A7hlCaI8tbg2QVnbMBBmLCUWneEV3wVVehDSMA3Dwq6jD/MrCHHSdFIk0pOsHYkKyifrhjS58M/irrwv1fsbs/NHdjngBHYGswP10cYyCNSI9LvsN47/pVxDPr/9nUfSB2wNWUTaRLflPpokT8tmMc4AIkAmri6VWXnlgO 进行实际的http请求的签名模块模拟签名与验证 模块pom依赖 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.6.3/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.atguigu/groupIdartifactIdsign-center/artifactIdversion0.0.1-SNAPSHOT/versionnamesign-center/namedescriptionapi接口的安全设计/descriptionurl/licenseslicense//licensesdevelopersdeveloper//developersscmconnection/developerConnection/tag/url//scmpropertiesjava.version1.8/java.version!-- spring-cloud.version2021.0.4/spring-cloud.version--spring-cloud.version2021.0.1/spring-cloud.version/propertiesdependencies!-- redisson依赖--dependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion3.15.5/version/dependency!--redis链接客户端--dependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion3.2.0/version/dependency!--fastjson--dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.62/version/dependency!--集成redis--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactIdversion2.1.7.RELEASE/version/dependency!--joda time 这个还有些问题这个类库是做什么的--dependencygroupIdjoda-time/groupIdartifactIdjoda-time/artifactIdversion2.10/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-mail/artifactId/dependencydependencygroupIdcom.atguigu.gulimall/groupIdartifactIdgulimall-common/artifactIdversion0.0.1-SNAPSHOT/versionexclusionsexclusionartifactIdservlet-api/artifactIdgroupIdjavax.servlet/groupId/exclusion/exclusions/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-amqp/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.amqp/groupIdartifactIdspring-rabbit-test/artifactIdscopetest/scope/dependency!--什么作用 --dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-collections4/artifactIdversion4.2/version/dependencydependencygroupIdorg.springframework.amqp/groupIdartifactIdspring-rabbit/artifactIdversion2.4.2/versionscopecompile/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexcludesexcludegroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/exclude/excludes/configuration/plugin/plugins/build/project 主类 package com.atguigu.signcenter;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;EnableDiscoveryClient SpringBootApplication public class SignCenterApplication {public static void main(String[] args) {SpringApplication.run(SignCenterApplication.class, args);}} 封装的安全工具类SecurityUtil package com.atguigu.signcenter.util;import org.apache.tomcat.util.codec.binary.Base64; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;/*** 描述安全工具类* ————————————————* p* 原文链接https://blog.csdn.net/weixin_47560078/article/details/118222785** author: jd* create: 2024-07-31*/ public class SecurityUtil {//加密算法private static final String ALGORITHM_RSA RSA;//字符编码指定的字符集private static final String RSA_CHARSET UTF-8;/*** 描述将字符串通过RSA算法公钥加密** param content 需要加密的内容* param pubKey 公钥* return 加密后字符串* throws Exception*/private static String EncryptByRSAPubKey(String content, String pubKey) throws Exception {try {PublicKey publicKey SecurityUtil.getRSAPubKey(pubKey);Cipher cipher Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, publicKey);cipher.update(content.getBytes(RSA_CHARSET));return SecurityUtil.encodeBase64(cipher.doFinal());} catch (Exception e) {e.printStackTrace();throw new Exception();}}/*** 描述将字符串通过RSA算法公钥解密** param content 需要解密的内容* param pubKey 公钥* return 解密后字符串* throws Exception*/public static String DecryptByRSAPubKey(String content, String pubKey) throws Exception {try {PublicKey publicKey SecurityUtil.getRSAPubKey(pubKey);Cipher cipher Cipher.getInstance(publicKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, publicKey);cipher.update(SecurityUtil.decodeBase64(content));return new String(cipher.doFinal(), RSA_CHARSET);} catch (Exception e) {e.printStackTrace();throw new Exception();}}/*** 描述将字符串通过RSA算法私钥加密** param content 需要加密的内容* param priKey 私钥* return 加密后字符串* throws Exception*/public static String EncryptByRSAPriKey(String content, String priKey) throws Exception {try {PrivateKey privateKey SecurityUtil.getRSAPriKey(priKey);Cipher cipher Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.ENCRYPT_MODE, privateKey);cipher.update(content.getBytes(RSA_CHARSET));return SecurityUtil.encodeBase64(cipher.doFinal());} catch (Exception e) {e.printStackTrace();throw new Exception();}}/*** 描述将字符串通过RSA算法私钥解密** param content 需要解密的内容* param priKey 私钥* return 解密后字符串* throws Exception*/public static String DecryptByRSAPriKey(String content, String priKey) throws Exception {try {PrivateKey privateKey SecurityUtil.getRSAPriKey(priKey);Cipher cipher Cipher.getInstance(privateKey.getAlgorithm());cipher.init(Cipher.DECRYPT_MODE, privateKey);cipher.update(SecurityUtil.decodeBase64(content));return new String(cipher.doFinal(), RSA_CHARSET);} catch (Exception e) {e.printStackTrace();throw new Exception();}}/*** 从秘钥文件中获取密钥对** return*/private static KeyPair getKeyPair(){//从classpath下的证书中获取秘钥对KeyStoreKeyFactory keyStoreKeyFactory new KeyStoreKeyFactory(new ClassPathResource(jwt.jks), 123456.toCharArray());return keyStoreKeyFactory.getKeyPair(jwt, 123456.toCharArray());}/*** 从jwt.jks文件中获取公钥字符串** return* throws Exception*/public static String getPublicKey() throws Exception {// 获取密钥对KeyPair keyPair getKeyPair();// 获取私钥信息PublicKey publicKey keyPair.getPublic();//byte 转 Stringreturn encodeBase64(publicKey.getEncoded());}/*** 从jwt.jks文件中获取私钥字符串** return* throws Exception*/public static String getPrivateKey() throws Exception {// 获取密钥对KeyPair keyPair SecurityUtil.getKeyPair();// 获取私钥信息PrivateKey privateKey keyPair.getPrivate();// byte 转 Stringreturn SecurityUtil.encodeBase64(privateKey.getEncoded());}/*** 描述获取RSA私钥** param priKey 私钥* return PrivateKey* throws Exception*/private static PrivateKey getRSAPriKey(String priKey) throws Exception {try {PKCS8EncodedKeySpec privateKeySpec new PKCS8EncodedKeySpec(SecurityUtil.decodeBase64(priKey));KeyFactory keyFactory KeyFactory.getInstance(ALGORITHM_RSA);return keyFactory.generatePrivate(privateKeySpec);} catch (Exception e) {e.printStackTrace();throw new Exception();}}/*** 描述获取RSA公钥** param pubKey 公钥* return*/private static PublicKey getRSAPubKey(String pubKey) throws Exception {try {X509EncodedKeySpec publicKeySpec new X509EncodedKeySpec(SecurityUtil.decodeBase64(pubKey));KeyFactory keyFactory KeyFactory.getInstance(ALGORITHM_RSA);return keyFactory.generatePublic(publicKeySpec);} catch (Exception e) {e.printStackTrace();}return null;}/*** base64编码** param source* return* throws Exception*/public static String encodeBase64(byte[] source) throws Exception {return new String(Base64.encodeBase64(source), RSA_CHARSET);}/*** Base64解码** param target 需要解码的目标字符串* return*/private static byte[] decodeBase64(String target) throws Exception {return Base64.decodeBase64(target.getBytes(RSA_CHARSET));}public static void main(String[] args) throws Exception {//获取公钥String pubKey getPublicKey();//获取私钥String priKey getPrivateKey();//需要加密的参数String content age18nameyushanma;//字符串加密String s EncryptByRSAPubKey(content, pubKey);System.out.println(s参数通过公钥加密后 s);System.out.println(加密后的字符串通过私钥解密后 DecryptByRSAPriKey(s, priKey));content age18nameyushanma;s EncryptByRSAPriKey(content, priKey);System.out.println(s参数通过私钥加密后 s);System.out.println(加密后的字符串通过公钥解密后 DecryptByRSAPubKey(s, pubKey));//有个疑问是私钥和公钥都可以用来加密 吗私钥和公钥是什么关系//TODO}} main方法 public static void main(String[] args) throws Exception {//获取公钥String pubKey getPublicKey();//获取私钥String priKey getPrivateKey();//需要加密的参数String content age18nameyushanma;//字符串加密String s EncryptByRSAPubKey(content, pubKey);System.out.println(s参数通过公钥加密后 s);System.out.println(加密后的字符串通过私钥解密后 DecryptByRSAPriKey(s, priKey));content age18nameyushanma;s EncryptByRSAPriKey(content, priKey);System.out.println(s参数通过私钥加密后 s);System.out.println(加密后的字符串通过公钥解密后 DecryptByRSAPubKey(s, pubKey));//有个疑问是私钥和公钥都可以用来加密 吗私钥和公钥是什么关系//TODO} 测试结果 s参数通过公钥加密后RT9yWv4CL3LtG2RYKxV35KWkFNHA/tCFQEpEn0AjFJYelscLYupJL1Fssblp0OC/HGUqd0bx5Ji3OdZln5wI8HDMChfAxj5k4pb9NfAlXPvCKYZynFL4n/gnxLijJCWTTC0jXazYrn8qxMmPUvh8uqwIhTGnm5F1nNlLFoxOzaGyWz3wkjy36RVFr609g1mHWRu1PoqLSWb6qyiWhL0qr4tCNYsgx1OeJVptSJ67OW747oVkoAzs22LKlSv1gMtGvSqYLh2rxdkvdN36PeSmQgsuW3dRKdpQEsyfR7jmmZnQ99Zjog5Hc6CKQjlYFQjgZjnGpOM2kTGDw 加密后的字符串通过私钥解密后age18nameyushanma s参数通过私钥加密后YOW/GiySigBsY4RyM/Q25Qyg3ypohvelONxHuSd8NbRoRu9mBxVOgCq4MXEKOqf92mBcuAEdIxq4J8ARwZz0ba7846bQnpuRiLxpndZXs/ViZVH/gC93s5GpkmOhsx1nM4kNMap39FNASSn04Gxs8MJkYZLibZ4HKCaq1IZrolIawzW1Stm2nKnB3CHpyYvMxKCDn7WdOtJaAdDf9MLOjvbZDM3GmIkQAoNctWrExjLoIsF689lAQuDRoIPLNNsYMtD4Zrx4KqPFAWnLsAMI17Mc6igQxNejiGNOw4S2WjZew44MoEKxutQCR5mFUVAXs94fsFH7AVwtJhuHW3A 加密后的字符串通过公钥解密后age18nameyushanma 封装签名工具类 ApiUtil package com.atguigu.signcenter.util;import com.alibaba.fastjson.JSONObject; import com.mysql.cj.util.StringUtils; import com.rabbitmq.tools.json.JSONUtil; import jodd.util.StringUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils;import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.DigestException; import java.util.*;/*** 封装签名工具类* https://blog.csdn.net/weixin_47560078/article/details/118222785* author: jd* create: 2024-07-31*/ Slf4j public class ApiUtil {/*** 根据传的参数Map对参数进行排序并拼接成A1b2....* param data* return*/private static String getSortedContent(MapString, String data){StringBuffer content new StringBuffer();ListString keys new ArrayList(data.keySet());Collections.sort(keys);int index 0;for (String key : keys) {String value data.get(key);content.append((index 0 ? : )).append(key).append().append(value);index;}return content.toString();}/*** 参数加密,吸纳使用MD5加密然后使用自定义的私钥加密方法进行加密最终进行URL编码并返回。* param data* return* throws Exception*/public static String getSignature(MapString, String data) throws Exception {// 第一次加密使用MD5加密 对排序好的字符串进行加密然后转小写String summary DigestUtils.md5Hex(getSortedContent(data));log.info(md5加密后的参数 summary: summary);//第二次加密使用自定义的加密方法加密[自定义的加密方法通过私钥加密]String encryptByRSAPriSummary SecurityUtil.EncryptByRSAPriKey(summary, SecurityUtil.getPrivateKey());//对加密后的字符串进行Url编码,并返回return URLEncoder.encode(encryptByRSAPriSummary,utf-8);}/*** 验证签名* param params 所有参数* param sign 数字签名* param signType 加密类型* return* throws Exception*/public static boolean verifySign(MapString, String params, String sign, String signType) throws Exception {//如果签名直接为空则返回验证失败if(StringUtil.isEmpty(URLDecoder.decode(sign, utf-8))){return false;}//暂不支持非RSA的签名if(StringUtil.isEmpty(signType)!RSA.equals(signType)){log.info(暂不支持其他加密方法的签名验证);return false;}//走过参数校验之后开始正式的签名校验//参与签名的数据String data getSortedContent(params);log.info(原始data: data);String summary DigestUtils.md5Hex(data).toLowerCase();log.info(data进行md5Hex加密后 summary: summary);String summaryDecode null;try {//对签名通过公钥解密因为加密的时候先加密后编码所以这里需要先解码后解密又因为使用自定义加密方法之前是先经过了MD5加密所以对比的时候也要对原始串进行下MD5//紧接着上一行然后再和解密的字符串去对比。summaryDecode SecurityUtil.DecryptByRSAPubKey(URLDecoder.decode(sign,utf-8),SecurityUtil.getPublicKey());} catch (Exception e) {throw new RuntimeException(do_digest_error, e);}return summary.equals(summaryDecode);}public static void main(String[] args) throws Exception {MapString,String data new HashMap();data.put(name,zhaijh);data.put(age,20);log.info(原始参数{},data);String signature getSignature(data);log.info(参数签名{},signature);String signType RSA;log.info(验证结果{},verifySign(data,signature,signType));}} 测试结果 09:01:07.417 [main] INFO com.atguigu.signcenter.util.ApiUtil - 原始参数{namezhaijh, age20} 09:01:07.432 [main] INFO com.atguigu.signcenter.util.ApiUtil - md5加密后的参数 summary:bea0310dc7f03ad5d036d906dbe513f4 09:01:08.642 [main] INFO com.atguigu.signcenter.util.ApiUtil - 参数签名j0CTBZ0NpiZFycua7otGYXr7KHNgXsBc0DBojHzyKbTKtSrutZv%2FblSFqFi5lCM6stSkxWd8OQQRcgPwPopsy1HYZ6cU%2Fi%2Bpwc0JAH2DH49jmTGgJVatCGFZ0NtcNK972XIncpSOaeWNx6fvBffi71jbxg7BdWM89anLL%2BQJ1GeF5i3OL4wBzFoyC7FdiGdxG9qShSdORBcy2LMyCa3sHJDTayoPmOhNLAqgvrAWeTfF%2BkUZAPqysHVGX8KpmfcNY0vf1y%2BSmWXYJ5x%2Faw1GVCIy39vcXppqy1ofqZQTo0d6drk62J1cjmDzl0Pj7c4J0h13mCw4yl4dn3KRkJ3jhg%3D%3D 09:01:08.644 [main] INFO com.atguigu.signcenter.util.ApiUtil - 原始data:age20namezhaijh 09:01:08.644 [main] INFO com.atguigu.signcenter.util.ApiUtil - data进行md5Hex加密后 summary:bea0310dc7f03ad5d036d906dbe513f4 09:01:08.645 [main] INFO com.atguigu.signcenter.util.ApiUtil - 验证结果true 控制器签名接口与校验接口 SignController package com.atguigu.signcenter.controller;import com.atguigu.signcenter.util.ApiUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map;/*** 控制器签名接口与校验接口* author: jd* create: 2024-08-01*/ Slf4j RestController public class SignController {/*** 模拟前端请求时发送的 参数签名* param data 实际的业务入参数据* return*/GetMapping(/sign/getSign)public MapString,Object getSign(RequestParam MapString, String data) throws Exception {log.info(入参{},data);//返回信息map结构HashMapString, Object result new HashMap();result.put(code,0); //状态码result.put(msg,success); //返回信息String signature ApiUtil.getSignature(data);//获得入参参 通过私钥的签名内容result.put(data,signature);result.put(verify,ApiUtil.verifySign(data,signature,RSA));return result;}/*** 模拟后端进行请求中“参数签名”的验证* param request Http请求* param data 实际的业务入参数据* return* throws Exception*/GetMapping(/sign/verifySign)public boolean verifySign(HttpServletRequest request,RequestParam MapString, String data) throws Exception {String sign request.getHeader(sign);String sign_type request.getHeader(sign_type);boolean result ApiUtil.verifySign(data, sign, sign_type);log.info(参数签名验证结果{},result);return result;}} yml相关配置 server:port: 8025spring:application:name: sign-centerdatasource:url: jdbc:mysql://192.168.56.10:3306/gulimall_umsusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivercloud:nacos:discovery:server-addr: 127.0.0.1:8848#配置日志输出级别 logging:level:com.atguigu.gulimall: debug #level 日志等级 指定命名空间的日志输出模拟前端产生签名测试 参数name zhaijh age 21 模拟后端签名校验测试 请求头 请求参数 这里我将sign放到header中是因为签名signature中有些字符是特殊字符放到parameter中可能会导致有些字符被过滤最终在校验签名时抛出签名长度不够的错误这个问题可以通过url编码解决 当传的参数是一样的话验证通过 返回true 【参数name zhaijh age 21】 当参数被修改时签名验证就会返回false 【参数name zhaijh age 22】 参考链接https://blog.csdn.net/weixin_47560078/article/details/118222785
http://www.hkea.cn/news/14349100/

相关文章:

  • 网站建设氺金手指排名12企业网站建设组织人员可行性分析
  • 网站免费永久做网站用新域名还是老域名
  • 华夏网站建设平面设计属于哪个专业大类
  • 检察机关门户网站建设自查报告唐山网站建设制作
  • 餐馆建设网站的目的是什么网站建设申请费用
  • 建设银行车主卡网上交罚款网站接订单去哪个网站
  • 免费的源代码分享有哪些网站如何设计并制作各级网页
  • 注册公司名称查询网站销售外包公司
  • 制造网站建设哪家好泉州专业网站营销
  • 网站建设是管理费用的哪项费用乐天seo培训中心
  • 新兴街做网站公司网站建设德尔普
  • 西安网站建设哪里好wordpress插件doc
  • 自己的网站如何做推广做网站诱导网站
  • 男女直接做的视频网站好多钱网站
  • 深圳建网站好的公司网站设计错误
  • 仿站网站源码下载游戏直播网站怎么做
  • 房产网站管理系统wordpress搬到谷歌服务器
  • 建站公司最喜欢的网站100个好听到爆的公司名字
  • 遵义专业建站常州专业做网站
  • 怎么做app网站ui原型澄海网站建设公司
  • 关于电子商务网站建设的论文浙里建官网登录
  • 营销型网站设计特点昆明 网站建设兼职
  • 网站运营推广策划书深度优化
  • 网站建设销售岗位职责广州市研发网站建设平台
  • 如何选择电商网站建设淘宝流量平台
  • 兰州做网站改版的公司dede网站地图xml
  • 基于cms的企业网站建设ps软件下载电脑版免费
  • wordpress id 缩略图wordpress seo 模板
  • 列出网站目录ug wordpress
  • html网页模板网站wordpress主题安装不了