保利威文档中心

幫助中心

SM2加密說明

更新時間:2024-08-14 09:51:53

演算法參數說明

  1. 金鑰對生成
  1. 加密模式
  • 使用C1C2C3模式
  • 加密結果byte[]轉Hex字串

公鑰配置說明

前往新版管理後台配置、查看SM2公鑰 sm2_config.png

請求參數加密說明

註:使用保利威SM2公鑰加密

請求參數加密開啟

請求頭攜帶參數x-e-type:2,值2表示SM2加密

GET加密請求參數規則

暫不支援GET請求參數加密

POST JSON請求參數加密規則

  1. 將body中JSON報文整體使用保利威公鑰SM2加密
  2. POST請求body為加密後的密文

POST FORM表單請求參數加密規則

註:簽名相關參數appId,timestamp,sign不參與加密

  1. 原始參數生成簽名sign
  2. 將簽名檢驗參數appId,sign,timestamp除外的其他業務參數按照JSON格式封裝
{
    "channelId": 2376543,
    "pageNumber": 1,
    "pageSize": 10
}
  1. 將JSON報文使用保利威公鑰SM2加密得到密文ABCDEF
SM2Util.encrypt(respEncryptKey, SM2Engine.Mode.C1C2C3, xparam)
  1. 剔除加密前業務參數,表單增加加密欄位xparam=ABCDEF
http://api.polyv.net/xxx?appId=xxx&sign=xxx&timestamp=xxx&xparam=ABCDEF

加密參數請求響應說明

  1. 請求參數解密成功時,正常響應介面對應業務碼
  2. 請求參數解密失敗時,http響應碼為400,錯誤業務碼10001
{
    "code": 400,
    "status": "error",
    "error": {
        "code": 10001,
        "desc": "参数错误"
    },
    "success": false
}

響應報文加密說明

註:使用者生成SM2公私鑰對(自行保管好私鑰),在保利威平台配置的SM2公鑰,開啟響應加密後,會對響應報文中data欄位進行加密

響應參數加密開啟

請求參數攜帶參數encryptResponseType:2,值2表示SM2加密

響應報文加密規則

  1. 未配置金鑰或配置錯誤金鑰,響應結果為明文不加密
  2. 只對響應碼200,業務成功響應時,JSON中data欄位進行加密
  3. 響應碼非200,業務失敗時,error為明文不加密
  4. 使用者使用對應SM2金鑰對響應報文進行解密
  5. 加密報文響應範例
{
    "code": 200,
    "status": "success",
    "data": "043D1BF16CB1C2629348A7B18F9C51036C9466F3E198F75C6ABDE83A428E2893",
    "success": true
}

SM2加解密演算法範例程式碼

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.5.2</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
import java.nio.charset.StandardCharsets;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import cn.hutool.crypto.BCUtil;
import cn.hutool.crypto.ECKeyUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;

public class SM2Util {
    
    /**
     * 生成密钥对
     * @return
     */
    public static SM2KeyPair generateKeyPair() {
        SM2 sm2 = SmUtil.sm2();
        //这里会自动生成对应的随机秘钥对 , 注意! 这里一定要强转,才能得到对应有效的秘钥信息
        byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());
        //这里公钥不压缩  公钥的第一个字节用于表示是否压缩  可以不要
        byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);
        SM2KeyPair sm2KeyPair = new SM2KeyPair();
        sm2KeyPair.setPrivateKey(Util.byteToHex(privateKey));
        sm2KeyPair.setPublicKey(Util.byteToHex(publicKey));
        return sm2KeyPair;
    }
    
    /**
     * 加密
     * @param publicKey
     * @param mode
     * @param text
     * @return byte2Hex
     */
    public static String encrypt(String publicKey, SM2Engine.Mode mode, String text) {
        SM2 sm2 = SmUtil.sm2();
        sm2.setPublicKeyParams(ECKeyUtil.toSm2PublicParams(publicKey));
        sm2.setMode(mode);
        byte[] encrypt = sm2.encrypt(text.getBytes(StandardCharsets.UTF_8), KeyType.PublicKey);
        return Util.byteToHex(encrypt);
    }
    
    /**
     * 解密
     * @param privateKey
     * @param mode SM2Engine.Mode
     * @param text hexString
     * @return
     */
    public static String decrypt(String privateKey, SM2Engine.Mode mode, String text) {
        SM2 sm2 = SmUtil.sm2();
        sm2.setPrivateKeyParams(ECKeyUtil.toSm2PrivateParams(privateKey));
        sm2.setMode(mode);
        byte[] encrypt = sm2.decrypt(Util.hexToByte(text), KeyType.PrivateKey);
        return new String(encrypt);
    }
    
    
}
联系客服,在线咨询