一:协议规范

为确保数据交互安全,使用RSA私钥签名+AES加密接口调用方式。

RSA私钥签名+AES加密:使用RSA私钥对数据生成签名,用分配的secret_key对数据进行AES加密,以防止敏感信息泄露。

 

二:请求字段规范

1、RSA签名+AES加密

字段名

字段类型

字段说明

version

String

当前接口版本号,默认为:1.0

sign

String

RSA签名

content

String

json字符串通过secret_key AES加密并转换为16进制的字符串

└─phone

String

手机号

└─smscontent

String

发送内容

请求参数参考:

{

  "version": "1.0",

  "sign": "V3CP+NalLWGawdxZKjRv",

  "content": "EC18C4D91553D4227AB8F615"

}

三、响应字段规范

字段名

字段类型

字段说明

code

String

返回码,200成功,其他失败

errorCode

String

错误编码,英文错误码

msg

String

返回消息

返回格式参考:

{

  "code": "200",

  "errorCode": "SUCCESS",

  "msg": "ok"

}

 

四、RSA签名及验签

1、首先对data(明文)中各字段参数按参数名做字典序升序排列

2、将上一步所得结果中字段按照key=value格式化,并通过&拼接为字符串。

3、调用方对上一步所得字符串计算RSA私钥签名,签名方式为'SHA256withRSA'; 被调用方(即发货方)用分配的secret_key对数据进行AES解密,然后用分配的RSA公钥进行验签。

示例:

data:{"phone": “18353521235”, "smscontent":”xxxxxx”}

签名字符串: phone=18353521235&smscontent=xxxxxx

RSA签名计算方式参考:

 

/**

* 用私钥对信息生成数字签名

* @param rasPrivateKey RSA私钥

* @param data 待签名数据,须转成二进制格式

* @return 签名

*/

public static String sign(String rasPrivateKey, byte[] data) throws Exception{

    // 解密私钥                                                                      

    byte[] keyBytes = Base64.decodeBase64(rasPrivateKey);                       

    //构造PKCS8EncodedKeySpec对象                                                   

    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);

    //指定加密算法                                                                    

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");                      

    //取私钥匙对象                                                                    

    PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);    

    //用私钥对信息生成数字签名                                                              

    Signature signature = Signature.getInstance("SHA256withRSA");               

    signature.initSign(privateKey);                                             

    signature.update(data);                                                     

    return Base64.encodeBase64String(signature.sign()).replaceAll("[\r\n]", "");

}

验签样例:

/**

* 校验数字签名

* @param data 待签名数据

* @param sign RSA私钥签名

* @param rasPublicKey RSA公钥

* @return 验签成功返回true, 否则返回false

*/

public static boolean verify(byte[] data, String sign, String rasPublicKey)throws Exception{

    //解密公钥

    byte[] keyBytes = decryptBASE64(rasPublicKey);

    //构造X509EncodedKeySpec对象

    X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);

    //指定加密算法

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");

    //取公钥匙对象

    PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);

 

    Signature signature = Signature.getInstance("SHA256withRSA");

    signature.initVerify(publicKey2);

    signature.update(data);

    //验证签名是否正常

    return signature.verify(decryptBASE64(sign));

}

五、AES加密及解密

加密:

/**

 * AES 加密操作

 * @param content 待加密内容

 * @param password 加密密码

 */

public static byte[] encrypt(String content, String password) {

    try {

        byte[] byteContent = content.getBytes("utf-8");

        // 创建密码器

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

        // 初始化为加密模式的密码器,秘钥长度 16/24/32

        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password.getBytes("utf-8"), "AES"));

        return cipher.doFinal(byteContent);

    } catch (Exception e) {

        e.printStackTrace();

    }

    // 如果有错就返回null

    return null;

}

 

解密:

/**

 * AES 解密操作

 * @param content 待解密内容

 * @param password 加密密码

 * @return

 */

public static String decrypt(byte[] content, String password) {

    try {

        //实例化

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

        //使用密钥初始化,设置为解密模式,秘钥长度 16/24/32

        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password.getBytes("utf-8"), "AES"));

        //执行操作

        byte[] result = cipher.doFinal(content);

        return new String(result, "utf-8");

    } catch (Exception e) {

        e.printStackTrace();

    }

    // 如果有错就返回null

    return null;

}

 

/**

* 将二进制转换为16进制

* @param buf 待转换二进制数组

* @return 16进制字符串

*/

static String parseByte2HexStr(byte[] buf) {

    StringBuilder sb = new StringBuilder();

    for (byte b : buf) {

        String hex = Integer.toHexString(b & 0xFF);

        if (hex.length() == 1) {

        hex = '0' + hex;

        }

        sb.append(hex.toUpperCase());

    }

    return sb.toString();

}

 

/**

* 将16进制转换为二进制

* @param hexStr 待转换16进制字符串

* @return 2进制字节数组

*/

static byte[] parseHexStr2Byte(String hexStr) {

    if (hexStr.length() < 1) {

        return null;

    }

    byte[] result = new byte[hexStr.length() / 2];

    for (int i = 0; i < hexStr.length() / 2; i++) {

    int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);

    int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);

    result[i] = (byte) (high * 16 + low);

    }

    return result;

}

六、请求方式

POST方式请求。

七、编码方式

UTF-8

八、ContentType

application/json