微信支付:小微商户申请入驻第三步:平台证书序列号解密和敏感词加密

首先,还是上微信官方链接

微信官方平台证书解密指引

微信官方敏感词加密指引

平台证书解密

定义接口

首先,由于平台证书获取,跟解密,都是平台证书这货的,那就放在同一个service吧。 对了,pom文件之前文章有,就不粘贴了,也可以去github查看

/**
 * 平台序证书获取
 */
public interface CertFicatesService {
    String getCertFicates();

    /**
     * 平台证书解密
     * @param associatedData
     * @param nonce
     * @param cipherText
     * @param apiv3Key
     * @return
     */
    String decryptCertSN(String associatedData, String nonce, String cipherText, String apiv3Key)throws Exception;
}


复制代码

参数确认

四个参数: associatedData, nonce, cipherText, apiv3Key。

回顾一下获取平台证书序列号返回的结果,因为我们需要对其解密

<certificates><![CDATA[{"data":[{"serial_no":"42A5C4F7F70D57D0576BBEDA0E0928D6E5C4
F003","effective_time":"2017-08-18 14:52:04","expire_time":"2022-08-17
14:52:04","encrypt_certificate":{"algorithm":"AEAD_AES_256_GCM","nonce":"bfcb2bd59
c97","associated_data":"certificate","ciphertext":"vQ4N+lLNvtIhaV5Gqao44mbYBSaz3bZ
4Md3M4f+OuquEJrp+/v4gA//UZqnQ1G0roYqnSMfcsRFj7ItTCP0tbYregpYqBKd4NSLiF/m1o01JD/9nz
d3pBwBUJenUzvE1cuMO+fookaBYr+Z5AfesXUUmvl5qAbD3Yj+5GuMIkTCQcn4W6rls/W2YDo3o3T9sWtl
5A/5w+U/Wsb9/UefNow6ND+2MAWRm1GK5tRTkBGVKMt699SM4p0pUns3D4g3slz6zeYIFY3+x+NzrxNq+O
v7I4e/wkp1s3QJd3vctDC4j5btvpCvdEIrBmzzTKzmJ+qhHIRVpXqiMTtOWSpCcTCptUt4v/ZrIlMihESd
ruDv7Zj4984+4tzBqmQ/Mt1Bwbs8RyKYe2UufmXSMyOeCW06TtkXduZ7M2QSKE4kTlRerEGPatymglepMn
jpSMX/CnwaSaHcIBWN2oNjAcuBdMGFlbv05owBlkEZm4sRgZR9EMDIX/N469TUsJ3yXVLuN2k6XaAEM5wp
X/Hc15R1o1rhpnLjGZpZoKOVpmcyqw5/0uBQgAAaTXOGgr6L2mrSsp9Au4J0hIX/SjfrjaovXEZTvSM+1o
GlJmRVLZ+jxjTD/al7X2xsjTleYYggp4EN4aaC4DTwUNcAAzhHF9R7e+bIfyopa2FF+exXC9kZUYLywg9b
wKOJwhkykz7NM669gXLjlyEu6W9gIa8sa3HKSfeLfcpTan7Ev9BjRbowQYmn7RZEyvizKJHJU3ge04OIme
JFY4fT8JahzaOT8BQnvP4g2ZT65r4jQwXEbFqOJNH5SdRlTL+3oCqkgMx+1wccaj9ZKqxY9EFDwZgjLZWo
ySJvIbDQfEayo1pRzlcF9MbuFyGH0vblRLSx3viCc/q6oUkx2OjRw1Hp3sdtFGZMS2OE1+xICymLPglHuM
zGkGYwl7ZxbotiXKkqAN46Zd7hNcTwHhxMjQXcoaUoGNEKK1fRZrBv0eUjhES8GbZvzS7+Xm1SR8dKTNMQ
yEvFesUY143nFt1GK+/bJR+0l2dz0zgpJGAS4yKBkWdsTng0a/jzRbMryRy+fAjWGfvHlVcXXD5b51kx1P
3pxcQdMe3K0al+40gLilbegFUVPXhZ04BVgxiWHfeRPnDVwVXFzHG7MAjmPWS0PFzJupZExuy+jxIf5oyH
LcYjnl2jwNNcWdzm5AFWYqy5oQI88lcOBx1X+fGuZTKAopk8/2zCa7uu9ILSyVBf801wagINDhxSNemoDo
RPE0lvIYE/ax7RQehQ2Q3F2JNmpP6EfP1KZsT6nSWLBf1M5tvX/pAsPbYowNCgrwXLa68L5e03ScplSZrJ
WP7H3UcGxq9fRLgOYnF7ocRr0iviSRGVmSDqdtpIWwhb+UoAw4347hTQsEHRhYQdR6fTryiANB+H+6SnRJ
any/cozFV11J03w6h9Lmx95OJGYwF8Cei8S3pNkHpq90o7eUq2PmfS/wwxL3ZyJFPS8OY05zR4ykRnwir4
L2X1RyCVoV34AAzVsvr93fVNPHtY3yf+i6sDWb4yGaXaYMM/cOnNs7wrxME44in+YZtPduI+8MZ5EGTbaq
jJzrGnrbDnb515OOXg6gk+eV+bJkMXxxoNQGOkLCCI5pN+wrrokXRYhFZbYSkLd/rkg+T3JS23nO1TYOej
ewvatmQ97i9OFxNrwxOzDL9E87jLj26Wm+VSbm/SNafEh0eU0owwyVskg7evUe7XxcBErXC8M87MuK6AJo
/IhhivYlEb/d+wG2r0gV7VesAjYC2n3ZAI1oz78WMMTmj6IqXgDc20uNmGYX0IEB+cxpJwejEfV72ArStq
zumUzw3YhvD4L7Ozq0b6Y2gao88MONn9nevnydq5IvsG0bsGutXCFwjhYGxLyqigGIkVkXeq+BbxFpNxbo
gkB43cM"}}]}]]></certificates> 
复制代码

里面找到了associated_data,nonce,ciphertext 。 都找到了

呃。。。。apiv3Key这玩意找不到,那没办法了,就这样吧

apiv3Key

我直接上微信官方图

你会发现,页面很熟悉,这不就是大明湖畔的那个谁谁谁吗?

快去重置获取吧,哈哈,反正我是忘了放哪了。

划重点~这边就有短短的密钥,要保存好。

4个参数完成

编写实现类

    @Override
    public String decryptCertSN(String associatedData, String nonce, String cipherText, String apiv3Key) throws Exception{
        final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(apiv3Key.getBytes(), "AES");
        GCMParameterSpec spec = new GCMParameterSpec(128, nonce.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, key, spec);
        cipher.updateAAD(associatedData.getBytes());
        return new String(cipher.doFinal(Base64.getDecoder().decode(cipherText)));
    }
复制代码

编写测试类,开始测试

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class CertFicatesServiceImplTest {
    @Autowired
    private CertFicatesService certFicatesService;

    @Test
    public void decryptCertSNTest() {
        try {
            String decertContent = certFicatesService.decryptCertSN("associatedData", "nonce", "cipherText", "apiv3Key");
            log.info("content = {}",decertContent);
        } catch (Exception e) {
            log.error("解密异常啦 {}", e);
        }
    }

}
复制代码

开始敏感词加密工具类

丢代码

import javax.crypto.Cipher;
import javax.security.cert.X509Certificate;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.PublicKey;
import java.util.Base64;

public class EncryptionUtils {
    private static final String CIPHER_PROVIDER = "SunJCE";
    private static final String TRANSFORMATION_PKCS1Paddiing = "RSA/ECB/PKCS1Padding";

    private static final String CHAR_ENCODING = "UTF-8";//固定值,无须修改


    //数据加密方法
    private static byte[] encryptPkcs1padding(PublicKey publicKey, byte[] data) throws Exception {
        Cipher ci = Cipher.getInstance(TRANSFORMATION_PKCS1Paddiing, CIPHER_PROVIDER);
        ci.init(Cipher.ENCRYPT_MODE, publicKey);
        return ci.doFinal(data);
    }
    //加密后的秘文,使用base64编码方法
    private static String encodeBase64(byte[] bytes) throws Exception {
        return Base64.getEncoder().encodeToString(bytes);
    }
    /**
     *  对敏感内容(入参Content)加密
     *  path 为平台序列号接口解密后的密钥 pem 路径
     */
    public static String rsaEncrypt(String Content, String path) throws Exception {
        final byte[] PublicKeyBytes = Files.readAllBytes(Paths.get(path));
        X509Certificate certificate = X509Certificate.getInstance(PublicKeyBytes);
        PublicKey publicKey = certificate.getPublicKey();

        return encodeBase64(encryptPkcs1padding(publicKey, Content.getBytes(CHAR_ENCODING)));
    }

    /**
     * 为了自己方便,多加个个传内容的,因为我解密后并没有保存到文件里,而是自己重新解密
     * 要问为什么?
     * 需求有多个服务商号,没办法
     * @param Content
     * @param certStr
     * @return
     * @throws Exception
     */
    public static String rsaEncryptByCert(String Content, String certStr) throws Exception {
        X509Certificate certificate = X509Certificate.getInstance(certStr.getBytes());
        PublicKey publicKey = certificate.getPublicKey();
        return encodeBase64(encryptPkcs1padding(publicKey, Content.getBytes(CHAR_ENCODING)));
    }

}
复制代码

你要问为什么?? 官方给的

编写测试类

    @Test
    public void decryptCertSNTest() {
        try {
            String content = certFicatesService.decryptCertSN("associatedData", "nonce", "cipherText", "apiv3Key");
            String encrypt = EncryptionUtils.rsaEncryptByCert("我的身份证", content);
            log.info("身份证的密文了 {}",encrypt);
        } catch (Exception e) {
            log.error("解密异常啦 {}", e);
        }
    }
复制代码

源代码

github.com/bertonlee/m… 分支为decryptCertSN

如果帮助到您,欢迎star

个人博客地址

https://www.ccode.live/bertonlee/list/27?from=art

欢迎关注公众号“码上开发”,每天分享最新技术资讯

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值