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

135 天前
 topeak

有最新的吗?

网上找到的这个还是 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);
    }
}

}

//

977 次点击
所在节点    程序员
2 条回复
kkk9
135 天前
企业向税务总局申请对接,总局会下发相关文档到登记的负责人邮箱,你应该找公司负责人要
Desdemor
134 天前
可以看看诺诺,税务这种对接一般都会给详细的文档,你从网上找的不行的吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1056646

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX