收起左侧

飞牛api 登录上传文件等

0
回复
190
查看
[ 复制链接 ]

1

主题

6

回帖

0

牛值

fnOS系统内测组

飞牛api逻辑

根据浏览器抓包,飞牛大部分接口都是websocket协议

上传用的http协议,但是要使用ws获取一个文件名,叫做checkUpload

飞牛网页一共建立三个ws,分别是main, file,timer,实际都是一个服务响应

只是网页版建立了三个连接,用python调用api,使用type=main也可以checkUpload

ws接口地址

ws://192.168.1.4:5666/websocket?type=main # 这里的main就是类型区分

请求参数结构

json格式的的请求体

参数 类型 示例 用途
req str user.login 指定调用的api
reqid str 6819dfb56819dfb500000002000d 请求id,和响应对应
其他业务参数 ... ... ...

reqid生成代码

python生成,自增

def _get_reqid():
    index = 1

    def func(backId='0000000000000000'):
        nonlocal index
        t = format(int(time.time()), 'x').zfill(8)
        e = format(index, 'x').zfill(4)
        index += 1
        return f"{t}{backId}{e}"

    return func

get_reqid = _get_reqid()

接口加密

连接ws后先发送获取RSA公钥的请求到服务器,用于登录和其他参数加密

{reqid: "6819e1ca00000000000000000001", req: "util.crypto.getRSAPub"}

返回示例:

{"pub":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzWICqab2gcSuRzhguXqH\nKOzS0irokLS9pvT488UIv1581RcfuqUKV/CpvBvbzrLEM1kQtbSAXjOSAYrmOW+V\nN9Nwb8XhJSZHuPdAmqDzm9hu+06QDkIE9TLkNnIZcQKW6gG9Pbo5vID7BWYjzJVU\n7rP+lX5lUrCbpgsXxs5UjEb+4E5St1RaKFCOMiapy40wXgMh4rVyfbfkT752RSsj\nvnNWyYEHuFDJZ7Z2JHJZBhZnIRXOt0k4bTzpqxBbq/2llZ2Z60pm+Ad/h+xpLjvU\nlITh9ddocFpYddYO7MIGQ6dDO4KBObPkqvOJuZ+9sKw1PE6pm4C/ArR1lVHh4L3j\n8wIDAQAB\n-----END PUBLIC KEY-----\n","si":"21474836501","result":"succ","reqid":"6819e1ca00000000000000000001"}

登录接口

原始数据

参数 类型 示例值 备注
req str user.login
reqid str 6819e1ce00000000000000000003 自增id,自己维护,可以是uuid
user str admin 需要登录的账号
password str password 账号的密码
deviceType str Browser 这里可以固定,也可以随便填,我认为不重要
deviceName str Windows-Google Chrome 同上
stay bool True 勾选“保持登录”时为True
si str 21474836501 util.crypto.getRSAPub返回的si

加密后

参数 类型 示例 备注
aes str 5aA/cocgii6UWK.... 把原始请求数据使用aes加密
iv str aHr5yKmqaVU8gJ... 随机os.urandom(16)
req str encrypted 固定
rsa str aTlI**Z8HOjhV0... aes加密key使用rsa加密

失败返回

{"errno":131072,"result":"fail","reqid":"6819e1ce00000000000000000003"}

成功响应

{
    "uid": 1000, // uid
    "admin": true, // 是否管理
    "token": "TvPxZlDmGWj+Zhoj3ePKAXhNwEoRg20sOTC0+j/Yof8=", // 会话token
    "secret": "bWH/dMzpTM2c498hzpW5FXic9ap5wPHhFiMqXnFBqs4=", // 后面签名密钥
    "backId": "6819e65000000004", // 替换reqid的8-24位的0, 参考reqid生成代码
    "machineId": "744d46cccc6b4ababf2ffbe273a55cc620fee21f", // 没搞懂
    "result": "succ", // 接口响应状态
    "reqid": "6819e65000000000000000000004" // 和请求id保持一致
}

加密函数

# AES 加密
def aes_encrypt(data, key, iv):
    cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(pad(data.encode('utf-8'), AES.block_size))
    return base64.b64encode(ciphertext).decode('utf-8')

# RSA 加密
def rsa_encrypt(public_key_str, plaintext):
    key = RSA.import_key(public_key_str)

    # 注释和不注释都能过,就很奇怪
    # MAX_ENCRYPT_BLOCK = 117
    # ciphertext = b''
    # for i in range(0, len(plaintext), MAX_ENCRYPT_BLOCK):
    #     chunk = plaintext[i:i + MAX_ENCRYPT_BLOCK]
    #     cipher = PKCS1_v1_5.new(key)
    #     encrypted_chunk = cipher.encrypt(chunk)
    #     ciphertext += encrypted_chunk

    cipher = PKCS1_v1_5.new(key)
    ciphertext = cipher.encrypt(plaintext.encode())
    ciphertext = base64.b64encode(ciphertext).decode()
    return ciphertext


def login_encrypt(data, public_key_str, key, iv):
    # RSA 加密
    rsa_encrypted = rsa_encrypt(public_key_str, key)

    # AES 加密
    # data = json.dumps(t, separators=(',', ':'))
    aes_encrypted = aes_encrypt(data, key, iv)

    # 返回加密数据
    return {
        'req': 'encrypted',
        'iv': base64.b64encode(iv).decode('utf-8'),  # 正常
        'rsa': rsa_encrypted,
        'aes': aes_encrypted  # 正常
    }

写不下去了

去github看代码吧,我实在不会写文档,所有代码使用python写

仓库地址:https://github.com/k23223/fnnas-api?tab=readme-ov-file

免责声明

如果此仓库违反了飞牛私有云用户协议,请联系我删除仓库。

收藏
送赞
分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则