channelLink

阿凡达平台对接外部渠道,如果渠道方需要使用专用接口,即对接使用渠道方的接口文档。如果渠道方没有定制接口需求,则按照阿凡达平台接口文档规范进行交互


接口规则

<p>[TOC]</p> <h1>文档目的</h1> <p>鸿雁平台对接外部渠道,如果渠道方需要使用专用接口,即对接使用渠道方的接口文档。如果渠道方没有定制接口需求,则按照该接口文档规范进行交互</p> <h1>文档说明</h1> <p>文档中必传字段展示,Y标识必传,CY标识条件必传,N标识不必传</p> <h1>接口信息</h1> <p>1.  统一使用post请求,json格式,加密传输,秘钥另外提供</p> <p>2.  签名算法可能并不止包括,“RSA”,“MD5”,“AES”</p> <table> <thead> <tr> <th>传输方式</th> <th>为保证交易安全性,采用HTTPS传输</th> </tr> </thead> <tbody> <tr> <td>提交方式</td> <td>采用POST方法提交</td> </tr> <tr> <td>数据格式</td> <td>提交和返回数据都为text/plain格式</td> </tr> <tr> <td>参数</td> <td>String(加密后的密文)</td> </tr> <tr> <td>字符编码</td> <td>统一采用UTF-8字符编码</td> </tr> <tr> <td>签名算法</td> <td>MD5、AES算法</td> </tr> </tbody> </table> <h1>参数规定</h1> <table> <thead> <tr> <th style="text-align: left;">字符</th> <th style="text-align: left;">一般数据类型,一般使用String接收</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">金额</td> <td style="text-align: left;">BigDecimal类型</td> </tr> <tr> <td style="text-align: left;">数值</td> <td style="text-align: left;">Integer类型</td> </tr> <tr> <td style="text-align: left;">日期/日期时间</td> <td style="text-align: left;">date/dateTime类型</td> </tr> <tr> <td style="text-align: left;">字符</td> <td style="text-align: left;">一般数据类型,一般使用String接收</td> </tr> <tr> <td style="text-align: left;">是否为必录</td> <td style="text-align: left;">Y-必录;CY-条件必录;N或空白:非必录</td> </tr> </tbody> </table> <h1>headers中的信息</h1> <table> <thead> <tr> <th style="text-align: left;">字段名称</th> <th style="text-align: left;">字段代码</th> <th style="text-align: left;">字段类型</th> <th style="text-align: left;">是否必传</th> <th style="text-align: left;">字段描述</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">渠道编码</td> <td style="text-align: left;">policySource</td> <td style="text-align: left;">varchar</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">保司提供</td> </tr> <tr> <td style="text-align: left;">签名</td> <td style="text-align: left;">sign</td> <td style="text-align: left;">varchar</td> <td style="text-align: left;">Y</td> <td style="text-align: left;"><a href="#签名说明">签名说明</a></td> </tr> <tr> <td style="text-align: left;">订单号</td> <td style="text-align: left;">orderNo</td> <td style="text-align: left;">varchar</td> <td style="text-align: left;">Y</td> <td style="text-align: left;"></td> </tr> <tr> <td style="text-align: left;">token</td> <td style="text-align: left;">token</td> <td style="text-align: left;">varchar</td> <td style="text-align: left;">CY</td> <td style="text-align: left;"></td> <td></td> </tr> </tbody> </table> <h1>环境地址</h1> <ul> <li>测试环境: <a href="https://hermesgyb.zhlic.net">https://hermesgyb.zhlic.net</a></li> <li>生产环境: <a href="https://gyb.zhlic.net">https://gyb.zhlic.net</a></li> </ul> <h1>interfaceType</h1> <ul> <li><strong>head中的interfaceType(&lt;b style=&#039;color:red&#039;&gt;可使用接口最后一个方法名&lt;/b&gt;)</strong></li> </ul> <table> <thead> <tr> <th style="text-align: left;">接口</th> <th style="text-align: left;">是否必传</th> <th style="text-align: left;">描述</th> <th style="text-align: left;">interfaceType</th> </tr> </thead> <tbody> <tr> <td style="text-align: left;">核保</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">核保逻辑</td> <td style="text-align: left;">proposalOrder</td> </tr> <tr> <td style="text-align: left;">承保</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">承保逻辑</td> <td style="text-align: left;">policyOrder</td> </tr> <tr> <td style="text-align: left;">获取缴费链接</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">获取承保缴费链接</td> <td style="text-align: left;">payUrl</td> </tr> <tr> <td style="text-align: left;">出单通知接口</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">出单通知接口</td> <td style="text-align: left;">paySucc</td> </tr> <tr> <td style="text-align: left;">退保试算</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">退保试算逻辑</td> <td style="text-align: left;">refundCal</td> </tr> <tr> <td style="text-align: left;">退保</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">退保逻辑</td> <td style="text-align: left;">refundOrder</td> </tr> <tr> <td style="text-align: left;">退保通知接口</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">退保通知接口</td> <td style="text-align: left;">refundNotice</td> </tr> <tr> <td style="text-align: left;">续费接口</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">获取缴费链接</td> <td style="text-align: left;">renew</td> </tr> <tr> <td style="text-align: left;">续费成功通知接口</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">渠道续费通知</td> <td style="text-align: left;">renewNotice</td> </tr> <tr> <td style="text-align: left;">token生成接口</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">token生成</td> <td style="text-align: left;">getToken</td> </tr> <tr> <td style="text-align: left;">影像信息上传接口</td> <td style="text-align: left;">Y</td> <td style="text-align: left;">影像信息上传</td> <td style="text-align: left;">uploadImage</td> </tr> </tbody> </table> <h1>报文说明</h1> <p>1.  整体报文使用AES对称加密传输,请求过来的需要是密文报文,秘钥另外提供</p> <ol> <li>渠道返回报文也需要进行AES加密,保司需要对返回报文进行AES解密。</li> </ol> <h1>签名说明</h1> <p>1.  整体报文使用AES对称加密传输,请求过来的需要是密文报文,秘钥另外提供</p> <p>2.  <a href="#headers中的信息">headers</a>中增加数据校验,及将加密后的整体报文,再将其使用MD5加密获取sign值,即sign=MD5(加密报文+key) 小写32位</p> <p>3.  测试环境aesKey、md5Key。生产环境上线前提供</p> <pre><code> key = &amp;quot;fuahdfujhauidhiuawse&amp;quot;; aesKey = &amp;quot;sadedfjekashciew&amp;quot;;</code></pre> <h2>如下图</h2> <p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=219b980b543c7c5c62718c2d2b0cca24&amp;amp;file=file.jpg" alt="请求说明" /></p> <h1>签名、加解密demo</h1> <p>[报文信息.zip](<a href="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=794bd3b9274821f312bcce52184ccee4">https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=794bd3b9274821f312bcce52184ccee4</a> &quot;[报文信息.zip&quot;)</p> <h1>签名</h1> <pre><code class="language-java">package com.huanong.avatar.common.utils; import org.springframework.util.Base64Utils; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5Utils { private static final String KEY_MD5 = &amp;quot;MD5&amp;quot;; public static String md5(String str, String encoding) { byte[] hash = null; try { hash = MessageDigest.getInstance(KEY_MD5).digest(str.getBytes(encoding)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } StringBuilder hex = new StringBuilder(hash.length * 2); for (byte b : hash) { if ((b &amp;amp; 0xFF) &amp;lt; 0x10) { hex.append(&amp;quot;0&amp;quot;); } hex.append(Integer.toHexString(b &amp;amp; 0xFF)); } return hex.toString(); } } </code></pre> <h1>报文加密、解密</h1> <pre><code class="language-java"> import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.huanong.avatar.common.utils.MD5Utils; import org.apache.commons.net.util.Base64; import org.springframework.util.Base64Utils; import sun.security.provider.Sun; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.Security; public class EncodeTest { private final static String key = &amp;quot;fuahdfujhauidhiuawse&amp;quot;; private final static String aesKey = &amp;quot;sadedfjekashciew&amp;quot;; private static final String SECURITY_PROVIDER = &amp;quot;SUN&amp;quot;; private final static String DData = &amp;quot;{\&amp;quot;avatarInsureBody\&amp;quot;:{\&amp;quot;holderInfo\&amp;quot;:{\&amp;quot;address\&amp;quot;:\&amp;quot;全国\&amp;quot;,\&amp;quot;birthday\&amp;quot;:\&amp;quot;1982-07-23\&amp;quot;,\&amp;quot;email\&amp;quot;:\&amp;quot;363854962@qq.com\&amp;quot;,\&amp;quot;gender\&amp;quot;:\&amp;quot;2\&amp;quot;,\&amp;quot;idCode\&amp;quot;:\&amp;quot;220724198207231823\&amp;quot;,\&amp;quot;idType\&amp;quot;:\&amp;quot;0\&amp;quot;,\&amp;quot;mobile\&amp;quot;:\&amp;quot;15506588298\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;王微\&amp;quot;,\&amp;quot;type\&amp;quot;:\&amp;quot;0\&amp;quot;},\&amp;quot;insureOrderInfo\&amp;quot;:{\&amp;quot;effectTime\&amp;quot;:\&amp;quot;2021-04-29 00:00:00\&amp;quot;,\&amp;quot;firstPeriodPremium\&amp;quot;:960,\&amp;quot;invalidTime\&amp;quot;:\&amp;quot;2022-04-28 23:59:59\&amp;quot;,\&amp;quot;isRenewPolicy\&amp;quot;:false,\&amp;quot;issueTime\&amp;quot;:\&amp;quot;2021-04-27 09:11:48\&amp;quot;,\&amp;quot;nextPeriodPremium\&amp;quot;:0,\&amp;quot;payFrequency\&amp;quot;:\&amp;quot;0\&amp;quot;,\&amp;quot;payMode\&amp;quot;:\&amp;quot;1\&amp;quot;,\&amp;quot;planCode\&amp;quot;:\&amp;quot;260812\&amp;quot;,\&amp;quot;presenterPolicy\&amp;quot;:false,\&amp;quot;productCode\&amp;quot;:\&amp;quot;2608\&amp;quot;,\&amp;quot;totalAmount\&amp;quot;:6000000,\&amp;quot;totalPremium\&amp;quot;:960.00},\&amp;quot;insuredInfos\&amp;quot;:[{\&amp;quot;address\&amp;quot;:\&amp;quot;全国\&amp;quot;,\&amp;quot;birthday\&amp;quot;:\&amp;quot;1990-03-07\&amp;quot;,\&amp;quot;gender\&amp;quot;:\&amp;quot;1\&amp;quot;,\&amp;quot;hasSocial\&amp;quot;:false,\&amp;quot;idCode\&amp;quot;:\&amp;quot;110101199003078153\&amp;quot;,\&amp;quot;idType\&amp;quot;:\&amp;quot;0\&amp;quot;,\&amp;quot;mobile\&amp;quot;:\&amp;quot;13792889545\&amp;quot;,\&amp;quot;name\&amp;quot;:\&amp;quot;王思思\&amp;quot;,\&amp;quot;relType\&amp;quot;:2,\&amp;quot;type\&amp;quot;:\&amp;quot;0\&amp;quot;}]},\&amp;quot;head\&amp;quot;:{\&amp;quot;interfaceType\&amp;quot;:\&amp;quot;/general/proposalOrder\&amp;quot;,\&amp;quot;orderNo\&amp;quot;:\&amp;quot;BC0000001\&amp;quot;,\&amp;quot;policySource\&amp;quot;:\&amp;quot;HN_BC\&amp;quot;,\&amp;quot;reqTime\&amp;quot;:\&amp;quot;2021-04-27 09:11:48\&amp;quot;,\&amp;quot;uuid\&amp;quot;:\&amp;quot;ca32571e-3b57-4041-b85a-34b5db0b333f\&amp;quot;}}&amp;quot;; private final static String EData = &amp;quot;35URoRsQtIQSC5HS8YWj7NckJeLAe423pWGNkGufMYArowNr1Y/QMYBp11tfb0ClJM5VAmH7Up1zWaotOB6RfCWKDpsfiQ6/BL55T4fmjSDxdGYvzCvEx4pR8ORpKAjR8ALp5caXI1b0P/cYk8uK1rtXarLvgzSNxWOyKNnaLEC4H4DXYsyUH7SvByt+hJyvDu18NDf4GKsy0tMNvxEpy2A404s+JqZCma1M1i+AyRYnBKVCpzm9Hr1zM1yl05NPqmQxzFuepCXhbVEkYhKqOH2dLzwgaABHFrLg7oUJa5ahu/Z5CpYsJ8GJg/UY6IPfeGDgoNMLgmdXOq58mKoSmcjo04nFofLade+8mmBLYWK44mikQ1BC/Df0uRpDuB8RpqLjlCiUV7PXTg+DlVlZuGE7Sj5XLTOYl6DJ4Fg5SiJbatOLRZuVhI394vJ2xdVCIIzUwFA+fwPAstcXS1zR9EKRiwwOzkYS1t0Xe6ZCTHhdFuPFdxNrvgfbQyeKlSjZAtmgnkCf+S5XO5NQrSelFSE4RdyBY7wc4r61oep+ZcyxoHCVqALmkjMH+Bu7N/bgfLPifGxoZX6/NYFT5o94STe/bg8+yvCCgibJM9ZknxPvTB0vg9rEEq5MXgK+ui8VE+/otjncBrrjvkejM9S2OLaTCIJY1E7lCJL2PyB3+b1phQZ7i9UQUVRMM/bV5ttC0SIPh22vQFMxAZSIJirXpEn0TJyGl/GsRDNWjDqtSTiqmp7uSF1CNhZIdQjyCh+iuqNTcYJcWRZjWa38dNYe3ybiH7Hl6A6W44m+LZxZyndRQcXdGXqo87BP5heQMOokttAuCoIm2irTaXldEGHM1IseD/AIRpLjhRLEqut5yvEZ2Zjz2hDSUnhJcwNqqmXmOcU9PqY6fOxUsH4UqJ/hYfdon8cJDxdHsHkRvwwCJWNxtDnOF7YdbSNvMsjA+J00i9Vj13p2JGGXtAzMqYXAj2F7fapZ/uoe32Qza6uxKxlIfNWlgq4fHc3AFkKlk614Cx/TLDNwmQBIpG8dccgpmHdwsjbBDok3bkwxhnxeGDrJc8HzVS5HRB7f2+doYeBULun5WEqv1UobTaixpszL8M1rqTNDspluYj29AC9fV1BLSAf1rFpm5otxHYy7CDSZfPqJ/w2ih+ooijXLExMxtFCqxn22ZtJIL+MDnfOkU3NJHU1MYrY9Ho2Sjxnl0xTJcvMzM2JtYCNRJut9ZwFzng==&amp;quot;; public static String encode(String data) { int mode = 1; try { byte[] content = data.getBytes(StandardCharsets.UTF_8); SecretKey secretKey = getSecretKey(aesKey); // 创建密钥 SecretKeySpec keySpec = new SecretKeySpec(secretKey.getEncoded(), &amp;quot;AES&amp;quot;); // 创建密码器 Cipher cipher = Cipher.getInstance(&amp;quot;AES&amp;quot;); // 初始化 cipher.init(mode, keySpec); byte[] result = cipher.doFinal(content); return new String(Base64.encodeBase64(result)); } catch (Exception e) { System.err.println(&amp;quot;AES密文处理异常&amp;quot; + e); e.printStackTrace(); } return null; } public static String decode(String data) { long startTime = System.currentTimeMillis(); try { byte[] decode = Base64Utils.decode(data.getBytes()); // 解密 byte[] decryptResult = decrypt(decode, aesKey); String decryptContent = new String(decryptResult, &amp;quot;UTF-8&amp;quot;); return decryptContent; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e + &amp;quot;解密失败&amp;quot;); } } public static String getSign(String data) { String newSign = MD5Utils.md5(data + key, &amp;quot;utf-8&amp;quot;); return newSign; } public static SecretKey getSecretKey(String key) { try { KeyGenerator gen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;); if (null == Security.getProvider(SECURITY_PROVIDER)) { Security.addProvider(new Sun()); } SecureRandom secureRandom = SecureRandom.getInstance(&amp;quot;SHA1PRNG&amp;quot;); secureRandom.setSeed(key.getBytes()); gen.init(128, secureRandom); return gen.generateKey(); } catch (Exception e) { throw new RuntimeException(&amp;quot;初始化秘钥出现异常&amp;quot;); } } public static byte[] decrypt(byte[] content, String password) { try { SecureRandom random = SecureRandom.getInstance(&amp;quot;SHA1PRNG&amp;quot;); random.setSeed(password.getBytes()); KeyGenerator kgen = KeyGenerator.getInstance(&amp;quot;AES&amp;quot;); kgen.init(128, random); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, &amp;quot;AES&amp;quot;); // 创建密码器 Cipher cipher = Cipher.getInstance(&amp;quot;AES&amp;quot;); // 初始化 cipher.init(Cipher.DECRYPT_MODE, key); byte[] result = cipher.doFinal(content); // 加密 return result; } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { e.printStackTrace(); } return null; } public static void main(String[] args) { String encode = encode(DData); System.out.println(&amp;quot;加密:&amp;quot; + encode); String sign = getSign(encode); System.out.println(&amp;quot;签名:&amp;quot; + sign); String decode = decode(EData); System.out.println(&amp;quot;解密:&amp;quot; + decode); HttpRequest request = HttpUtil.createPost(&amp;quot;https://porsche-avatar.chinahuanong.com.cn/avatar/general/proposalOrder&amp;quot;); request.header(&amp;quot;sign&amp;quot;, sign); request.header(&amp;quot;orderNo&amp;quot;, &amp;quot;123&amp;quot;); request.header(&amp;quot;policySource&amp;quot;, &amp;quot;123&amp;quot;); request.header(&amp;quot;content-type&amp;quot;,&amp;quot;text/plain&amp;quot;); // request.contentType(&amp;quot;text/plain&amp;quot;); request.body(encode); HttpResponse execute = request.execute(); String respBody = execute.body(); String deBody = decode(respBody); System.out.println(&amp;quot;解密:&amp;quot; + deBody); } } </code></pre> <h1>PHP加解密示例</h1> <pre><code class="language-php">&amp;lt;?php /** * 加密 */ function encrypt(string $data): string { $key = &amp;#039;sadedfjekashciew&amp;#039;; $aesKey = substr(openssl_digest(openssl_digest($key, &amp;#039;sha1&amp;#039;, true), &amp;#039;sha1&amp;#039;, true), 0, 16); return base64_encode(openssl_encrypt($data, &amp;#039;AES-128-ECB&amp;#039;, $aesKey, OPENSSL_RAW_DATA)); } /** * 解密 */ function decrypt(string $data): string { $key = &amp;#039;sadedfjekashciew&amp;#039;; $aesKey = substr(openssl_digest(openssl_digest($key, &amp;#039;sha1&amp;#039;, true), &amp;#039;sha1&amp;#039;, true), 0, 16); return openssl_decrypt(base64_decode($data), &amp;#039;AES-128-ECB&amp;#039;, $aesKey, OPENSSL_RAW_DATA); } $json = &amp;#039;{&amp;quot;avatarInsureBody&amp;quot;:{&amp;quot;insureOrderInfo&amp;quot;:{&amp;quot;productCode&amp;quot;:&amp;quot;PDC00177&amp;quot;,&amp;quot;planCode&amp;quot;:&amp;quot;PLC00881&amp;quot;,&amp;quot;issueTime&amp;quot;:&amp;quot;2023-11-10 14:57:01&amp;quot;,&amp;quot;effectTime&amp;quot;:&amp;quot;2023-11-10 14:57:01&amp;quot;,&amp;quot;invalidTime&amp;quot;:&amp;quot;2023-11-10 17:57:01&amp;quot;,&amp;quot;periodDay&amp;quot;:&amp;quot;30&amp;quot;,&amp;quot;payFrequency&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;isRenewPolicy&amp;quot;:false,&amp;quot;parentPolicyNo&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;firstPeriodPremium&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;totalPremium&amp;quot;:&amp;quot;3&amp;quot;,&amp;quot;totalAmount&amp;quot;:&amp;quot;110000&amp;quot;,&amp;quot;presenterPolicy&amp;quot;:true,&amp;quot;payMode&amp;quot;:2},&amp;quot;holderInfo&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;太原合旭网络科技有限公司&amp;quot;,&amp;quot;idType&amp;quot;:&amp;quot;6&amp;quot;,&amp;quot;idCode&amp;quot;:&amp;quot;91149900MA7XHL8Q3M&amp;quot;,&amp;quot;province&amp;quot;:&amp;quot;140000&amp;quot;,&amp;quot;city&amp;quot;:&amp;quot;140100&amp;quot;,&amp;quot;district&amp;quot;:&amp;quot;140105&amp;quot;,&amp;quot;unitResidence&amp;quot;:&amp;quot;太原市小店区长风街道和信商座3202&amp;quot;,&amp;quot;linkerName&amp;quot;:&amp;quot;吉晓彬&amp;quot;,&amp;quot;linkerPhone&amp;quot;:&amp;quot;13100008431&amp;quot;,&amp;quot;industryType1&amp;quot;:&amp;quot;U99&amp;quot;,&amp;quot;unitType&amp;quot;:&amp;quot;0007&amp;quot;,&amp;quot;extensionInfo&amp;quot;:{&amp;quot;linkerIdentifyNo&amp;quot;:&amp;quot;142430199109301637&amp;quot;,&amp;quot;linkerIdentifyType&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;companyAddress&amp;quot;:&amp;quot;山西转型综合改革示范区学府产业园平阳路426号大和昌业29层2901室&amp;quot;}},&amp;quot;insuredInfos&amp;quot;:[{&amp;quot;name&amp;quot;:&amp;quot;鹿坤&amp;quot;,&amp;quot;idType&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;idCode&amp;quot;:&amp;quot;140411199510194419&amp;quot;,&amp;quot;gender&amp;quot;:&amp;quot;1&amp;quot;,&amp;quot;birthday&amp;quot;:&amp;quot;1995-10-19&amp;quot;,&amp;quot;mobile&amp;quot;:&amp;quot;15035514195&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;relType&amp;quot;:&amp;quot;0&amp;quot;,&amp;quot;extensionInfo&amp;quot;:{&amp;quot;schoolName&amp;quot;:&amp;quot;山东华宇工学院&amp;quot;}}]},&amp;quot;head&amp;quot;:{&amp;quot;policySource&amp;quot;:&amp;quot;PHN_ZTJJ_CKYW&amp;quot;,&amp;quot;reqTime&amp;quot;:&amp;quot;2023-11-10 14:57:01&amp;quot;,&amp;quot;interfaceType&amp;quot;:&amp;quot;proposalOrder&amp;quot;,&amp;quot;orderNo&amp;quot;:&amp;quot;20231031153158644564&amp;quot;,&amp;quot;uuid&amp;quot;:&amp;quot;xmx202311101699599421&amp;quot;}}&amp;#039;; $encryptData = encrypt($json); echo &amp;quot;密文:&amp;quot; . $encryptData . PHP_EOL; $md5Key = &amp;#039;fuahdfujhauidhiuawse&amp;#039;; $sign = md5($encryptData . $md5Key); echo &amp;quot;sign:&amp;quot; . $sign . PHP_EOL; $decryptData = decrypt($encryptData); echo &amp;quot;明文:&amp;quot; . $decryptData; ?&amp;gt; </code></pre> <h1>.NET 加密示例</h1> <pre><code> using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Web; namespace InsuranceSys.UI.Common { public class AESEncrypter { /// &amp;lt;summary&amp;gt; /// 生成对应JAVA AES加密方法的KEY值 /// &amp;lt;/summary&amp;gt; /// &amp;lt;param name=&amp;quot;aesKey&amp;quot;&amp;gt;&amp;lt;/param&amp;gt; /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; private static byte[] encryptJavaAes(string aesKey) { byte[] keyArray = null; using (var sha1 = new SHA1CryptoServiceProvider()) { byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(aesKey)); var rd = sha1.ComputeHash(hash); keyArray = rd.Take(16).ToArray(); /* 将字节流转换成字符串输出 Base64Encoder coder = new Base64Encoder(); coder.GetEncoded(keyArray); * */ } return keyArray; } /// &amp;lt;summary&amp;gt; /// .NET对JAVA进行AES加密 /// &amp;lt;/summary&amp;gt; /// &amp;lt;param name=&amp;quot;encryptString&amp;quot;&amp;gt;需要加密的字符串&amp;lt;/param&amp;gt; /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; public static string AESEncryptForJava(string encryptString, string aesKey) { if (string.IsNullOrEmpty(encryptString)) return null; Byte[] toEncryptArray = Encoding.UTF8.GetBytes(encryptString); RijndaelManaged rm = new RijndaelManaged { Key = encryptJavaAes(aesKey),//Convert.FromBase64String(encryptKey), Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }; ICryptoTransform cTransform = rm.CreateEncryptor(); Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } /// &amp;lt;summary&amp;gt; /// 解密加密的字符串 /// &amp;lt;/summary&amp;gt; /// &amp;lt;param name=&amp;quot;toDecrypt&amp;quot;&amp;gt;需要解密的字符串&amp;lt;/param&amp;gt; /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt; public static string AESDecryptForJava(string toDecrypt,string aesKey) { string aeskey = System.Configuration.ConfigurationManager.AppSettings[&amp;quot;aeskey&amp;quot;]; byte[] keyArray = encryptJavaAes(aesKey);//Convert.FromBase64String(key); byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.Mode = CipherMode.ECB; //必须设置为ECB rDel.Padding = PaddingMode.PKCS7; //必须设置为PKCS7 ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } } } </code></pre> <h1>关于电子保单保函403的问题</h1> <p>保司使用的电子保函、电子保单链接<strong>有可能</strong>为HTTP请求302的重定向链接,会出现无法直接下载获取的情况,jdk8以上请使用该方法再试一次方可解决403或无法下载电子保单保函的问题</p> <h3>JAVA</h3> <pre><code class="language-java">import java.io.*; import java.net.HttpURLConnection; import java.net.URL; /** * 从网络Url中下载文件并加密成base64 * * @param urlStr * @throws IOException * @return */ public static byte[] downLoadByUrlBase64(String urlStr) throws IOException { URL url = new URL(urlStr); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //设置超时间为3秒 conn.setConnectTimeout(5 * 1000); //302重定向则获取重定向后的地址重新下载 int responseCode = conn.getResponseCode(); if (responseCode == 302) { return downLoadByUrlBase64(conn.getHeaderField(&amp;quot;location&amp;quot;)); } //得到输入流 InputStream inputStream = conn.getInputStream(); //获取自己数组 byte[] getData = readInputStream(inputStream); if (inputStream != null) { inputStream.close(); } return getData; }</code></pre> <p>上述代码使用了java.net.*可解决403问题,若使用了HttpClient的话请在上述的基础上再加上</p> <pre><code class="language-java">setRedirectsEnabled(false) //默认为 true 请设置成false</code></pre> <h3>PHP</h3> <pre><code class="language-php">function downloadByUrlBase64($urlStr) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $urlStr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 10); $data = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode == 302) { return downloadByUrlBase64($data); } else { return base64_encode($data); } }</code></pre> <h3>python</h3> <pre><code class="language-python">import requests import base64 def download_by_url_base64(url): response = requests.get(url, timeout=5) if response.status_code == 302: return download_by_url_base64(response.headers[&amp;#039;location&amp;#039;]) elif response.status_code != 200: raise Exception(&amp;#039;请求失败,HTTP状态码为{}&amp;#039;.format(response.status_code)) else: return base64.b64encode(response.content).decode()</code></pre>

页面列表

ITEM_HTML