APIP1V1_OpenAPI(zh-CN)



  • APIP1: OpenAPI
    Version: 1
    Language: zh-CN
    Author: C_armX
    Status: draft
    Created date: 2021-10-30
    update:2021-11-24
    File hash: ""
    TXid: 
    

    APIP1V1_OpenAPI(zh-CN)

    目录

    摘要

    什么是APIP

    APIP协议的共识

    本协议的基本共识

    连接请求与响应

    数据请求与响应

    两种服务方式

    摘要

    Type: APIP
    SerialNumber: 1
    ProtocolName: OpenAPI
    Version: 1
    Description : 在freecash主链上发布用于规范各种API的基础协议.
    Author: C_armX
    Language: zh-CN
    tags: APIP, API, general protocol
    preVersionHash:""
    

    什么是APIP

    1. APIP是自由共识生态协议的一种类型,用于创建开放的API文档,并且按照《FEIP1_FreeProtocol》的规则发布在Freecash主链上。

    2. “自由共识”是基于去中心化的密码身份的开放生态,APIP协议为该生态构建去中心化的API市场。

    3. 任何人可按照某个APIP协议开发和提供相应的API服务。

    4. 各种密码应用(CAPP)在开发时只根据需要选用APIP协议,运行时可动态选择该协议的任何一个API服务实例。

    5. CAPP指的是采用椭圆曲线算法的公私钥作为身份系统的各种应用程序。

    APIP协议的共识

    1. 按照APIP类型发布的接口的唯一标识为:接口名称@PID#[接口协议的PID]。示例:

    txList@PID#855fa18ea748a558404dba9fffde10691feac325a6e8fbdc7fc3a0afe84e736d

    1. API的URL路径由服务商按照《FEIP29_Service》协议在“url”字段发布上链。

    2. APIP协议涉及的时间戳,若无特定说明,默认为13位,精确到毫秒。

    3. 采用HTTP/HTTPS协议POST方法请求时,参数采用JSON格式,请求头部包含:Content-type: application/json

    4. 无特殊说明,哈希算法采用两次sha256算法,即:sha256(sha256([message])).

    5. 请求参数的筛选字段:

      • 筛选字段在原字段名前加filter,如:以cd为筛选条件的字段为filterCd

      • 数字类型:"filterCd": "-2, 3, 4-5, 7-"

        对cd字段进行筛选,选择值小于2(不含2)、或等于3、或4与5之间(含4和5)、或大于4(不含4)的所有条目。

      • 字符串类型:

        • 模糊查询: "filterCid": "C_arm"

          不区分大小写,查询cid字段所有包含“C_arm”的条目,如“C_ARmX”。

        • 非空查询: "filterOpReturn":"not_null"

          查询opReturn字段非空的所有条目。

        • 为空查询:"filterOpReturn":"null"

          查询opReturn字段为空的所有条目。

      • 布尔类型: "filterStatus": 0

      • 多个筛选字段时,筛选关系为“与”,即满足所有筛选条件。

        {
          "filterCd": "7-",
          "filterCid": "arm"
        }  //查询cd大于7,且cid包含"arm"的条目。
    
    1. 请求参数的排序字段:

      • 排序字段在原字段名前加sort,如以cd排序的字段名为sortCd

      • 排序字段的值为up(升序)或down(降序):

        "sortCd": "up"

        即:以cd字段升序排序

      • 每次请求的排序字段唯一,不支持多级排序。

    2. 请求批量数据时,以count字段给出每次请求的条目数,sequence字段给出当前请求第几批次。sequence从0开始,缺省默认为第0批。如:

    {
        "count":100,
        "sequence":3
    }
    //即:请求排序为第201至300项,共100项数据。
    

    本协议的基本共识

    1. Open API是规定APIP类型协议的一般共识的基础协议,其他APIP协议可以引用本协议,而不需要重复描述这些一般共识。

    2. 本协议定义CAPP请求连接API和请求数据的基本方式。

    3. 本协议的数据采用JSON格式。

    4. 本协议示例数据:

    requester的FCH地址:FEk41Kqjar45fLDriztUDTUkdki7mmcjWK
    requester的公钥:030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a
    requester的私钥:L2bHRej6Fxxipvb4TiR5bu1rkT3tRp8yWEsUy4R1Zb8VMm2x7sd8
    

    连接请求接口

    requester通过此接口向API服务商提出连接请求,获取对称密钥secretKey,用于后续的各种数据请求。连接请求的简要过程为:

    requester提供自己的公钥并附上私钥签名,向API服务商提出连接请求;API服务商为该requester生成对称密钥secretKey,并用requester的公钥加密做出响应;requeter解密保存secretKey用于进一步的数据请求。

    1. 接口名称

    connect

    2. 请求方法

    GET

    POST

    3. URL

    API服务商根据《FEIP29_Service》在url字段中发布API服务的路径,格式为:

    schema://domainOrIP:port/path/

    所需信息 必填 说明
    schema Y 协议类型,http、https、ws等
    domainOrIP Y 域名或IP
    port N 端口
    path N 接口路径

    示例

    https://www.sign.cash/api/connect
    

    4. 请求参数

    连接请求需要提供的参数:

    参数 类型 必填 说明
    timestamp time stamp Y Timestamp in milliseconds。精确到毫秒的时间戳
    publicKey hex Y 请求者的公钥
    sign string Y 用publicKey对应私钥对其他参数构造的url的签名

    5. 构造连接请求

    • 1)参数排序

    对除sign以外的参数,按字母升序排序,如:

    {
        "publicKey":"030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a",
        "timestamp":1635513688254
    }
    
    • 2)构造未签名请求unsignedRequest

    GET

    https://www.sign.cash/api/connect?publickey=030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a&timestamp=1635513688254
    

    POST

    加入URL:https://www.sign.cash/api/connect

    {"publicKey":"030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a","timestamp":1635513688254,"url":"https://www.sign.cash/api/connect"}
    
    • 3)签名

    用publicKey的私钥对构造的unsignedRequest进行签名,得到sign的值:

    GET

    H5viYRRPi4fr4ivgWAiSkWS7pLRpo+8YjiJ2FaRjnCDqUSUlEgIfav/AsYXYe862EgGUjICSISr8QeL1qIXCRfI\u003d
    
    - url编码后得到sign的值:
    
    H5viYRRPi4fr4ivgWAiSkWS7pLRpo%2B8YjiJ2FaRjnCDqUSUlEgIfav%2FAsYXYe862EgGUjICSISr8QeL1qIXCRfI%5Cu003d
    

    POST

    IPZEm2XcRA2dxw3OFrHLT5KzS03MqZyp++QT/3TF5AGdfcfm0GCZo8t8FUE+MLiZ7ZNH0GV1Er8pJole+Qv73lE\u003d
    
    • 4)生成请求signedRequest

    GET

    - 将url编码后的sign添加到unsignedRequest的末尾,得到signedRequest的值:
    
    https://www.sign.cash/api/connect?publickey=030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a&timestamp=1635513688254&sign=H5viYRRPi4fr4ivgWAiSkWS7pLRpo%2B8YjiJ2FaRjnCDqUSUlEgIfav%2FAsYXYe862EgGUjICSISr8QeL1qIXCRfI%5Cu003d
    
    requester用此signedRequest向接口服务器提出连接请求。
    

    POST

    将sign添加到unsignedRequest的末尾,得到signedRequest的值:
    
    {"publicKey":"030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a","timestamp":1635513688254,"sign":"IPZEm2XcRA2dxw3OFrHLT5KzS03MqZyp++QT/3TF5AGdfcfm0GCZo8t8FUE+MLiZ7ZNH0GV1Er8pJole+Qv73lE\u003d"}
    
    requester用https://www.sign.cash/api/connect,将此signedRequest提交接口服务器提出连接请求,Content-type为:application/json。
    

    6. 验证请求

    接口服务器收到requester连接请求后,验证:

    • 1)验证签名

    取publicKey的值为公钥,取删去sign项后的为message,验证sign的值,即签名是否正确。

    • 2)验证timestamp是否小于阈值

    接口服务器为防止ddos攻击和重放攻击,自行设置请求时间窗口长度(windowTime),判断timestamp是否有效。

    • 3)验证publicKey的地址是否在用户列表

    用publicKey的值计算相应的FCH地址,并判断该地址是否有权获得接口服务。

    授权方法、条件等由接口服务商根据《FEIP29_Service》在链上发布。

    7. 响应参数

    服务器验证请求有效后,为requester分配随机生成的授权密码secretKey,用requester的publicKey加密,将密文和secretKey的有效天数返回给requester。

    • 1)secretKey:授权密码,随机生成,256bit。

    • 2)加密公钥:请求参数publicKey的值。

    • 3)加密算法:默认为ECC256k1-AES256CBC。其他算法可由API服务商在链上注册服务时声明。

    响应参数为secretKey的密文和有效天数:

    参数 类型 必填 说明
    ciphertext string Y secretKey的密文
    days int N secretKey的有效天数

    示例

    "secretKey"="d2c03bbc1ba1380eafc395374e8da61f92545a1aac5d30b0c19289a69bd34a09"
    
    "publicKey"="030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a"
    
    响应参数为:
    
    {
        "ciphertext"="ArhfV+IZDn7jEcARv99mjmifU/WcWwOcV/J9hGB6dmxBCalW1F18QPe0kEuZzNR2iTercOpvxrD7mC5eD0fRMVMy4l08DOPOk3Q/hqddUNzQtE3YoA93jp3o5GJ2yYyalL7CmtRQHOWs+pFKpgzsl7gX4GhJpFHpeTD4+DlgU0fi9MWbCoQxSQYGxwnAvvU8avvgsDnr7p5EgiZ8TCnHl44=",
        "days":365
    }
    
    

    8. 返回值

    返回值 类型 必填 说明
    code int Y 错误码
    msg string Y 错误信息
    data object N 相关数据

    错误信息:

    code msg 说明 data字段
    0 OK 请求成功
    1 Unknown error. 未知错误 signedRequest
    1000 Signature verification failed. 签名验证失败 unsignedRequest, address, sign
    1001 Request expired, 请求已过期。 timestamp,windowTime
    1002 The user is not authorized. 用户未被授权 address
    1003 Access is restricted, please contact the service provider. 授权受限,请联系服务方 SID or the contact of the provider

    示例

    {
        "code":1001,
        "msg":"Signature verification failed.",
        "data":{
            "unsignedRequest":"https://www.sign.cash/api/connect?publickey=030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a×tamp=1635513688254",
            "publicKey":"030be1d7e633feb2338a74a860e76d893bac525f35a5813cb7b21e27ba1bc8312a",
            "sign":"H5viYRRPi4fr4ivgWAiSkWS7pLRpo%2B8YjiJ2FaRjnCDqUSUlEgIfav%2FAsYXYe862EgGUjICSISr8QeL1qIXCRfI%5Cu003d"
        }
    }
    

    9. 解密获得secretKey

    requester获得ciphertext后,用相应算法解密,获得secretKey,用于请求其他接口。

    10. 服务方保存用户信息

    服务方应保存的信息包括:

    信息 类型 说明
    address string 用户获得服务资格时提供,作为ID。
    publicKey string 用户提交请求时获得,用于加密和验证签名。
    secretKey string 为用户生成后保存,用于验证数据请求。
    timestamp time stamp secretKey发放时间,用于控制连接的有效期
    days int N

    11. requester保存API服务信息

    requester应保存API服务信息包括:

    信息 类型 必填 说明
    sid hex N 接口服务的SID
    apiURL string Y api服务的url
    address string N 发布者为api服务指定的pubKey的地址。
    publicKey string N 发布者为api服务指定的pubKey,用于加密和验证签名。
    secretKey string N API服务发来的密钥,用于验证数据请求。
    timestamp time stamp N secretKey的发放时间,用于控制连接的有效期
    days int N secretKey的有效天数

    12. 重置secretKey

    requester收到错误码为1001时,需要重新发起连接请求,获得新的secretKey。

    数据请求与响应

    requester获得secretKey后,可以通过APIP类型协议定义的API获取数据,简要流程为:

    requester按照API服务商在链上注册服务时提供的URL,按照响应APIP文档构造请求;然后将secretKey加入请求尾部,进行双sha256,获得签名sign;用sign替代secretKey,并加入requester的fch地址,获得最终的请求。

    API服务商收到请求后,准备响应数据,在响应数据尾部加入secretKey值后,做双sha256,获得签名sign;用sign替代secretKey添加到响应数据尾部,供requester验证数据。

    1. 接口名称

    API服务商根据提供的数据服务不同,定义不同的接口名称。

    示例:

    interface1

    2. 请求方法

    GET

    POST

    3. URL

    API服务商根据《FEIP29_Service》在url字段中发布API服务的路径。

    示例

    https://www.sign.cash/api/interface1
    

    4. 构造数据请求

    • 1)请求参数

    数据请求的参数由相应的APIP协议定义。

    示例

    {
        "address":"FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts,
        "amount":210000000
    }
    
    • 2)构造unsignedRequest

    参数中增加“timestamp”,POST方法再增加“url”字段,以防止重放攻击。

    对所有字段按照键的字母升序排序,不区分大小写,得到unsignedRequest。

    示例

    GET

    https://www.sign.cash/api/interface1?address=FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts&amount=210000000&timestamp=1635513688254
    
    

    POST

    加入url字段
    
    {"address":"FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts","amount":"210000000","timestamp":"1635513688254","url":"https://www.sign.cash/api/interface1"}
    
      1. 签名

    requester将secretKey加入signedRequest尾部后,用两次sha256进行哈希计算,得到签名sign,示例:

    GET

    sign =sha256(sha256(https://www.sign.cash/api/interface1?address=FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts&amount=210000000&timestamp=1635513688254&secretKey=d2c03bbc1ba1380eafc395374e8da61f92545a1aac5d30b0c19289a69bd34a09))=0404fe3dd90b2165c9f146ca3c1fa40aa1af92f344c7ef8ddbbc0c44e49b498c
    
    

    POST

    sign =sha256(sha256({"address":"FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts","amount":"210000000","timestamp":"1635513688254","url":"https://www.sign.cash/api/interface1","secretKey":"d2c03bbc1ba1380eafc395374e8da61f92545a1aac5d30b0c19289a69bd34a09"}))=16357161dec4537009f526268cc71df3dbabad26bdf043bda82dfb7ede67c875
    
      1. 生成请求signedRequest

    将requester的fch地址和sign的值加入unsignedRequest尾部,得到signedRequest:

    GET

    https://www.sign.cash/api/interface1?address=FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts&amount=210000000&timestamp=1635513688254&requester=FEk41Kqjar45fLDriztUDTUkdki7mmcjWK&sign=0404fe3dd90b2165c9f146ca3c1fa40aa1af92f344c7ef8ddbbc0c44e49b498c
    
    requester用此signedRequest向接口服务器提出数据请求。
    

    POST
    将api url加入参数

    {"address":"FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts","amount":"210000000","timestamp":"1635513688254","url":"https://www.sign.cash/api/interface1","requesrer":"FEk41Kqjar45fLDriztUDTUkdki7mmcjWK","sign":"16357161dec4537009f526268cc71df3dbabad26bdf043bda82dfb7ede67c875"}
    
    requester用https://www.sign.cash/api/interface1,将此signedRequest提交API服务方提出数据请求,Content-type为:application/json。
    

    5. 验证请求

    API服务器收到请求后,验证请求:

    • 1)确认当前时间戳减timestamp小于windowTime。

    • 2)确认requester的值为被授权用户地址。

    • 3)查询与requester值相对应的secretKey。

    • 4)对signedRequest删除requester和sign值,加入相应secretKey后计算两次sha256,并验证与sign的值是否相等。

    6. 响应参数

    • 1)准备数据:请求通过验证后,API服务方根据请求参数,按照相应APIP的规则准备数据。

    示例

    {
    	"txid":"df0e4393e103fd8692165c9eb74dd25b8dae662dbce926bf824237a55d4b61d3",
    	"index":1
    }
    
      1. 排序:按字母升序排列,不区分大小写。响应二进制数据时略过此步骤。

    示例

    {
    	"index":1,
    	"txid":"df0e4393e103fd8692165c9eb74dd25b8dae662dbce926bf824237a55d4b61d3"
    }
    
    • 3)签名

    JSON

    在数据的尾部加入secretKey,压缩:

    {"index":1,"txid":"df0e4393e103fd8692165c9eb74dd25b8dae662dbce926bf824237a55d4b61d3","secretKey":"d2c03bbc1ba1380eafc395374e8da61f92545a1aac5d30b0c19289a69bd34a09"}
    

    计算两次sha256,获得sign的值:

    sign =sha256(sha256({"index":1,"txid":"df0e4393e103fd8692165c9eb74dd25b8dae662dbce926bf824237a55d4b61d3","secretKey":"d2c03bbc1ba1380eafc395374e8da61f92545a1aac5d30b0c19289a69bd34a09"}))=b0d3bf96597cb51eb34e0c9b660b51b321342453ee3259931b047dd74bd80dc9
    

    二进制

    响应二进制数据时,将256位secretKey加入数据尾部,计算两次sha256哈希。

    • 4)响应数据

    JSON

    将sign替换secretKey放置于数据尾部,发送给requester。

    示例

    {"index":1,"txid":"df0e4393e103fd8692165c9eb74dd25b8dae662dbce926bf824237a55d4b61d3","sign":"b0d3bf96597cb51eb34e0c9b660b51b321342453ee3259931b047dd74bd80dc9"}
    

    二进制

    将256位的sign值添加到二进制文件的尾部,发送给requester。

    7. 返回值

    服务方对requester请求的返回值包括:

    返回值 类型 必填 说明
    code int Y 错误码
    msg string Y 错误信息
    data object N 相关数据

    错误信息:

    code msg 说明 data字段
    0 OK 请求成功
    1 Unknown error. 未知错误 signedRequest
    1001 Request expired, 请求已过期。 timestamp,windowTime
    1002 The user is not authorized. 用户未被授权 address
    1003 Access is restricted, please contact the service provider. 授权受限,请联系服务方 SID or the contact of the provider
    1004 signedRequest verification failed. 数据验证失败 signedRequest
    1005 The connection secretKey has expired. 连接密钥已失效 address

    示例

    {
        "code":1004,
        "msg":"signedRequest verification failed.",
        "data":{
            "signedRequest":"https://www.sign.cash/api/interface1?address=FTqiqAyXHnK7uDTXzMap3acvqADK4ZGzts&amount=210000000&requester=FEk41Kqjar45fLDriztUDTUkdki7mmcjWK&sign=7a4ae6a8862039c0679ef9039de5099f148b9d5a4f37313409afdf5d726c4903"
        }
    }
    

    8. 验证数据

    requester获得响应参数后

    • 1)删除sign,加入secretKey

    • 2)做两次sha256计算

    • 3)将所得到的值与sign的值进行比较,相同则数据未经篡改,接受该数据。

    9. 重置secretKey

    requester收到错误码为1006时,需要重新发起连接请求,获得新的secretKey。

    两种服务方式

    CAPP可选择以CAPP身份或用户身份与API服务商建立服务关系:

    1. 以CAPP身份请求API服务

    • 1)CAPP发布者生成CAPP请求API专用FCH地址。

    • 2)CAPP发布者获得API服务商服务许可,登记CAPP的地址为被授权地址。

    • 3)CAPP用专用地址公钥请求连接,获得secretKey。

    • 4)用户使用CAPP时,所需要的数据通过CAPP向API服务商提出请求。

    • 5)特点:符合传统开发习惯,但CAPP有中心化风险。

    2.以用户身份请求API服务

    • 1)用户通过CAPP或其他途径获得API服务许可,登记自己的FCH地址为被授权地址。

    • 2)用户进入CAPP需要获取数据时,用自己的公钥和签名通过CAPP向API服务商提出连接请求。

    • 3)CAPP为用户在本地保存secretKey,用户从本地向API服务商发起数据请求。

    • 4)特点:符合密码经济用户自主的内在逻辑,对CAPP的依赖减少,更加开放



  • @昌用 sign=sha256(sha256({"txid":"df0e4393e103fd8692165c9eb74dd25b8dae662dbce926bf824237a55d4b61d3","index":1,"secretKey":"d2c03bbc1ba1380eafc395374e8da61f92545a1aac5d30b0c19289a69bd34a09"})=c4f3f458f00c7915ebbf463fe99881dd7f7fe9d1106479222771b8cd8fa7b1a5
    上面这个示例的括号有缺失吧?



  • 是的,少了个),加上了。


Log in to reply