AuthUtils.java 7 KB
package com.idss.vulsync.utils;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.LinkedHashMap;

/**
 * @Author: zc
 * @Date: 2024/8/13 14:34
 */
@Component
@Slf4j
public class AuthUtils {
    @Value("${auth.publickey:11}")
    private String publickey;

    @Autowired
    ObjectMapper objectMapper;

    public boolean valid(HttpServletRequest req) {
//         提取Authorization头
        String authHeader = req.getHeader("Authorization");
        try {
            if (authHeader == null || !authHeader.startsWith("Basic ")) {
                return false;
            }

            // 提取base64编码的pubKeyInfo
            String base64PubKeyInfo = authHeader.substring("Basic ".length());
            // 解码base64
            byte[] decodedBytes = Base64.getDecoder().decode(base64PubKeyInfo);
            String pubKeyInfo = new String(decodedBytes, "UTF-8");
            pubKeyInfo = pubKeyInfo.replace("\\", "");


            // 分解pubKeyInfo字符串

            JsonNode jsonObject = objectMapper.readTree(pubKeyInfo);

            int hashAlgo = jsonObject.get("hashAlgo").asInt();
            String pubKeyHash = jsonObject.get("pubKeyHash").asText();
            byte[] pubKeySign = Base64.getDecoder().decode(jsonObject.get("pubKeySign").asText());

            // 获取公钥(此处需要替换为实际公钥获取方式)
            PublicKey publicKey = getPublicKey();

            // 根据hashAlgo选择摘要算法
            MessageDigest digest;
            Signature verifier;
            switch (hashAlgo) {
                case 1:
                    digest = MessageDigest.getInstance("MD5");
                    verifier = Signature.getInstance("MD5withRSA");
                    break;
                case 2:
                    digest = MessageDigest.getInstance("SHA-1");
                    verifier = Signature.getInstance("SHA1withRSA");
                    break;
                case 3:
                    digest = MessageDigest.getInstance("SHA-256");
                    verifier = Signature.getInstance("SHA256withRSA");
                    break;
                case 4:
                    digest = MessageDigest.getInstance("SHA-512");
                    verifier = Signature.getInstance("SHA512withRSA");
                    break;
                default:
                    throw new IllegalArgumentException("Unsupported hash algorithm");
            }

            // 验证签名

            verifier.initVerify(publicKey);
            verifier.update(pubKeyHash.getBytes());
            boolean isSignatureValid = verifier.verify(pubKeySign);

            if (isSignatureValid) {
                // 验证成功
                return true;
            } else {
                // 验证失败
                return false;
            }
        } catch (Exception e) {
            log.error("解析Authorization异常", e);
            return false;
        }
    }


    public PublicKey getPublicKey() {
        try {
            // Base64解码
            byte[] encoded = Base64.getDecoder().decode(publickey);
            // 生成公钥对象
            X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePublic(spec);
        } catch (Exception e) {
            log.error("加载公钥异常{}", publickey, e);
        }
        return null;
    }


    public static String generateSHA1Sign(String jsonString) {
        try {
            log.info("参与签名的字符串:{}", jsonString);
            // Compute the SHA-1 hash of the JSON string
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            byte[] hashBytes = digest.digest(jsonString.getBytes(StandardCharsets.UTF_8));

            // Convert the hash bytes to a hexadecimal string
            String hashHex = new BigInteger(1, hashBytes).toString(16);

            // Pad the hexadecimal string to ensure it is 40 characters long
            while (hashHex.length() < 40) {
                hashHex = "0" + hashHex;
            }

            // Print the result
            log.info("SHA-1 hash: " + hashHex);
            return hashHex;
        } catch (Exception e) {
            log.error("生成签名异常{}", jsonString, e);
        }
        return null;
    }


    public static void main(String[] args) throws JsonProcessingException {
        String a="{\\\"hashAlgo\\\": 3, \\\"pubKeyHash\\\": \\\"a1771141fc41757dd3e2876730c2e4960323f3250f91a64d3ddc30c5535a0e8d\\\", \\\"pubKeySign\\\": \\\"u5JJmfldHBpeW5a6aIvw2BSjl5NxLiZMJ0VF/WZSYNimgiSPX8KfucAm3JcVek6P/ox2BVooJlX2D7m+jdLZHO6iJVmME1aa66hLdsKwYT4fZIpXhI3HrWbe5GJkmo9x2Y/qeerG3IXwIrmAJXBmImz33tQO81gB8F7hsiDeok3AS8VNFP9e+/BvxXBYfTfGrGj06c7xTXMIN8ZHHw46nX0C2zpFuZuNumiqE1sUXv4QNSbaslED8wyqiR/KjRYpYFgk58g417BJUhSdAhREbd0+qJ+ug8o+wanQ+bCVyCiDcjzaw23tXzMs5Fa1sk6TOBapUJy5MJGWfIsvzS3IyA==\\\"}";
        System.out.println(Base64.getEncoder().encodeToString(a.getBytes()));

        //9585914816779ed6001e5e7fe1fa75aa92f20c26
        //
        //
        String json = "{\"msgID\":\"Q5UB0DR7IQRXQS1952LWXTULP5LTEW8IN0XPXKKENG4MRMDEMMXWNN78OX25SDJGUCH50FPDNM1KS40JZFG9PXXOZOH973QQIIUP2N5A3N619QR7W903J5SSE3HWI8VNT425WDSODPNSEVQ65YYJFCI6700ZATDK50QH4DQ41P7SSKPMJ9XQ3OGHZ9RDPJK6DJ5J12PVK4VDZQQSMRDDBCAMVRQKW2MFTGNWVXHXKVVRF9PBYABP1ZSJVXQ7BHV\",\"msgType\":1,\"IspCode\":\"CUCC\",\"OrgCode\":\"110000\",\"ReqMsgCnt\":{\"TransID\":\"GX8G5ZJG0HZV5EJ28CP2\",\"filePath\":\"/sftpbsau1/tvm_asset_sync\",\"user\":\"sftpbsau1\",\"port\":5048,\"creditType\":1,\"initDelay\":\"1分\",\"updCycle\":\"1时\",\"credit\":\"QWEuMTJJSDdQU0g3\"}}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, false);
        LinkedHashMap<String, Object> bigMap = objectMapper.readValue(json, TypeFactory.defaultInstance().constructMapType(LinkedHashMap.class, String.class, Object.class));


        bigMap.remove("timestamp");
        bigMap.remove("sign");


        String validSign = generateSHA1Sign(JSON.toJSONString(bigMap));


        if (!"2f9240fed4707d960c560f9451d3c0ad10ceb771".equals(validSign)) {
            System.out.println("不通过");
        } else {
            System.out.println("通过");
        }
    }
}