V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
topeak
V2EX  ›  程序员

数电发票乐企接口示例代码

  •  
  •   topeak · 136 天前 · 982 次点击
    这是一个创建于 136 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有最新的吗?

    网上找到的这个还是 lq.chinatax.gov.cn 旧的 最新的应该是 lqpt.chinatax.gov.cn 很久不写代码,都废了

    import static channel.Channel.*;

    public class JDKPMain {

    static String key = "乐企";//乐企秘钥
    static String jrdybm = "";//接入单位 id
    static String sydwbm = "";//使用单位 id
    static String ylbm ="" ;//用例编码
    
    
    static String nsrsbh = "";//纳税人识别号
    
    public static void main(String[] args) {
        CXNSRJBXX();
    }
    
    
    /**
     * 查询纳税人基本信息
     */
    private static void CXNSRJBXX() {
        String url = "https://lqpt.chinatax.gov.cn:84/access/v2/invoke/202007/CXNSRJBXX";
        //正式沙箱环境,https://lqpt.chinatax.gov.cn:8443/access/sandbox/v2/invoke/202007/CXNSRJBXX
        String param = "{\"nsrsbh\":\""+nsrsbh+"\"}";
        request(url, param, key, jrdybm, sydwbm, ylbm);
    }
    

    }

    package channel;

    import com.alibaba.fastjson.JSON; import org.apache.http.HttpEntity; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils;

    import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.Map;

    public class Channel {

    public static String request(String url, String param, String key, String jrdybm, String sydwbm) {
        return request(url,param,key,jrdybm,sydwbm,null);
    }
    
    
    public static String request(String url, String param, String key, String jrdybm, String sydwbm, String ylbm) {
        param = param.replace("\n","");
        param = param.replace("{  ","{");
        param = param.replace(",  ",",");
        param = param.replace(",  ",",");
        param = param.replace("[  ","[");
        param = param.replace("{  ","{");
    

    // System.out.println("\n 请求乐企服务地址:" + url); System.out.println("\n"); System.out.println("请求乐企原始报文:" + param); String encParam = SM4Util.encryptEcb(key, param); System.out.println("请求乐企加密报文:" + encParam); String result = postLeqi(url, encParam, jrdybm, sydwbm, ylbm); System.out.println("响应乐企原始报文:" + result); Map<String, Object> resultDTO = JSON.parseObject(result, Map.class); Map<String, Object> body = JSON.parseObject((String) resultDTO.get("body"), Map.class); Map<String, Object> response = (Map<String, Object>) body.get("Response"); String data = (String) response.get("Data"); String resultMsg = SM4Util.decryptEcb(key, data); System.out.println("响应乐企解密报文:" + resultMsg); return resultMsg; }

    public static String postLeqi(String url, String reqDTO, String jrdybm,
                                  String sydwbm, String ylbm) {
    
        try {
            SSLContext ctx = null;
            try {
                ctx = SSLContext.getInstance("SSL");
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }
            X509TrustManager tm = new X509TrustManager() {
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
    
                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] arg0,
                                               String arg1) {
                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
            HttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(ssf).disableCookieManagement().build();
            HttpPost httpPost = new HttpPost(url);
            httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
            httpPost.addHeader("Accept", "application/json");
            httpPost.addHeader("jrdwptbh", jrdybm);
            httpPost.addHeader("sydwptbh", sydwbm);
            if (ylbm != null) {
                httpPost.addHeader("ylbm", ylbm);
            }
            StringEntity stringEntity = new StringEntity(reqDTO, StandardCharsets.UTF_8);
            httpPost.setEntity(stringEntity);
            CloseableHttpResponse response = (CloseableHttpResponse) httpClient.execute( httpPost);
            HttpEntity responseEntity = response.getEntity();
            return EntityUtils.toString(responseEntity);
        } catch (KeyManagementException | IOException e) {
            throw new RuntimeException(e);
        }
    }
    

    }

    package channel;

    import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.util.encoders.Hex;

    import javax.crypto.; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.security.; import java.util.Base64;

    public class SM4Util {

    private SM4Util() {
    }
    
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    
    private static final Charset ENCODING = StandardCharsets.UTF_8;
    public static final String ALGORITHM_NAME = "SM4";
    // 加密算法/分组加密模式/分组填充方式
    // PKCS5Padding-以 8 个字节为一组进行分组加密
    // 定义分组加密模式使用:PKCS5Padding
    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";
    // 128-32 位 16 进制; 256-64 位 16 进制
    public static final int DEFAULT_KEY_SIZE = 128;
    
    /**
     * 自动生成密钥( 16 进制字符串,长度 32 )
     */
    public static String generateKey() {
        return Hex.toHexString(generateKey(DEFAULT_KEY_SIZE));
    }
    
    /**
     * @param keySize 密钥长度
     */
    public static byte[] generateKey(int keySize) {
        try {
            KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
            kg.init(keySize, new SecureRandom());
            return kg.generateKey().getEncoded();
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 生成 ECB 暗号
     *
     * @param algorithmName 算法名称
     * @param mode          模式
     * @param key           密码
     */
    private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) {
        try {
            Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
            Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
            cipher.init(mode, sm4Key);
            return cipher;
        } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | NoSuchProviderException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * sm4 加密 ,加密模式:ECB
     *
     * @param hexKey   16 进制密钥(忽略大小写)
     * @param paramStr 待加密字符串
     * @return 返回 Base64 后加密字符串
     */
    public static String encryptEcb(String hexKey, String paramStr) {
        try {
            // 16 进制字符串-->byte[]
            @SuppressWarnings("deprecation")
            byte[] keyData = ByteUtils.fromHexString(hexKey);
            // String-->byte[]
            byte[] srcData = paramStr.getBytes(ENCODING);
            // 加密后的数组
            byte[] cipherArray = encryptEcbPadding(keyData, srcData);
            // byte[]-->hexString
            return Base64.getEncoder().encodeToString(cipherArray);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 加密模式为 ECB
     *
     * @param key  2 进制密钥
     * @param data 2 进制原文
     * @return 二进制密文
     */
    public static byte[] encryptEcbPadding(byte[] key, byte[] data) {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
        try {
            return cipher.doFinal(data);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * sm4 解密 ,解密模式:采用 ECB
     *
     * @param hexKey     16 进制密钥
     * @param cipherText 16 进制的加密字符串(忽略大小写)
     * @return 解密后的字符串
     */
    public static String decryptEcb(String hexKey, String cipherText) {
        try {
            // hexString-->byte[]
            @SuppressWarnings("deprecation")
            byte[] keyData = ByteUtils.fromHexString(hexKey);
            // hexString-->byte[]
            byte[] cipherData = Base64.getDecoder().decode(cipherText);
            // 解密
            byte[] srcData = decryptEcbPadding(keyData, cipherData);
            // 接收解密后的字符串 byte[]-->String
            return new String(srcData, ENCODING);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    /**
     * sm4 解密
     *
     * @param key        2 进制密钥
     * @param cipherText 2 进制密文
     * @return 解密后的 2 进制原文
     */
    public static byte[] decryptEcbPadding(byte[] key, byte[] cipherText) {
        Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
        try {
            return cipher.doFinal(cipherText);
        } catch (IllegalBlockSizeException | BadPaddingException e) {
            throw new RuntimeException(e);
        }
    }
    

    }

    //

    2 条回复    2024-07-12 09:46:41 +08:00
    kkk9
        1
    kkk9  
       136 天前
    企业向税务总局申请对接,总局会下发相关文档到登记的负责人邮箱,你应该找公司负责人要
    Desdemor
        2
    Desdemor  
       136 天前
    可以看看诺诺,税务这种对接一般都会给详细的文档,你从网上找的不行的吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5805 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 06:34 · PVG 14:34 · LAX 22:34 · JFK 01:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.