gupo/php-crypto

v0.1.59 2024-03-11 06:07 UTC

README

获取

Coding:https://cloudladder.coding.net/p/business-common/d/php-crypto/git

Packagist:https://packagist.org/packages/gupo/php-crypto

Composer:composer require gupo/php-crypto

环境

  • PHP7.4+
  • Laravel5.8+

包依赖继承关系

1.国密类依赖扩展:ext-gmp

2.国密类继承关系:lpilp/guomi

3.国密类依赖包:cloudladder/http

安装

  1. 安装国密包

    composer require gupo/php-crypto
    
  2. 配置用户中心api地址, 并让用户中心配置平台名称(system_code)生成密钥对, system_code 如:

    ih-patient-v2-api-hainan
    
  3. 增加加解密路由公共中间件, 在app/Http/Kernel.php的 $middleware 数组下增加

    \Gupo\PhpCrypto\ParamCrypto::class 
    
  4. 注册基础路由服务, 在config/app.php文件的providers数组下增加

    laravel版本:
    Gupo\PhpCrypto\Api\CryptoRouteServiceProvider::class
    
    lumen版本:
    Gupo\PhpCrypto\Api\LumenCryptoRouteServiceProvider::class
    
  5. 在项目根目录的config目录下,新建路由白名单 cryptoConfig.php 文件,内容如下:

     return [
         'platform_name'         => env('PLATFORM_NAME'),                // (必填)平台名称(资源名称); 如: ih-patient-v2-api, ih-patient-v2-api-tongliang
         'authorize_url'         => env('CRYPTO_AUTHORIZE_URL'),         // (必填)请求用户中心的api域名地址
         'api_name'              => env('CRYPTO_API_NAME'),              // 请求接口; 默认 /api/v2/system/cipher/sm2
         'method'                => env('CRYPTO_METHOD'),                // 请求方式 get 或 post; 默认 get
         'allow_code'            => env('CRYPTO_ALLOW_CODE'),            // 正确的code列表, 用,分割; 默认 200
         'code_field'            => env('CRYPTO_CODE_FIELD'),            // 验证code的字段; 默认 code
         'result_field'          => env('CRYPTO_RESULT_FIELD'),          // 获取结果的字段; 默认 data
         'param_platform_field'  => env('CRYPTO_PARAM_PLATFORM_FIELD'),  // 请求传参字段名; 默认 system_code
         'ret_public_key_field'  => env('CRYPTO_RET_PUBLIC_KEY_FIELD'),  // 结果公钥字段名, 可用.分隔代表层级; 默认 key_value.public_key
         'ret_private_key_field' => env('CRYPTO_RET_PRIVATE_KEY_FIELD'), // 结果私钥字段名, 可用.分隔代表层级; 默认 key_value.private_key
         'ret_format_sign_field' => env('CRYPTO_RET_FORMAT_SIGN_FIELD'), // 结果密钥格式字段名, 可用.分隔代表层级; 默认 key_value.format_sign
         'ret_rand_fixed_field'  => env('CRYPTO_RET_RAND_FIXED_FIELD'),  // 结果密钥中间椭圆配置字段名, 可用.分隔代表层级; 默认 key_value.rand_fixed
         'ret_is_safety_field'   => env('CRYPTO_RET_IS_SAFETY_FIELD'),   // 结果加解流程控制配置字段名, 可用.分隔代表层级; 默认 key_value.is_safety
         'ret_expire_time_field' => env('CRYPTO_RET_EXPIRE_TIME_FIELD'), // 结果密钥失效时间字段名, 可用.分隔代表层级, 格式:年-月-日 时:分:秒; 默认 key_value.expire_time
         'white'                 => env('CRYPTO_WHITE_ROUTE'),           // 免加解密路由白名单, 用,分割; 如: /* 即代表全局免加密输出, /gupo-php-crypto/crypto/get-public-key 仅针对该路由
         'is_single'             => env('CRYPTO_IS_SINGLE', 0),          // 单机模式, 默认 0; 0: 否, 1: 是
         'format_sign'           => env('CRYPTO_FORMAT_SIGN', 0),        // 单机模式密钥格式, 默认 0; 0: base64, 1: hex
         'rand_fixed'            => env('CRYPTO_RAND_FIXED', 0),         // 单机模式是否使用中间椭圆, 使用中间椭圆的话, 速度会快一些, 但同样的数据的签名或加密的值就固定了, 默认 0; 0: 否, 1: 是
         'decrypt_log'           => env('CRYPTO_DECRYPT_LOG', false)     // 是否记录request参数解密日志
     ];
    
  6. 配置env
    ## 必须 *
    PLATFORM_NAME='请替换成自己项目的资源名称'
    ## 必须 *
    CRYPTO_AUTHORIZE_URL="https://uat-api.group-ds.com/bmo-auth-api/"
    

基础接口(已在路由白名单)

  1. 获取公钥:
    https://uat-api.group-ds.com/ih-patient-v2-api-tongliang/api/gupo-crypto/crypto/get-public-key
    
  2. 密钥过期通知:
    https://uat-api.group-ds.com/ih-patient-v2-api-tongliang/innerapi/gupo-crypto/crypto/cipher-expire-notice
    
  3. 获取SM2加密内容:
    https://uat-api.group-ds.com/ih-patient-v2-api-tongliang/api/gupo-crypto/crypto/sm2-encrypt
    
  4. 获取SM2解密内容:
    https://uat-api.group-ds.com/ih-patient-v2-api-tongliang/api/gupo-crypto/crypto/sm2-decrypt
    
  5. 获取SM4加密内容:
    https://uat-api.group-ds.com/ih-patient-v2-api-tongliang/api/gupo-crypto/crypto/sm4-encrypt
    
  6. 获取SM4解密内容:
    https://uat-api.group-ds.com/ih-patient-v2-api-tongliang/api/gupo-crypto/crypto/sm4-decrypt
    

注意

请求传参:query_string和body存在同名参数时,body参数会覆盖query_string参数。
如:curl --request POST \
  --url 'http://10.123.234.158:8301/api/xxxx?a=1&b=2' \
  --header 'Authorization: JpOIlLlBENEg88WWx8Ub7A==' \
  --header 'content-type: multipart/form-data' \
  --form a=3 \
  --form b=2

最终实际拿到的结果:
{
    "a": 3,
    "b": 2
}

错误码

错误码含义
4222配置或解密失败错误

使用示例

  1. sm2加密:(new Sm2())->sm2Encrypt(公钥, 原文)

    $public_key   = '04343750eb81d0d4dbdc9f04c9f92118bbbe325660f59ccd7767cbf5c30a03242bcf656c5c9ec8857b13a68e3e1789c4a190a9277250a249cfa1b8bd9fb1d1da5b'
    $encrypt_text = '353778304a464b6d756573386c63654e';
    (new Sm2($this->formatSign))->sm2Encrypt($public_key, $encrypt_text);
    
  2. sm2解密:(new Sm2())->sm2Decrypt(私钥, base64_encode(密文))

    $private_key  = '94e41c33646343a159c6d4e18c32210f82789fe24b74d6ee7482879c844d9602';
    $decrypt_text = base64_encode('79e6dd716048248ad915dd4b796b5b08e563513c6cece3dbe012b8909b236304bbacf91175ae4baaad68edd142ca84fe8521e6260e1f1103b2826fde2b2fa124aeec1d1be69af218c4a8b748374bbf0a72902f7aaa10557aea7ff868d8455db30a2122caf6ae5029c0bc9991bc2fda1ed777f1f11a22b9659a4dc3116be25e6a');
    (new Sm2($this->formatSign))->sm2Decrypt($private_key, $decrypt_text);
    
  3. sm4生成密钥:Sm4::buildSm4Secret(约定密钥, 盐值)

    $public_key   = '04343750eb81d0d4dbdc9f04c9f92118bbbe325660f59ccd7767cbf5c30a03242bcf656c5c9ec8857b13a68e3e1789c4a190a9277250a249cfa1b8bd9fb1d1da5b'
    $data_time    = time();
    Sm4::buildSm4Secret($public_key, $data_time);
    
  4. sm4加密:(new Sm4(密钥))->sm4Encrypt(原文)

    $public_key   = '04343750eb81d0d4dbdc9f04c9f92118bbbe325660f59ccd7767cbf5c30a03242bcf656c5c9ec8857b13a68e3e1789c4a190a9277250a249cfa1b8bd9fb1d1da5b'
    $data_time    = time();
    $key          = Sm4::buildSm4Secret($public_key, $data_time);
    $encrypt_text = '{"publick_key":"04343750eb81d0d4dbdc9f04c9f92118bbbe325660f59ccd7767cbf5c30a03242bcf656c5c9ec8857b13a68e3e1789c4a190a9277250a249cfa1b8bd9fb1d1da5b","is_safety":"1"}';
    (new Sm4($key))->sm4Encrypt($encrypt_text, 'sm4-ecb');
    
  5. sm4解密:(new Sm4(密钥))->sm4Decrypt(密文)

    $key = '6515bde8915db460';
    $decrypt_text = '1Cmb5sWZh5iYql0y4BwSZeCn3RUNADs/k2CSIAM0/dXKR8SmSEg9thOG2xpQPaf9OAa81lyBKdfR2v7IPzJUU5hj+XSk1v0CzLvHaWJo2qH54BlXgKC7bvsBNKv3RuZaxOKTRGBRMz6zlDRwWUJ9qkzFDwDAs8+3d1x2kMXoPXsRb9kxav62TBs4waPUQSjgL0nce4yVUaxu9dag1jmx7o+f8nNyN8K85EpbYAHwrzY=';
    (new Sm4($key))->sm4Decrypt($decrypt_text, $this::SM4_TYPE);